Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/gtap-dev/html


https://github.com/gtap-dev/html

Last synced: about 2 months ago
JSON representation

Awesome Lists containing this project

README

        

# Twig & HTML ``

*A mostly reasonable approach to Twig*

This is a superset of the [Official SensioLabs Twig Standards](https://twig.symfony.com/doc/1.x/coding_standards.html).

## Resources

- [Twig docs](https://twig.symfony.com/doc/1.x/).

## Filters


- [2.1]() String tokens to be used inside the `replace` filter should be
marked with percentage signs.

```twig
{# Bad #}
{{ sidekicks|replace('{{ robin }}', 'Dick Grayson') }}

{# Good #}
{{ sidekicks|replace('%robin%', 'Jason Todd') }}
```


- [2.2]() Do not use the default filter for default data.

Default data should come from context. Use default filter for logic only.

```twig
{# Bad #}
{{ url|default('#') }}

{# Good #}
{{ url|default(data.url) }}
```


- [2.3]() Use merge filter to add to arrays or objects.

Note that you need to make sure the array/object is iterable.

```twig
{# Bad #}
{% include '@button' with { data: { text: data.button.text, icon: '#arrow-right' } } %}

{# Good #}
{% include '@button' with { data: data.button|merge({ icon: '#arrow-right' }) } %}
```


- [2.4]() Escape data and values in HTML attributes with the `escape` filter.

```twig
{# Bad #}

{# Good #}

```


- [2.5]() If possible, avoid transforming data with filters. Transform data beforehand, in PHP.

## Functions


- [3.1]() Use dump function to debug data.

Wrap the output with a `pre` tag to make it easier to read.

```twig


{{ dump(user) }}

```

## Operators


- [4.1]() Do not use Math operators.

Math is calculation logic that should stay in PHP.

As an example, instead of the mod operator, use batching.
```twig
{# Bad #}
{% for row in items %}
{% if loop.index == 1 or (loop.index % 3) == 1 %}
{# do something with every third item #}
{% endif %}
{% endfor %}

{# Good #}
{% for row in items|batch(3) %}
{% for column in row %}
{% if loop.index == 1 %}
{# do something with every third item #}
{% endif %}
{% endfor %}
{% endfor %}
```

## Variables


- [5.1]() Use variables to store common values in templates.

Instead of doing the same template logic in multiple instances, save the values to variables with `set` tags.

## Comments


- [6.1]() Use Twig comments to convey important implementation information to other developers.

Twig comments will be compiled away, HTML comments are transferred and visible in source to all users.

```twig
{# Bad #}

{# Good #}
{# TODO: id should not be static #}

```

## Whitespace


- [9.1](#whitespace--before-blocks) Place 1 space before the leading brace.

```twig
{# Bad #}
{% set dog={
'age': '1 year',
'breed': 'Bernese Mountain Dog',
} %};

{# Good #}
{% set dog = {
'age': '1 year',
'breed': 'Bernese Mountain Dog',
} %};
```


- [9.2](#whitespace--around-keywords) Place 1 space before the opening
parenthesis in control statements (`if`, `for` etc.). Place no space
between the argument list and the function name in function calls and
declarations.

```twig
{# Bad #}
{% if(isJedi) %}
{% set enemy = 'sith' %}
{% endif %}

{# Good #}
{% if (isJedi) %}
{% set enemy = 'sith' %}
{% endif %}

{# Bad #}
{{ jedi|default ('Yoda') }}

{# Good #}
{{ jedi|default('Yoda') }}
```


- [9.3](#whitespace--infix-ops) Set off operators with spaces.

```twig
{# Bad #}
{% set x=y+5 %}

{# Good #}
{% set x = y + 5 %}
```


- [9.4](#whitespace--newline-at-end) End files with a single newline
character.

```twig
{# Bad #}
{{ stuff }}
```

```twig
{# Bad #}
{{ stuff }}↵

```

```twig
{# Good #}
{{ stuff }}↵
```


- [9.5](#whitespace--padded-blocks) Do not pad your blocks with blank lines.

```twig
{# Bad #}
{%

set foo = 'bar'

%}

{# Bad #}
{% if baz %}

{{ qux }}
{% elseif %}
{{ foo }}

{% endif %}

{# Good #}
{% if baz %}
{{ qux }}
{% elseif %}
{{ foo }}
{% endif %}
```


- [9.6](#whitespace--in-parens) Do not add spaces inside parentheses.

```twig
{# Bad #}
{{ foo|default( 'foo' ) }}

{# Good #}
{{ foo|default('foo') }}
```


- [9.7](#whitespace--in-brackets) Do not add spaces inside brackets.

```twig
{# Bad #}
{% set foo = [ 1, 2, 3 ] %}
{{ foo.0 }}

{# Good #}
{% set foo = [1, 2, 3] %}
{{ foo.0 }}
```


- [9.8](#whitespace--in-braces) Add spaces inside curly braces.

```twig
{# Bad #}
{% set foo = {clark: 'kent'} %}

{# Good #}
{% set foo = { clark: 'kent' } %}
```


- [9.9](#whitespace--max-len) Avoid having everything in one line.

> Why? This ensures readability and maintainability.

```twig
{# Bad #}
{% if victory|default %}{{ congratulations }}{% else %}{{ failure }}{% endif %}

{# Good #}
{% if victory|default %}
{{ congratulations }}
{% else %}
{{ failure }}
{% endif %}
```


- [9.10](#whitespace--attributes) Avoid having too much attributes in single line.

> Why? This ensures readability and maintainability.

```twig
{# Bad #}
{{ data.alt }}

{# Good #}
{{ data.alt }}
```


- [9.11](#whitespace--single-attribute) Avoid having too much logic in a single HTML attribute.

> Why? This ensures readability and maintainability.

Instead, split the logic to a separate variable block with whitespace control.

```twig
{# Bad #}

{# Good #}
{% set BEM -%}
textfield
{% if modifier %} {{ modifier }}{% endif %}
{%- if class %} {{ class }}{% endif %}
{%- if data.isInvalid %} is-invalid{% endif %}
{%- if data.isDisabled %} is-disabled{% endif %}
{%- if data.icon %} textfield--icon{% endif %}
{% endset %}


```


- [9.12](#whitespace--indenting) Indenting nested logic and blovks

For consistency, everything that is nested should be indented by one level more than its context. (Even if it breaks HTML indentation)

```twig
{# Bad #}
{% if data.title %}
{{ data.title }}
{% endif %}

{{ data.rowOne }}

{% if data.rowTwo %}
{{ data.rowTwo }}

{% endif %}

{# Good #}
{% if data.title %}
{{ data.title }}
{% endif %}

{{ data.rowOne }}

{% if data.rowTwo %}
{{ data.rowTwo }}

{% endif %}
```

## Stylistic rules


- [10.1](#styles--leading-trailing) Leading commas: **No.**

```twig
{# Bad #}
{% set story = [
'once'
, 'upon'
, 'a'
, 'time'
] %}

{# Good #}
{% set story = [
once,
upon,
aTime,
] %}

{# Bad #}
{% set hero = {
'firstName': 'Ada'
, 'lastName': 'Lovelace'
, 'birthYear': '1815'
, 'superPower': 'computers'
} %}

{# Good #}
{% set hero = {
'firstName': 'Ada',
'lastName': 'Lovelace',
'birthYear': '1815',
'superPower': 'computers'
} %}
```


- [10.2](#styles--quotes) Use double quotes for HTML attributes, single quotes for everything else.

```twig
{# Bad #}

{# Good #}

{# Bad #}
{% set hero = "bad" %}

{# Good #}
{% set hero = 'good' %}
```

## Naming conventions

- [11.1](#naming-camelCase) Use camelCase to name variables.

```twig
{# Bad #}
{% set story_of_my_life = 'cry baby cry' %}
{% set storyofmylife = 'cry baby cry' %}

{# Good #}
{% set storyOfMyLife = 'cry baby cry' %}
```

## Known issues

You can use majority of twig functions, but there are some restrictions in styleguide, because we use Twig.js adapter.


- [13.1](#known-issues--macro) Include inside macro not working very well. Example:

```twig
{% macro li(item, class, icon) %}



  • {% include '@icon' with { name: icon } %}
    {{ item.text }}


  • {% endmacro %}

    {{ ul.li(data.item, 'pagination__item--first', 'arrow') }}
    ```

    You can fix this issue by sending whole icon component into macro. Example:

    ```twig
    {% macro li(item, class, icon) %}



  • {{ icon }}
    {{ item.text }}


  • {% endmacro %}

    {% set icon %}
    {% include '@icon' with { name: 'arrow' } %}
    {% endset %}
    {{ ul.li(data.item, 'pagination__item--first', icon) }}
    ```

    It's not nice but will work.

    ## General


    - [14.1]() When deciding to choose whether to use a certain Twig functionality, make sure it is supported by both Twig PHP and [Twig.js](https://github.com/twigjs/twig.js) as we generally use both in our projects.


    - [14.2](#general--if-wrapping) If data existence is questionable, use twig if tag.

    ```twig
    {# Bad #}


    {{ data.error }}

    {# Bad #}


    {% if data.error %}
    {{ data.error }}
    {% endif %}

    {# Good (no unnecessary html) #}
    {% if data.error %}


    {{ data.error }}

    {% endif %}
    ```


    - [14.3](#general--use-data) Use data.something only if data really comes from back-end and is changeable

    ```twig
    Example if button icon is fixed and admin can't change it.


    {{ data.text }}
    {% include '@icon' with { name: icon, class: 'button__icon', modifier: '' } %}

    ```

    ## HTML


    - [15.1](#html--semantics) Use semantic [HTML elements](https://developer.mozilla.org/en-US/docs/Web/HTML/Element), wherever appropriate.

    This is to ensure basic usability of the website for all people.

    ```twig
    {# Bad #}
    {# Clickable div that does not have role button nor is tabbable. #}


    {{ data.text }}

    this is a button that has interactivity via JS and no real href

    {# Good #}

    {{ data.text }}

    this is a button that has interactivity via JS
    ```


    - [15.2](#html--landmarks) Use appropriate landmarks to convey important parts of the website to assistive tech.

    See examples in [WAI-ARIA Authoring Practises](https://www.w3.org/TR/wai-aria-practices-1.1/#aria_landmark).


    - [15.3](#html--semantic-content-order) Make sure your content order is semantic.

    Sometimes due to design quirks HTML structure cannot be semantically correct. In these cases you can hide the wrongfully placed elements using `aria-hidden="true"` and add visually hidden elements to semantically appropriate places, thus making content order correct and accessible.

    ```twig
    {# Bad #}

    ...

    Section title


    ...

    {# Better #}

    Section title


    ...

    Section title


    ...

    {# Best #}
    {# Work with your designer to make sure the design order follows semantic order! #}

    Section title


    ...

    ...


    ```


    - [15.4](#html--accessibility) Use appropriate ARIA behavior on interactive components that do not exist natively in HTML.

    For example: alerts, dialogs, tooltips, accordions, tabs, autocomplete inputs do not have native HTML elements that convey their behavior and semantics to assistive technology.

    These kinds of interactive components need to have appropriate ARIA roles and JavaScript functionality to work properly for everyone.

    Please explore the [WAI-ARIA Authoring Practises](https://www.w3.org/TR/wai-aria-practices-1.1/) document for specific examples and explanations.


    - [15.5](#html--target-blank) Avoid using `target="_blank"` on links.

    Do not force people to new tabs/windows when it is not strictly necessary. People who want to open links in new tabs usually know how to do this themselves.

    See this [CSS-Tricks article](https://css-tricks.com/use-target_blank/) for more explanations.

    If you absolutely must use `target="_blank"` on links, use `rel="noreferrer` with it.