Skip to content

Latest commit

 

History

History
299 lines (218 loc) · 8.25 KB

html-processing.md

File metadata and controls

299 lines (218 loc) · 8.25 KB

English description | Описание на русском

HTML

Jade, Pug or Handlebars can be used as a html templater. You can choose templater in tars-config.js or during initialization of TARS via TARS-CLI.

You can use all features of Jade, Pug and Handlebars. If you are used to the regular HTML, choose the handlebars and write HTML as before.

If you don't want to compile a particular page, you can simply add the '_' at the begining of the page name and it will not be compiled.

If you need to include files from the static directory (images, js-files), you must use the placeholder %=static=% or __static__. Then including of an image will be as in following example (in this example Handlebars is used):

<img src="%=static=%img/content/example.jpg"/>

To include image in CSS you need to use the same placeholder – %=static=%. This placeholder will be replaced with string from staticprefixforcss from config.

%=staticPrefixForCss=% and %=staticPrefix=% prefixes work, but these prefixes are deprecated! Just use %=static=%! New prefixes work in TARS from version 1.6.0

Very important feature is the usage of different data types in one template. For example, we have a head component, which has all that you should put in the head tag (different meta, titles, etc.). Suppose that every page should have its own title. Making copies of the same component, which differ only in one line is not the best practice. It would be logical to separate data from presentation.

So, the folder with the component has a folder called data, which has js file with data for this component. Example of data can be found in the component _template:

componentName: {
    dataType: {
        property: value
    }
}

In case of syntax errors in data files from your editor you can use another syntax, just a simple JavaScript object:

data = {
    componentName: {
        dataType: {
            property: value
        }
    }
};

TARS supports both syntaxes by default.

In the file data.js comments are supported within the data object.

You can add component into another component folder from TARS 1.8.0. In that case there can be some problems with duplicating names of these components. To prevent this situation, TARS generates unique key for each embedded component using the next scheme:

'parentComponentName_anotherParentComponent_currentComponentName' = {
    dataType: {
        property: value
    }
};

In the embedded component data file you can write code as usual:

const data = {
    'currentComponentName': {
        dataType: {
            property: value
        }
    }
};

Unique key will be generated automatically.

By default full data will contain the data from _template component and a list of all project pages like this:

__pages: [
    {
        name: 'pageName',
        href: 'pageHref'
    }
]

You can use this array to render a list of links to all pages of a project.

You can pass any data to templater by using env var TARS_ENV. For example, you can pass a simple string:

TARS_ENV="Hello World" tars dev --silent

And then you can get it in template (handlebars):

{{TARS_ENV}}

You can pass object to TARS_ENV too:

TARS_ENV="{\"name\": \"Paul\"}" tars dev --silent

And then you can get it in template (handlebars):

{{TARS_ENV.name}}

It is important to add double quotes and escape quotes inside object!

Connecting components with different data looks differently in Jade/Pug and Handlebars.

Working with components and data in Handlebars

Including component on the page:

{{> componentFolderName/componentName}}

Including component with passing data to the template:

{{> componentFolderName/componentName componentName.dataType}}

Example of including head component with default data:

{{> head/head head.defaults}}

Inside the component data is displayed by the handlebars:

<title>{{title}}</title>

If you include component without passing data, component gets an access to the global scope. For example, if we include component head without data, we will have to use the following code to get access to the field title:

// head/data/data.js
head: {
    defaults: {
        title: 'Default title'
    }
}

index.html

{{> head/head}}

head.html

<title>{{head.defaults.title}}</title>

But, if you have passed the data to component, you will not have access to the data of a child component. You have to pass global scope to the parent component (to not pass any data while including), to pass data for a child component. Or you can use another variant:

index.html

{{> component1/component1 component1.main}}

component1.html

<h1>{{title}}</h1>

{{> component2/component2 component2.main}}
// component1/data/data.js
component1: {
    main: {
        title: 'Title of component1',
        component2: function (fullData) {
            return fullData.component2;
        }
    }
}

component2.html

<h2>{{title}}</h2>
// component2/data/data.js
component2: {
    main: {
        title: 'Title of component2'
    }
}

So, you can get access to data of any component from data-file of current-component by using really simple construct:

// component/data/data.js
component: {
    main: {
        title: 'Title of component',
        innerComponentData: function (fullData) {
            // fullData is an object 
            // with all data of the application
            return fullData.componentName.componentType;
        }
    }
}

Everything will be much more easier with arrow functions ES6:

// component/data/data.js
component: {
    main: {
        title: 'Title of component',
        innerComponentData: fullData => fullData.componentName.componentType
        }
    }
}

Do not forget, that embeded components will have unique key in the complete data file in the build.

Handlebars is known as a very simple templater. But it is uncomfortable to use Handlebars in creation process without frameworks or something like that. So, different helpers have been added that expand Handlebars.

Helpers description can be found here.

Working with components and data in Jade/Pug

When using Jade/Pug, each component is a mixin, which is included in a page file. Mixin can receive data.

Including component on the page:

include ../components/componentFolderName/componentName
+componentName()  // Component include

Including component with data transmission in the template:

include ../components/componentFolderName/componentName
+componentName(componentName.dataType)  // Component include

Example of head component including with default data:

include ../components/head/head
+head(head.defaults)

You have to add extension in Pug:

include ../components/head/head.pug
+head(head.defaults)

Inside the component data is displayed by Jade/Pug (for example, the head component):

mixin head(data)
   <title>#{data.title}</title>

You can use any features that are available in Jade/Pug. You can include components with any nesting of child components and with any data by using inlude and '+'. And you can use functions in data.js like in examples for Handlebars.

There is one built-in helper for Jade/Pug in TARS — Icon. This helper generates templates for svg symbol inclusion. You can add your own helpers to /tars/user-tasks/html/helpers/jade"pug-helpers. There is an example of user-helper in there. You can use added helpers in a template like:

For Jade:

= jadeHelpers.helperName(params)

<!-- If your helper returns unescaped code -->
!= jadeHelpers.helperName(params)

For Pug:

= pugHelpers.helperName(params)

<!-- If your helper returns unescaped code -->
!= pugHelpers.helperName(params)