Anda di halaman 1dari 16

DRUPAL8 DEVELOPMENT

STANDARDS
Coding Standard and Best Practices

Abstract
This document covers best practices to be followed by all developers who will be working on
development and implementation of a Drupal8 CMS on Acquia platform for UNICEF.

ICTD-Solution Center and Services


Table of Contents

1 Executive summary ......................................................................................................................... 3


2 List of standardized tools which should be used while working on Drupal8 Project...................... 4
3 Creating a new Drupal8 codebase .................................................................................................. 4
4 Drupal 8 implementation structure (where do I find what) ........................................................... 5
4.1 Directory Structure ................................................................................................................ 5
4.2 Install Profile .......................................................................................................................... 5
4.3 Modules ................................................................................................................................. 5
4.4 Themes .................................................................................................................................. 6
4.5 Test directory structure ......................................................................................................... 6
5 Coding standards ............................................................................................................................ 7
6 Theme standards ............................................................................................................................ 7
7 Automated Testing.......................................................................................................................... 7
7.1 Coding standard Test ............................................................................................................. 7
7.2 Functional Test ...................................................................................................................... 7
8 Git Usage and workflow .................................................................................................................. 8
8.1 Pull Requests, commits and Code Review Guidelines ........................................................... 8
8.2 Naming Conventions when using Git .................................................................................... 9
8.3 Developer Workflow.............................................................................................................. 9
8.4 Deployment Via BLT ............................................................................................................ 10
9 Best practices for project/website development ......................................................................... 10
9.1 Composer Dependencies ..................................................................................................... 10
9.2 Configuration Management ................................................................................................ 11
9.3 Custom Code ....................................................................................................................... 11
9.4 Updates................................................................................................................................ 11
9.5 Variables naming ................................................................................................................. 11
9.6 Theme best practices ............................................................................................................................... 12
9.7 Definition of DONE during development process ............................................................... 12
10 Best practices for PR code review............................................................................................ 12
10.1 Preparation steps ................................................................................................................ 12
10.2 General checks..................................................................................................................... 13
10.3 JavaScript-related checks .................................................................................................... 13
10.4 Twig-related checks ............................................................................................................. 13
10.5 CSS and Sass-related checks ................................................................................................ 13
10.6 PHP-related checks .............................................................................................................. 14
10.7 YAML-related checks ........................................................................................................... 14
10.8 Automated Checks............................................................................................................... 14
10.9 Definition of DONE during code review process ................................................................. 15
11 Resources & additional information ........................................................................................ 15
1 Executive summary
The purpose of this document is to provide guidelines, recommendations and the minimum
mandatory requirements, which should apply to any Drupal 8 CMS based implementation using the
Acquia platform and authored by or under the responsibility of any UNICEF office.

UNICEF development standards are built to ensure a coherent and cohesive Drupal 8
implementation strategy across the organization as well as better quality, robustness and
maintainability during development, launch and post-launch.

UNICEF development standards require the use of Acquia BLT framework with Drupal native
configuration management. Using Acquia BLT enforces the development to use a set of tools, such
as Composer and NPM as the dependency management tools, and a Continuous Integration tool
(such as Travis). In addition, UNICEF highly recommends the use of a Drupal VM for easier
integration with BLT.

UNICEF requires to use configuration management approach (file-based) instead of regular SQL
database storage, in order to benefit from a versioning system for configuration in any Drupal 8
implementation.

In order to enable easier compliance of these standards, UNICEF will provide a Composer file, which
will include the list of approved Drupal modules. This Composer file will be required to be used to
create the project. In addition, UNICEF will provide a private Github repository under UNICEF Github
organization account where all development should happen.

Regular audits might be performed by UNICEF technical team to ensure compliance of UNICEF
development standards.

Additional requirements, guidelines and best practices are found in the document below.
2 List of standardized tools which should be used while working
on Drupal8 Project
The below list includes a (non-exhaustive) list of required and recommended tools to be used in any
Drupal 8 implementation.

