by Evgenii Nikitin
Project manager | Back-end developer | Front-end developer | QA tester |
---|---|---|---|
thinks about budget | provides logic, prepares data | implements representation | ensures that everything works properly |
needs clear vision on a project | needs easy way to integrate design in application | has to think about: platforms, browsers, accessibility, performance | needs time, tools for automated testing |
Back-end first, styles are added after it directly to theme.
Simplest, fastest. Good to use if only one developer works on the project.
All pages have to be prepared in advance. FE dev can't work if templates aren't ready.
Result is visible when BE and FE parts are completed. Long process, poor visibility.
FE dev are limited by existing html markup that template provides
BE:
FE:
PM:
QA:
BE:
FE:
Pages with examples can be removed. Difficult to provide variations of templates.
PM:
QA:
FE:
HTML markup is prepared separately, then it is copied to Drupal.
Starting point for teams with few developers that works simultaneously.
Easiest for FE developer. He does everything as he wants. No need additional libraries and tools.
HTML markup can be tested separately from BE part.
Developers can work simultaneously.
BE:
FE:
PM:
QA:
BE:
FE:
PM:
PM:
Need to add changes in HTML markup and BE part separately. Difficult support.
BE:
FE:
PM:
QA:
FE:
All elements are prepared as separate components.
Developers can work simultaneously.
BE:
FE:
PM:
HTML markup can be tested separately from BE part.
PM:
QA:
We need additional tools for it. Complexity increases.
PM:
FE:
BE:
FE:
Easy way to support theme during project life. As many variations of templates as we want.
BE:
FE:
PM:
Industrial method with division of labor for long-life projects.
context:
button_color: ''
button:
href: '#'
title: 'title text'
value: 'link text'
<a class="{{ button_color }}"
href="{{ button.href }}"
title="{{ button.title }}">
{{ button.value }}
</a>
Configuration (Fractal):
Template (Twig)
View
.button {
border: 1px solid $color-darker;
background: $color-darker;
color: $color-lightest;
width: 100%;
display: block;
line-height: 1.2;
padding:0.65em 20px;
margin: 0;
cursor: pointer;
@include font-family(2);
font-weight: 700;
font-size: 15px;
text-align: center;
text-decoration: none;
text-transform: uppercase;
box-sizing: border-box;
transition: background $duration-medium ease, color $duration-medium ease, border-color $duration-medium ease;
}
Styles (css/sass/scss)
JS (optional)
(function ($, Drupal, drupalSettings) {
...
})(jQuery, Drupal, drupalSettings);
context:
button_color: ''
button:
href: '#'
title: 'title text'
value: 'link text'
variants:
- name: 'Red button'
context:
button_color: 'red'
- name: 'Green button'
context:
button_color: 'green'
Configuration (Fractal):
.button--fill--veo-green {
color: green;
}
.button--fill--veo-red {
color: red;
}
Styles (scss)
View
{% for index, scheme_name in theme_colors %}
<div class="background-color--{{scheme_name}}">
{%
include 'components/button'
%}
</div>
{% endfor %}
Add to *.info.yml:
component-libraries:
myLib:
paths:
- path/components
Usage in twig template *.html.twig:
{% include "@myLib/box/box.twig" %}
{% include "@myLib/box/box.twig" with {
'value_1': 'some value 1',
'value_2': 'some value 2',
} %}
Passing variables to component in twig template *.html.twig:
1 Drupal template = at least 1 component.
Exceptions:
global-styling:
version: 1.x
css:
theme:
build/assets/styles/main.css: {}
global-scripts:
version: 1.x
js:
build/assets/scripts/main.js: {}
THEME.libraries.yml
THEME.info.yml
libraries:
- THEME/global-styling
- THEME/global-scripts
box-library:
version: VERSION
js:
build/assets/scripts/box/box.js: {}
css:
theme:
build/assets/styles/box/box.css: {}
THEME.libraries.yml
{{ attach_library('THEME/box-library') }}
{% include "@myLib/box/box.twig" %}
*.html.twig
function yourmodule_some_hook(array &$vars) {
$vars['#attached']['library'][] = 'THEME/box-library';
}
*.module
MODULE.libraries.yml
module_library:
js:
js/script.js: {}
dependencies:
- THEME/box-library
Drupal Twig filters:
t
trans
placeholder
drupal_escape
safe_join
without
clean_class
clean_id
render
format_date
Drupal Twig functions:
render_var
url
path
link
file_url
attach_library
active_theme_path
active_theme
create_attribute
{%
set classes = [
'webform',
'container',
'container--webform',
'container--width--narrow',
'container--space-outer--v-m',
]
%}
<form {{ attributes.addClass(classes) }}>
{{ title_prefix }}
{{ children }}
{{ title_suffix }}
</form>
Component webform.twig
label: 'Link'
context:
link: "<a href='#' title='' rel='nofollow'>Link</a>"
Configuration (Fractal):
{{ link }}
Template (Twig)
label: 'HTML examples'
context:
link: "<a href='#'>Link</a>"
title: "Title"
Configuration (Fractal):
{% set title = 'Title'|t %}
{% include "@myLib/component/component.twig" with {
'link': link_object,
'title': title,
} %}
<div class="title">{{ title }}</div>
<div class="link">{{ link }}</div>
Template (Twig)
Drupal template *.html.twig
{% if title is not empty %}
<div class="container">
{{ title }}
</div>
{% endif %}
Component
{% set title = '' %}
{% if content.field_title.0 is not empty %}
{% set title = content.field_title
{% endif %}
{% include @myLib/component.twig with {
title = title
} %}
Drupal template *.html.twig
Fractal (https://fractal.build)
- Bad support of Twig (https://github.com/Adyax/fractal-twig-drupal-adapter/).
- v1 is old.
Patternlab (https://drupal-pattern-lab.github.io/)
- Very good support of community.
- Atomic design methodology.