Read 03: Flexbox and Templating - Ahmad-Sawalqeh/amman-301d1 GitHub Wiki

Handlebars.js

With Handlebars, you can separate the generation of HTML from the rest of your JavaScript and write cleaner code.

Adding it to your project:

Just go to http://handlebarsjs.com/ , and click the download button to get the latest version. Now all you have to do is to include the library in your html with a regular <script> tag.

// From File
<script src="handlebars-v2.0.0.js"></script>

// From CDN
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/2.0.0/handlebars.js"></script>

Templates:

The templates have an easy to grasp syntax. They can contain HTML and text, mixed with Handlebars expressions. Expressions are wrapped in double or triple curly braces {{}}. Expressions tell Handlebars to include the value of variables or to execute helper functions. Templates need to be compiled to a JavaScript function before use. You can see an example below.

<!--This is our template. -->
<!--Data will be inserted in its according place, replacing the brackets.-->
<script id="address-template" type="text/x-handlebars-template">
  <p>You can find me in {{city}}. My address is {{number}} {{street}}.</p>
</script>

<!--Your new content will be displayed in here-->
<div class="content-placeholder"></div>

Expressions:

To build up from the previous example, any data that you print out in an {{ }} expression, will automatically get HTML escaped by handlebars. This is a great security feature, but some times you might wish to print raw HTML. In this case you will use the triple curly brace expression {{{ }}}.

Also, notice that the handlebars expressions support nested values which enables us to easily access any data from a JavaScript object.

<script id="expressions-template" type="text/x-handlebars-template">
  {{description.escaped}}
  {{example}}

  <br><br>

  {{description.unescaped}}
  {{{example}}}
</script>

<div class="content-placeholder"></div>

Context:

Handlebars builds on the best features of Mustache. And one these is the concept of context - the object where properties you include in curly braces are looked up. Every template you write has a context. On the top level, this is the JavaScript object that you pass to the compiled template. But helpers like #each or #with modify it, so that you can access the properties of the iterated object directly. The next example will make things clearer.

<!-- The #each helper iterates over an array of items. -->
<script id="example-template" type="text/x-handlebars-template">

  <!-- people is looked up on the global context, the one we pass to the compiled template -->

  {{#each people}}

    <!-- Here the context is each individual person. So we can access its properties directly: -->
    <p>{{firstName}} {{lastName}}</p>

  {{/each}}

</script>

Flexbox

we set a special value of display on the parent element of the elements you want to affect. In this case we want to lay out the <article> elements (flex items), so we set this on the <section> (which becomes a flex container):

section {
  display: flex;
}

Columns or rows:

Flexbox provides a property called flex-direction that specifies what direction the main axis runs in (what direction the flexbox children are laid out in) — by default this is set to row, which causes them to be laid out in a row in the direction your browser's default language works in (left to right, in the case of an English browser).

section {
  display: flex;
  flex-direction: column;
}

You can also lay out flex items in a reverse direction using the row-reverse and column-reverse values.

Wrapping:

adding the following declaration to your <section> rule:

section {
  display: flex;
  flex-direction: column;
  flex-wrap: wrap;
}

Also, add the following declaration to your <article> rule:

article{
  flex: 200px;
}

Horizontal and vertical alignment:

adding the following to the bottom of the example's CSS:

div {
  display: flex;
  align-items: center;
  justify-content: space-around;
}

Ordering flex items:

Flexbox also has a feature for changing the layout order of flex items, without affecting the source order. This is another thing that is impossible to do with traditional layout methods.

button:first-child {
  order: 1;
}

button will move to the end of the main axis. Let's talk about how this works in a bit more detail:

  • By default, all flex items have an order value of 0.
  • Flex items with higher order values set on them will appear later in the display order than items with lower order values.
  • Flex items with the same order value will appear in their source order. So if you have four items with order values of 2, 1, 1, and 0 set on them respectively, their display order would be 4th, 2nd, 3rd, then 1st.
  • The 3rd item appears after the 2nd because it has the same order value and is after it in the source order.
⚠️ **GitHub.com Fallback** ⚠️