Name of tool Description


Ticketing/Project UNICEF highly recommends the use of a project tracking tool which support
tracking software agile/scrum based projects (e.g. VSTS, Github Issues, JIRA)
tool
Github UNICEF requires the use of Github as the control versioning tool.
Acquia BLT UNICEF requires the use of Acquia BLT for deployment, build and test.
Continuous UNICEF highly recommends the use of Travis CI for seamless integration with
Integration Acquia BLT.
Bootstrap UNICEF requires the use of Bootstrap as the base theme
Acquia Lightning UNICEF requires the use of Acquia lightning distribution profile.
distribution

3 Creating a new Drupal8 codebase


UNICEF requires to use composer to manage dependencies with the codebase. For creating a new
Drupal8 codebase, UNICEF will provide composer files. Any deviation from the included core and
contributed modules and versions will have to communicated/coordinated with UNICEF
development team for approval before implementation.

Please note that UNICEF composer includes Acquia BLT framework to manage and deploy code and
database, as well as Acquia lightning distribution and additional contributed modules those are
approved by UNICEF.

UNICEF standards highly recommends the use of Drupal VM, as it provides a self contained
environment for local development. More information is found at https://www.drupalvm.com/

UNICEF standards requires the use of Drupal native configuration management approach (file-
based), as it provides a versioning system for configuration instead of regular SQL database storage.
More information on configuration management is found at
https://www.drupal.org/docs/8/configuration-management
4 Drupal 8 implementation structure (where do I find what)
This section describes the required implementation architecture structure that should be followed:

4.1 Directory Structure


Top-Level directories

/blt
/config
/docroot
/composer.json
/travis.yml

Second-level directories

/docroot/modules/
/docroot/profiles/
/docroot/sites/
/docroot/themes/

4.2 Install Profile


Install profile in Drupal 8 has all the functionality of modules, including access to hooks and plugins
and, critically, the ability to provide configuration for the site in the form of .yml files.

The profile name should consist of lowercase letters and underscore only.

Creation of the profile should be based on the lightning profile. For more details about how to create
sub-profile, refer to Acquia's documentation - https://docs.acquia.com/lightning/subprofile

Should the codebase make use of different profiles, the below structure should be followed.

/docroot
/profiles
/custom
/profilename
/config/
/modules/
/README.md
/profilename.info.yml
/profilename.install
/profilename.profile

4.3 Modules
The code base should include the following structure for contributed and custom modules:

/docroot
/modules
/contrib
/custom/
/example/
/example.module
/example.info.yml
/example.libraries.yml
/example.install

NOTE: The list of approved modules is included in the UNICEF composer file. Please note that any
additional contributed modules required for the project should be communicated/coordinated with
UNICEF technical team for approval before implementation.

4.4 Themes
The code base should include the following structure for sub-themes:

/docroot
/themes
/contrib
/custom
/sitetheme
/assets
/images
/templates
/sitetheme.info.yml
/sitetheme.libraries.yml
/sitetheme.info.yml
/sitetheme.breakpoints.yml

4.5 Test directory structure


The code base should include the following structure for testing files, which will be created as part of
Acquia BLT configuration:

/Tests
/behat - contains all Behat tests
/features
/bootstrap
/Example.feature
/behat.yml - contains behat configuration common to all
behat profiles.
/integration.yml - contains behat configuration
/phpunit - contains all PHP Unit tests
5 Coding standards
The Drupal community has outlined some pretty comprehensive coding standards for code written
and contributed to the Drupal community. The same standards should apply to any UNICEF Drupal 8
project. All the code should comply to the coding standards defined at
https://www.drupal.org/docs/develop/standards

6 Theme standards
Any custom theme should be created from base theme bootstrap, as a sub-theme. New theme
should follow SASS theming standard defined at https://drupal-
bootstrap.org/api/bootstrap/docs%21Sub-Theming.md/group/sub_theming/8

