Coder Social home page Coder Social logo

jqtemplate's Introduction

jQTemplate

Notice

This ended up turning into another library called contours which still uses jQuery but has optional support for it rather than required support. Contours also has improved performance over jQTemplate.

What is it?

jQuery templating micro-library that handles nesting of DOM nodes and jQuery objects using ES6 template strings/literals.

How it works.

Takes a template string and converts it to a jQuery object. It is mostly a wrapper around feeding your string into the jQuery constructor and creating your elements. With the exception that all placeholder values of the template string which are DOM nodes, jQuery objects, or an array composed of DOM nodes and jQuery objects will get a temporary placeholder with unique id before being fed into the jQuery constructor. After the DOM tree has been built all the unique id'ed elements will be replaced with their corresponding DOM node or jQuery element.

Quick example:

var $message = $("<div>Hello World</div>");

var $result = jQTemplate.template`
  <div>
    ${$message}
  </div>
`;

$result is a jQuery object with HTML content equivalent to:

var $sameResult = $(`
  <div>
    <div>Hello World</div>
  </div>
`);

Why jQTemplate?

I found myself using the same pattern to input text nodes into html I created using jQuery and I eventually thought of something I feel is easier to handle. I also wanted something that I could just plug-in to my existing jQuery projects without having to re-write anything.

I commonly did something similar to this:

var userText = "something dangerous!!!";

// create new element
var $el = $(`
  <div>
    ...
    <div class="js-insertUserText"></div>
    ...
  </div>
`);

// insert user text
var textNode = document.createTextNode(userText);
$el.find(".js-insertUserText").append(textNode);

// insert el to DOM
$("body").append($el);

With jQTemplate you can just do this:

var userText = "something dangerous!!!";

jQTemplate.template`
  <div>
    ...
    <div>${jQTemplate.textNode(userText)}</div>
    ...
  </div>
`.appendTo("body");

What you should know about this library before you use it.

The main function jQTemplate.template is meant to be used as a ES6 template tag function. There are a series of functions in the library that should be used in conjunction with the template function as any string values produced in template literal placeholders will be added as html through jQuery. Since this is unwanted for user input it is suggested that you turn your user input into text nodes when possible using either document.createTextNode("text string"), jQTemplate.textNode("text string") which is just an alias to the previous, or jQTemplate.htmlNode("span","text string") which wraps your given element in argument 1 around the text node it creates using the text from argument 2. Text Nodes cannot be used within the opening or closing tag of an element for this reason if you want to use something within the opening or closing you can merely escape it. For more advanced escaping I would try adding your own DOM white-listing libraries.

How do I use it?

jQTemplate uses the UMD module definition so it can work as: an amd module, a commonjs module, and will fall back to a global named jQTemplate if neither module system is being used.

Once you have jQTemplate included you can then expose the five functions of jQTemplate to your scope quickly using ES6.

var {template, textNode, htmlNode, simpleEscape, addEvents} = jQTemplate;

API

template`a template string with optional ${placeholders}`; OR template(strings, ...valuesFromPlaceholders)

Takes a template string and converts it to a jQuery object. It is mostly a wrapper around feeding your string into the jQuery constructor and creating your elements. With the exception that all placeholder values of the template string which are DOM nodes or jQuery objects will get a temporary placeholder with unique id before being fed into the jQuery constructor. After the DOM tree has been built all the unique id'ed elements will be replaced with their corresponding DOM node or jQuery element.

Quick example:

var $message = $("<div>Hello World</div>");

var $result = jQTemplate.template`
  <div>
    <h1>Greetings</h1>${$message}
  </div>
`;

$result is a jQuery object with HTML content equivalent to:

var $sameResult = $(`
  <div>
    <h1>Greetings</h1><div>Hello World</div>
  </div>
`);

since templates return jQuery objects they can also be nested in each other. The following also has equivelent HTML:

var $greetingEl = jQTemplate.template`<h1>Greetings</h1>${$message}`;

var $equivalentResult = jQTemplate.template`
  <div>
    ${$greetingEl}
  </div>
`;

Another useful example is using an array composed of either or both DOM nodes and jQuery objects in the template strings placeholder.

var {template, htmlNode} = jQTemplate;
var userTexts = ["hello", "world", "something interesting"];

template`
  <ul>
    ${userTexts.map(function (el, i) {
      return htmlNode('li', el, {class: `li-${i}`});
    })}
  </ul>
`.appendTo("body");

textNode(tagName, text = "")

type signature textNode(string)

Just a wrapper around document.createTextNode().

htmlNode(tagName, text = "", attributes = {})

type signature htmlNode(string, [string, object])

returns an element with the tag name tagName, text inserted as a text node of that element, and attributes of that element set equal to attributes.

The following are example true expressions:

'<h1></h1>' == jQTemplate.htmlNode("h1").outerHTML;
'<h1 class="true">world</h1>' == jQTemplate.htmlNode("h1", "world", {class: "true" }).outerHTML;
'<h1 data-action="true"></h1>' == jQTemplate.htmlNode("h1", {"data-action": "true" }).outerHTML;
'<h1 style="padding: 10px; margin: 10px; line-height: 1em;"></h1>' == jQTemplate.htmlNode("h1", {style: "padding: 10px; margin: 10px; line-height: 1em;" }).outerHTML
'<h1 style="padding: 10px; margin: 10px; line-height: 1em;"></h1>' == jQTemplate.htmlNode("h1", {style: {padding: "10px", margin: "10px", lineHeight: "1em"} }).outerHTML
'<h1 style="padding: 10px; margin: 10px; line-height: 1em;"></h1>' == jQTemplate.htmlNode("h1", {style: {padding: "10px", margin: "10px", "line-height": "1em"} }).outerHTML

Note how the style property can be either a style string or an object with camelCase letters or strings of the proper css style property. The camelCase properties will be converted to kabob-case internally.

The use of a property starting with "on" e.g. "onclick" will use jQuery's on method internally. The following code example shows an element when clicked will console.log "clicked".

jQTemplate.htmlNode("h1", {onclick: function (e) { console.log("clicked"); }});

simpleEscape(str)

type signature simpleEscape(string)

Translates HTML characthers in the keys to unicode character equivalents in the values than returns the manipulated string.

{
  "&": "&amp;",
  "<": "&lt;",
  ">": "&gt;",
  '"': '&quot;',
  "'": '&#39;',
  "/": '&#x2F;'
}

Good for use in escaping values for HTML DOM attributes. As an example of what you shouldn't do in jQuery or the templating library:

var {template} = jQTemplate;
var userText = '"><script>alert("malicious code could be here.")</script>';

template`<div data-name="${userText}"></div>`.appendTo("body");

And what you should do instead:

var {template, simpleEscape} = jQTemplate;
var userText = '"><script>alert("malicious code could be here.")</script>';

template`<div data-name="${simpleEscape(userText)}"></div>`.appendTo("body");

Contributing

Pull requests and issues welcome.

Licensing

The MIT License (MIT)
Copyright (c) 2016 John Johnson

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

jqtemplate's People

Contributors

johnsonjo4531 avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.