Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Project structure

A Drupal project has many folders, but only a few of them are meant to be changed. It is important to see at once where core is, where other people's modules are and where your code goes.

Project folders

site/
├── composer.json
├── vendor/
└── web/
    ├── core/
    ├── modules/
    │   ├── contrib/
    │   └── custom/
    ├── themes/
    │   ├── contrib/
    │   └── custom/
    ├── sites/
    │   └── default/
    │       ├── settings.php
    │       └── files/
    └── index.php

The custom folders do not exist after installation — create web/modules/custom and web/themes/custom by hand.

Folder or fileWhat it holds
composer.jsonThe list of project packages: core, modules, Drush
vendorDownloaded PHP packages. Never edited
webThe site root: the web server points at it
web/coreDrupal core. Never edited
web/modules/contribReady-made modules installed through Composer
web/modules/customYour modules
web/themes/customYour themes
web/sites/default/settings.phpThe database connection and site settings
web/sites/default/filesFiles uploaded through the site: images, documents

What goes into Git

The repository gets composer.json, composer.lock, the custom folders and the configuration files. The vendor, web/core, web/modules/contrib and web/sites/default/files folders are not committed: the first three are restored by composer install, and uploaded files belong to the site content.

The module folder

Each module is a separate folder inside web/modules/custom. In the course it is blog. By the end of the course it looks like this:

web/modules/custom/blog/
├── blog.info.yml          module description
├── blog.routing.yml       page addresses
├── blog.links.menu.yml    menu links
├── blog.permissions.yml   permissions
├── blog.services.yml      services
├── blog.libraries.yml     styles and scripts
├── blog.module            hook functions
├── blog.install           tables and updates
├── config/                default settings
├── templates/             Twig templates
├── css/  js/              style and script files
└── src/                   PHP classes
    ├── Controller/
    ├── Form/
    └── Plugin/

File names start with the module name. Classes live in src, and their namespace starts with Drupal\blog: the file src/Controller/BlogController.php holds the class Drupal\blog\Controller\BlogController.

None of these files except blog.info.yml is required — they are added as the need arises.

Common mistake

Editing files in web/core or web/modules/contrib looks like the shortest way, but the changes disappear at the next composer update. Other code's behaviour is changed from your own module — with hooks and event subscribers — and markup is changed from your own theme.

Thanks for reading!

Donate to the site — we work hard for you.