NOTE: The theme should be used strictly as a display layer and should not contain large amounts of
business logic or other JS/code.

7 Automated Testing
Drupal 8 development should include automated test coverage as below:

7.1 Coding standard Test


BLT includes automated testing for coding standards through linting/sniffing by default. More
information is found in section 10.8 Automated checks.

7.2 Functional Test


Behat Tests: Any development should include Behat test for all business logic and user interfaces
that are accessible via the browser. Functionality should be expressed as a behavioral test for
automated testing.

By default, the two primary areas of testing should be on the content model/content structure
implementation and user roles & permissions.

At a minimum each Pull Request submitted by a developer should include either a complete
behavioral test of the 'sunny skies' scenario of the story being built, or an update to an existing
scenario if this is a bug fix.

Behat resources can be found in a variety of places, here are a few extra reading links:

http://behat.org/en/latest/user_guide/context.html

http://docs.behat.org/en/v2.5/guides/1.gherkin.html

https://media.readthedocs.org/pdf/behat-drupal-extension/latest/behat-drupal-extension.pdf

Examples of Behat tests can also be found at:


<root>/vendor/drupal-
extension/src/Drupal/DrupalExtension/Context/DrupalContext.php
<root>/docroot/profiles/contrib/lightning/tests/features/*

PHPUnit Test: PHPUnit integration/unit test should be used for functionalities that are not reachable
by the browser. Examples: inside Cron logic, server-to-server communication of any kind, API
integrations, etc. The Drupal community maintains an excellent documentation.

8 Git Usage and workflow


All development should be done in a version control system, such as Git. Github software should be
used. Please contact UNICEF technical team to get a UNICEF private repository for your project.

When working with Github and Acquia, the following rules and workflow should be followed:

• The main git repository should contain at least a develop, a master and a hotfix branch
• All developers will work on their forked version of the repository
• Development can happen in parallel on different branches. Once finished should be merged
to Develop branch
• Developers will create pull requests against their main repository
• Once a pull request happens, a code review should be done by another developer, before
being merged to the main repository.
• Stable code will be released via Release branch (created from develop branch), it will be
tagged accordingly for production release and moved to master branch.
• Hotfixes will be managed by a hotfix branch and will be deployed to Prod environment via
another tag.
• Hotfix branch will later merged to develop
• Developers will be allowed to push directly to the Acquia dev environment.

Regular audits might be performed by UNICEF technical team to ensure compliance of UNICEF
development standards.

On those special cases when the project/website will live under the same codebase managed by
UNICEF development team, all deployments to staging and production environment will be
handled by UNICEF, once a code review is approved by UNICEF team.

8.1 Pull Requests, commits and Code Review Guidelines


Pull requests have a number of aspects that should be followed:

• The title of the pull request should include the ticket number and description. E.g. "VSTS-
1234: Fix template style on hero image”.
Pull requests should only contain the work relevant to the story being resolved. Do not
combine issues, or attach 'rider along code' that is unrelated.
Discussion during the review process should be kept civil. It is important to remember that
the code being reviewed is not art, and issues raised are only helpful to the cause.
Commit messages should identify the ticketing system issue number they are related to.
Note that this will not always line up with the number identified in the branch. for example,
if VSTS-1234 has a subtask, that issue might be referenced in the commit. EG:
"feat(new_module): 1235 - Added micro version handling."
Commits should be isolated to working groups of changes only. Do not commit non-
functional code, or split functionality between commits if they are dependent on each other.
Code reviews should follow best practices for theme review, as found in
https://www.drupal.org/docs/develop/standards/css/what-to-look-for-when-reviewing-css

8.2 Naming Conventions when using Git


The below naming conventions is recommended when committing and pushing code.

• commit message – Format is “task_type (very short task desc): task_id – description of
commit”
Task types are:
o feat (new feature)
▪ eg- feat(search): 1564 - updated search block markup
o fix (bug fix)
▪ eg: fix(country): 1564 - error for country module dependency.
o docs (changes to documentation)
▪ style (formatting, missing semi colons, etc; no code change)
o refactor (refactoring production code)
▪ eg: refactor(migration): 1564 - removes duplicated migration file
o test (adding missing tests, refactoring tests; no production code change)
o chore (updating grunt tasks etc; no production code change)
Branch Naming <type>-<name>
o <type>
▪ feature - New feature.
▪ release - New release.
▪ hotfix - Quick fixes to the codebase.
▪ junk - Experiments (will never be merged).
o <name>. Always use dashes to separate words, and keep it short. Examples:
▪ feature-renderer-cookies
▪ release-3.0

8.3 Developer Workflow


This section describes the workflow that developers should follow when committing their work to
the main repository.

Create a new/update an existing feature:


o Developer should create your own fork (forked repository) from main project
repository (upstream repository)
o On your local system you execute git clone on e.g.
https://github.com/<your_fork>/main-repository-name to get a local copy of the
repo
$ git clone https://github.com/<your_fork>/main-repository-name
o Add remote to local clone of forked repository (link local clone to upstream repo)
$ git remote add upstream https://github.com/unicef/main-repository-name
o You create a new feature branch in your local clone repo called feature-name
$ git checkout -b feature-name
o Work is done to complete the new feature and git commit is executed to save the
changes
$ git commit -a -m "Add first draft of migration code”
o Take latest code changes from original upstream repo (Run this command when
there is new updates on original repository) **
$ git pull upstream develop
$ git merge develop
o You then push the new feature branch to your remote forked repository
$ git push origin feature-name
o Using github you open up a pull request for the new branch “feature-name” against
the original repo at github.com/unicef/main-repository-name “develop” (merge
should be performed using –no-ff flag or Git merge from interface, do not use
either squash or rebase merge)

o Once merged delete your branch - git branch -d feature-name

8.4 Deployment Via BLT


As a vendor, you will need to deploy to Acquia cloud environment. The deployment should happen
automatically after Pull Request gets merged to the main repository if you are using Travis CI. The
configuration for the Travis CI should be similar as follows:

Configure the deployment at blt/project.local.yml:


git: default_branch: migration-build
remotes: 'unicef@svn-12345.prod.hosting.acquia.com:unicef.git'

More information about deployment workflow is found in:

https://blt.readthedocs.io/en/latest/readme/deploy/

More information about continuous integration is found in:

https://blt.readthedocs.io/en/latest/readme/ci/

9 Best practices for project/website development


The following are a list of best practices that should be followed by any Drupal CMS project. Many of
these are driven by the project's use of Acquia BLT.

9.1 Composer Dependencies


Contributed modules, and libraries must not be included in our code base. All external code (code
managed in public repositories) should be added as composer dependencies, and given proper
upgrade paths. Any modules, or components that require patches should have those patches added
to the master composer.json file, with accurate descriptions associated with each patch.

9.2 Configuration Management


All Drupal configuration should be exported to code in the form of config management using config
split and ignore that can be deployed to the site. Configuration should be exported to the config/
path outside of the document root.

For multisite implementations on single codebases, config-split over feature based implementation
should be adopted.

9.3 Custom Code


Custom code should always 'live' with the configuration it supports. Sometimes this means it exists
in and is maintained in a feature module - Considering these modules are auto-generated, this may
sound strange but the source files where this code is housed is always preserved during exports,
making these modules the ideal location for the glue-code that supports them.

Sometimes custom modules are not directly tied to a feature. In these cases the module should be
moved to the <root>/docroot/modules/custom folder, which will be maintained and tracked via Git
(unlike its 'contrib' counterpart).

9.4 Updates
Access to upstream environments should strictly be controlled, and a "zero touch" process is in
place. This means that no manual changes can take place on the servers, every update must be
deployed automatically. This comes in the form of 'hook_update_n()' functions. These functions are
required when any of the following conditions are needed:

Fields are renamed


Fields are deleted
Fields are changed from one data type to another
Fields are moved from one entity type to another
Data is manipulated
Content must be created

All of the reasons above must also be taken into account in either the module's config/install folder,
or in the hook_install() function, depending on the use case. For example: A renamed field must
have the config/install folder adjusted to take into account the new field name, and a
hook_update_n() needs to be created to transition the data to the new field, and remove the old
field. Creating a mandatory node however, it does not need the config/install folder adjusted, but
does need to be handled in both hook_install() and a hook_update_n() function.

9.5 Variables naming


When creating a new component/template starting from Front-end side, these instructions should
be followed to map the variables name to be used in templates.

• Prefix should start with ‘field_’ plus field name. e.g: field_[name] -> field_author
Body and Title are Drupal default fields, and the should be kept as it is. If necessary, the
same structure as above should be followed. e.g.: field_body or field_title

This way rework at variable’s renaming will be avoided since it will match both sides.

If development starts with Back-end side first, then this variable naming convention should also be
followed and Front-end will replicate the same variable names in templates.

9.6 Theme best practices


UNICEF recommends to use drupal 8 theme standards documentation found in
https://www.drupal.org/docs/develop/standards/css/css-architecture-for-drupal-8.

9.7 Definition of DONE during development process


The below information is used by UNICEF development team to ensure the quality of the process
during development process. UNICEF recommends to follow these rules:

The work of the developer is considered done when:

✓ Functionality passes the acceptance criteria


✓ Manual test is provided, modified if needed and passing
✓ Automated test is provided if needed and passing
✓ Code complies to Drupal coding standards, and the guidelines & best practices mentioned in
this document
✓ A pull request is created, assigned to a reviewer and How-To-Test are provided
✓ CI build is passing
✓ If issue type is bug, a short description of the solution is provided
✓ The issue has been set to a reviewer with the correct status

10 Best practices for PR code review


This section covers pull request code review best practices. UNICEF recommends following them
when reviewing other developers’ work.

10.1 Preparation steps


1. Checkout the PR code:

`git fetch <upstream_repo> pull/<PR id>/head:<name for new branch>`


(e.g `git fetch unicef pull/265/head:Release20171201`)
`git checkout Release20171201`

2. Open the source code of the project in an IDE


This is helpful to quickly look up relevant source code parts, or rely on the built-in inspections of the
IDE.1

10.2 General checks


Check the naming of functions, PHP classes, CSS classes, files, constants, SASS mixins, etc.
The names should be clear and concise.
Duplicated or very similar, code parts are problematic and should be removed in every file
type.
Code comments should be checked, that it's not copy and pasted with irrelevant pieces, and
that it is meaningful and provides value for the reader of the source code. This applies to
every file type.
Check whitespaces in every file type.2
Commented out code parts should be removed in almost every case, Git history is there to
restore any previous state if needed.
Check for obviously not used variables, rules, files, classes.
Check if Travis passed for the last commit.

10.3 JavaScript-related checks


Check the use of the Javascript API: Behaviors, settings, context.3
Check Javascript code format.4
• Excessive amount of custom, project-specific JavaScript code is a “code smell,” for a typical
Drupal project. Most functionality should be solved in PHP or using a JavaScript-based
library.
Check that errors of any kind are handled properly (e.g., unsuccessful HTTP requests)

10.4 Twig-related checks


BLT does validation automatically.
Check for indentation and spacing issues.
Check for absolute, hard-coded URLs that might cause issues if the base URL changes.
Check for HTTP-only included resources (will result in mixed content warning).

10.5 CSS and Sass-related checks

1
For PhpStorm, see
https://confluence.jetbrains.com/display/PhpStorm/Drupal+Development+using+PhpStorm ; For
Atom.io, see https://atom.io/packages/linter-drupalcs
2
https://www.drupal.org/docs/develop/standards/coding-standards#indenting
3
see https://www.drupal.org/docs/8/api/javascript-api/javascript-api-overview.
4
https://www.drupal.org/docs/develop/standards/javascript/javascript-coding-standards - use eslint to
check automatically (https://www.drupal.org/node/1955232).
Check code format.5
If in doubt that something is valid SASS, compile it.6
Check for HTTP-only included resources (will result in mixed content warning).

10.6 PHP-related checks


Use local static code analysis, like Drupal coding standard check, to spot obvious problems,
see below, report all issues.
Check for security issues, SQL injections and XSS. SQL injection can come from un-sanitized
user input, directly appended to SQL query. XSS typically come from unsanitized user input
sent to the output without filtering.7
Check for hard-coded paths, hard-coded URLs.
Check for HTTP-only included resources (will result in mixed content warning).
Check for proper usage of the Drupal API. If there is an API function or class for the purpose,
custom code should not be written, rather the code should rely on the existing solution. This
is the hardest part of the code review, as it requires an extensive knowledge of Drupal.
Errors of any kind should be handled and logged with Logger properly.
Check for validation of data forms. Validation should happen when accepting data from the
user, typically handled by the Drupal API.
Do performance-related checks, to determine if something seems to be a resource-heavy
operation. If so, question it; check if it's cache-able

10.7 YAML-related checks


Follow https://www.drupal.org/docs/develop/coding-standards/configuration-file-coding-standards

10.8 Automated Checks


Setting up PhpCS8

The ruleset can be found at the installed project too:

vendor/drupal/coder/coder_sniffer

If for any reason, it's needed globally (for other projects, contributed modules and so on):

git clone --branch 8.x-2.x https://git.drupal.org/project/coder.git


cd coder
composer install

5
https://www.drupal.org/docs/develop/standards/css/css-formatting-guidelines
6
http://beautifytools.com/scss-compiler.php
7
Refer to https://www.drupal.org/docs/8/security/writing-secure-code-for-drupal-8 for details
8See https://github.com/squizlabs/PHP_CodeSniffer and http://drupal.org/project/coder
Bash aliases:

These aliases should be appended to .bash_profile (MacOSX) or to .bash_rc (Linux):

alias codingstd='<path to main-repository>/vendor/bin/phpcs --


standard=<path to global-reb-
redesign>/vendor/drupal/coder/coder_sniffer/CodeSniffer/Standards/Drupal/ru
leset.xml --extensions=php,module,inc,install,test,profile,theme'

alias drupalpr='<path to main-repository>/vendor/bin/phpcs --standard=<path


to global-reb-
redesign>/vendor/drupal/coder/coder_sniffer//CodeSniffer/Standards/DrupalPr
actice/ruleset.xml --extensions=php,module,inc,install,test,profile,theme'

Setting up ESLint

Drupal 8 provides ESLint configuration out-of-the-box. To perform the initial setup:

cd docroot/core
npm install

Then to inspect an individual file:

<path to repository-name>/docroot/core/node_modules/eslint/bin/eslint.js
[target_custom_js]

10.9 Definition of DONE during code review process


The below information is used by UNICEF development team to ensure the quality of the process
during the code review process. UNICEF recommends to follow these rules:

The work of the code reviewer is considered done when:

✓ The code looks good


✓ The How-To-Test steps can be executed
✓ The manual test is executed successfully
✓ The pull request is merged into the correct branch
✓ The issue has been completed

11 Resources & additional information


Below is a set of URLs to documentation pertaining to various topics covered above and or general
reference resources.

• Acquia's Documentation: https://docs.acquia.com/documentation


• Acquia's BLT: https://blt.readthedocs.io/en/8.x/
• Travis CI Documentation: https://docs.travis-ci.com
• Composer: https://getcomposer.org

Anda mungkin juga menyukai