Drupal administration

by Gisle Hannemyr

This chapter discusses some of the interfaces and tools you may use in the day to day administration of a Drupal-based website.

Table of contents

Drupal extensions mentioned in this chapter: Backup and migrate, Pathauto, Token, User restrictions.

Administration menu

When you are logged in as the administrator of a Drupal 8 website, a menu with links to the various components of the administrator's interface will appear at the top of the screen.

admin_menu8.png
The Drupal 8 administrator's menu.

The screenshot above shows the the administrator's interface (black and white) and the page header (blue) as displayed by the default theme (Bartik). Inside the page header is the site name (“Web Times”) and slogan (“All the content that's fit to manage”).

The hamburger menu on top left (“Manage”) can be used to hide an expand the white line that holds the items you may manage. (“Shortcuts”)

Site information

To change site information, navigate to Manage » Configuration » Basic site settings. Many of the settings on this page (e.g. site name and the site's email address) are already filled in with information prompted for by Drupal's installation script.

The site name is used in a number of places on the website, including the page header at the top of each page (if the theme is set up to display it), and in the registration and cancellation emails.

The slogan is usually displayed in the page header, just below the title. Like the title, its placement is really controlled by the theme.

The site's email address is used as the From address in all the emails that are sent automatically. I usually set up an non-personal email account such as admin@sitename.com or webmaster@sitename.com for this field (where “sitename.com” is the site's domain name).

Managing users

General user account settings

The interface for configuring settings that apply to all users are Manage » Configuration » People » Settings. This interface lets you configure default behaviour of users, including registration requirements, emails, fields, and user pictures.

tipIn Drupal 6, the core allowed the administrator to enforce access rules to control whether a given user name, email address and/or host should be allowed to create an account or to log in. This could be used to require or disallow spaces in a user name, to enforce that only users with email-addresses in certain domains should be allowed to create an account, etc. Access rules was removed from the core of Drupal 7. If you need this functionality, you need to install the User restrictions package.

The screen shot below shows the top of this form. The two first items lets you set the display name for the predefined anonymous user roles (default “Anonymous”), and to pick the role that shall be granted the rights of the site administrator (default “administrator”). The third item shown below sets site policies for registration and cancellation og accounts.

user_accset01.png

The next item in the account settings for sets policies for signatures (text added automatically below any content created by the user) and user pictures (avatars). If you enable user pictures, there are some additional settings available.

user_accset02.png

If you choose to Enable user pictures, you should also specify the URL of a default picture to display if the user does not upload a picture.

The final item lets you customise the text of the emails that is sent by the systems as an response to miscellanenous account events, such as the adminsitrator creating a new user, the registers an account, etc.

user_accset03.png

When done comfiguring the account settings, press Save configuration to save the settings.

Adding fields to the user entity

The basic user entity only contains a few basic fields (e.g. uid, name, pass, mail, theme, signature, picture and a few more). To add more fields to an user entity in Drupal 7, you go to Manage » Configuration » People » Account settings » Manage Fields and add the new fields you want (e.g. real name, phone, number, address, favourite colour, etc.). To define a new field, you must assign the field a label, an internal machine name, a field type, and a widget to handle the form entry processing.

user_fields01.png

The value Weight determines the position of the field in the user rehistration form. Larger values (heavier weights) “sink” to the bottom. To determine the postion and appearance of the field when the user profile is displayed, click on the tab Manage display.

Cancelling users

Currently, the only means of finding out whether a user is still active is to list the users (People » List) and sort the user list according to Last access.

It is safe to cancel an inactive user. If you do, you will be asked what to do with the account and its content. There are four alternatives:

Undesirable users may be blocked. As long as they are blocked, they cannot log on and they cannot re-register with the same email address.

noteThe error messages shown to blocked users are less than obvious. They are told the account do not exist if they try to log on or to get a password reminder. If they try to re-register, they are informed the account already exists.

With comments, there is a provision for placing content created by certain user types (e.g. anonymous users) in a moderation queue, while other user types can create pre-approved content. For other content types, the work-flow settings may be used to force certain content types to be moderated.

URL aliases

By default, Drupal labels nodes with a number. To create URLs that is more meaningful (for instance to hand out to third parties), the Path module that is part of the Drupal core provides a way to create meaningful URL aliases.

To turn on this, first navigate to Manage » Extend and tick Path. Next, navigate to Manage » People » Permissions, and set the following permissions: Administer url aliases and Create and edit url aliases for the roles you want to give this capability. You would normally only let administrators do this.

Now, for those allowed to administer url aliases, there will be a Manage » Configuration » Search and metadata » URL aliases page to list existing URL aliases and to add new URL aliases.

URL aliases can also be added when a node is posted or edited (provided the user has sufficient permissions). You do this by editing the field under URL alias in the vertical tab.

See alsoBy installing and enabling the Pathauto and Token modules, URL aliases will be created automatically, without requiring the author of a node to manually specify the path alias. The aliases are generated by a pattern-based system that uses tokens set by the administrator.

Cron

Drupal comes with a built-in Cron function (sometimes referred to as “poor man's cron”) that is used by the system to perform periodic tasks. The built-in cron can be set up to run at specified intervals by navigating to Configuration » Cron (default is every three hours). Setting a longer interval helps reduce server load, but can also cause unwanted effects, such as search lagging behind content.

Drupal will automatically run the built-in cron whenever a page is requested if Cron has not been run within the requested interval.

Clicking the Run cron button runs cron immediately.

Unfortunately, Drupal's built-in cron significantly impacts page load performance when it runs. That is OK for a development site, but should be avoided in a production site. Instead, you can set up a Unix or Gnu/Linux to use crontab to trigger a cron run on a Drupal site. This will provide more predictable and reliable behaviour, and has less of an effect on delays that may impact users. You can do this by having a crontab-entry that pokes cron.php.

For example, each of the following crontab entries will run the cron task at 03:04 every night:

4 3 * * * /usr/bin/curl --silent --compressed http://example.com/cron.php?cron_key…
4 3 * * * /usr/bin/wget -O - -q -t 1 http://example.org/cron.php?cron_key=A0p8k5z2…
4 3 * * * /usr/bin/lynx -source http://example.net/cron.php?cron_key=A0p8k5zAb0p5w…

(Provided, of course, that curl, wget or lynx are available on the machine that runs the cron job. I provide three different command examples so that you can pick one that is available. Only one of these is of course required.)

Notice the secret cron_key passed as an argument with the URL. This is to prevent others using cron as a vector for a denial of service attack. Navigate to Reports » Status report to view the URL for your site. Without the right cron_key, nothing will happen.

When you set up an external cron trigger, you should disable Drupal's built-in cron by setting its frequency to “Never”.

noteIn addition to the above: If your site receives very little traffic, and you depend on cron for critical maintenance tasks, you cannot rely on page loads to trigger cron. Instead, set up cron to be run from the outside.

In an environment with a cluster of hosts, where your initial login-shell may be on a random host, it may be a good idea to include something like the following entry in the crontab. It will append a line each day to the named log-file recording the name of the host where there is an active crontab. Normally, you don't want more than a single active crontab in a cluster.

4 3 * * * echo `date` `hostname` >> /hom/gisle/crontab.host

There are several ways to maintain the crontab. I prefer to create a text file with all the entries I want in my crontab in a file named crontab.txt. I then can create an active crontab or replace the current crontab with the contents of that file with the following shell command:

$ crontab crontab.txt

To list the content of your current active crontab, you log on to the host where your crontab is active, and type the following shell command:

$ crontab -l

For a stable personal site, you might set up this cron job to run once a day. For a more active site you might want to run that job more often – perhaps every few hours or every hour.

See alsoDrupal 7 uses cron for a number of recurring tasks such as: indexing the site's content for search, retrieving feeds for the news aggregator, checking for updates, sending out notification, and various maintenance tasks (e.g. truncating log files). To learn more about cron jobs in Drupal, see the Drupal.org website.

Troubleshooting cron

Cron may fail due to tasks set up my activated modules is exhausting memory allocted for PHP. The error message will look like this:

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate
8192 bytes) in …/includes/database/database.inc on line 2227

To see the maximum allowed memory size, check Drupal's status report the by clicking the PHP-link for “more information”, and search for the value memory_limit. A typical PHP configuration will be set up with a value for 128 Mbytes (134217728 bytes).

If you run out of memory during cron runs, ensure that your PHP memory_limit is set high enough. You can find out how much is required by setting it very hight and enabling Memory profiler. You'll find the memory consumed in the watchdog log. To increase the memory limit for a vhost, change the setting in its configuraton file and restart the web server. For instance, to set it to 4096 Mbyte, use:

php_value memory_limit 512M

See also: Changing PHP memory limits.

To get email alerts about this error, enable Notify Cron Failed (Drupal 7 only).

If you get this error message:

"Attempting to re-run cron while it is already running."

There may be a number of underlying causes for this. If your cron is sceduled too frequent, this will happen. However, another possible cause is that there is bug somewhere that makes the site crash halfway trough the cron run, preventing cron from finishing. To look for the underlying cause, examine the "Recent log messages" report and the Apache error log.

Tou may also want to read: https://www.drupal.org/docs/7/setting-up-cron/troubleshooting-cron

If cron fails, a workaround to get stuff cleaned up is to use drush to clear the cron semaphore, refresh all caches, and then run cron from drush:

$ drush sqlq "DELETE FROM semaphore WHERE name = 'cron';"
$ drush cr
$ drush cron

For more cron troubleshooting tips, read Troubleshooting cron at Drupal.org.

Updating Drupal

noteIf you are unable to update because there is no space left, check for full root file system. If it is full, you need to free up some space.

Doing a minor update of the core

Semantic versioning is a specification for numbering software releases. It is being used by more and more free software projects, including Drupal. Semantic versioning is only meaningful if the package has a public API.

semver.png

Semantic version uses three integers for the release version. These are:

  1. Major version. Upgrades will break the API.
  2. Minor version. For introducing new features. Backwards compatible with API.
  3. Patch. For bug and security fixes. Backwards compatible with API.

A “minor update” in Drupal-speak is any update that will not break the API. Updating the core version 9.5.10 to 9.5.11 is a minor update, as is updating from version 9.4.0 to 9.5.11. Updating from version 9.5.11 to 10.1.6 is a major update.

Minor updates are issued frequently for the Drupal core. A minor update may add requested features, fix bugs and/or deal with security issues. Usually, you want to install a minor update as soon as possible after it is released to maintain the integrity and security for your Drupal installation.

Doing minor updates of the Drupal core is usually quick and painless, provided you've observed Drupal's prime directive, which is: Do not hack the core. Likewise, you should not hack extensions that are maintained elsewhere. This essentially means that you should avoid touching any code outside the directories modules/custom and themes.

noteDoing a major upgradeof the Drupal core (e.g. from Drupal 7 to Drupal 8) has so far not been quick and has been far from painless. Describing how to do it is beyond the scope of this ebook. This has changed, and the transition from Drupal 8 to Drupal 9 is a much smoother process.

If your installation is clean (i.e. you haven't hacked core), and your file system permissions are set correctly, you can do bring the core up to the latest version by using the CLI. The preferred method for updating Drupal 8 is using composer.

See alsoAlso see Drupal.org: Update core via composer.

The following command should tell you if version of the Drupal core in use is outdated:

$ composer show -l 'drupal/*'
drupal/console               1.9.2 1.9.2  The Drupal CLI. A tool to generate …
drupal/console-core          1.9.2 1.9.2  Drupal Console Core
drupal/console-en            1.9.2 1.9.2  Drupal Console English Language
drupal/console-extend-plugin 0.9.2 0.9.2  Drupal Console Extend Plugin
drupal/core                  8.7.5 8.7.6  Drupal is an open source content …
drupal/devel                 2.1.0 2.1.0  Various blocks, pages, and …

If the version numbers differ, an update is available.

To update the Drupal core with Composer:

$ composer update drupal/core --with-dependencies

After updating, you should also run any pending database updates and rebuild the cache:

$ drush updb
$ drush cr

If there are no pending updates, it will do nothing. This command is also quick way of making sure all pending updates have been run.

If you're not able to update, you may want to read about troubleshooting composer problems

tipThere exists a module named Automatic Updates to automate minor updates of the core.

Updating extensions

Maintainers in the Drupal community maintain their contributed extensions on a regular basis. An update may be due to a security problem being discovered and fixed, a bug being fixed, or just to add new features.

To check what Drupal packages that can be updated on your site, you can use one of the following CLI commands:

$ composer update --dry-run 'drupal/*'
$ composer show -l -o 'drupal/*'
$ composer outdated 'drupal/*'

The first will tell you what will be updated if you run composer update. The two last will both show a list of Drupal packages that is behind the latest version (the third is just an alias for the second).

If you drop the 'drupal/*' argument, it will tell you about everything that can be updated.

The security status from Drupal.org isn't available through . To get the security update status, use drush:

$ drush pm:security

To update a Drupal module extension named “examplemodule” with composer:

$ composer update drupal/examplemodule --with-dependencies

Finally, run any database updates and rebuild the cache:

$ drush updb
$ drush cr

See alsoWhen updating a multisite, drush may save you a lot of work since you can just add @sites to the drush database update command (i.e. drush @sites updb) to run the datebase update script for all the sites. For more about this, see Carl Vuorinen's post on Updating a Drupal multisite using drush. However, I have mixed experienced with this. Using this methods sometimes results in crashes due to unsufficient memory. An alternative is simply to screate a bash-script that decends into each individual site, sleeping between iterations to allow memory to be released.

To update more than a single module, you may use other variants of “composer update”. Examples:

$ composer update                     # Update everything.
$ composer update --with-dependencies # Update everything, including dependencies.
$ composer update 'drupal/*'          # Update all Drupal packages.
$ composer update 'drupal/console*'   # Update all packages matching the pattern.

The “composer update”-command will ignore composer.lock and update all dependencies in composer.json according to your requirements. Note that if one of the packages it updates has broken code in its latest release this may break the site. This means that it is probably not a good idea to update everything. It is also a good idea to never run composer update on a production server. Instead, do this on a staging server, and mirror the result to the production server when you are sure that the changes to the code base are OK.

See alsoAlso see the Drupal.org: Update modules and StackOverflow.com: Exclude a package from updating in composer.

If you are on an untagged dev-branch, composer outdated will suggest the most recent dev-branch snapshot:

$ composer outdated drupal/fixteaserlinks
drupal/fixteaserlinks        1.x-dev 93ffd52 1.x-dev 29dbca7 Control visibility of …

If a tagged release exists, Using composer require will download that release and update composer.json:

$ composer require drupal/fixteaserlinks
…
$ composer show -l drupal/fixteaserlinks
drupal/fixteaserlinks        1.0.0-alpha1    1.0.0-alpha1    Control visibility of …

When composer downloads extensions from Drupal.org, it will include the .git directory along with it.

#! /bin/bash
composer update 'drupal/*' --with-dependencies
drush updb
drush cr

tipTo save some typing, you could create a bash script for updating Drupal 8 core and modules with composer (doing what “drush pm:update” did for Drupal 7). I've done so and named it drupal8_update.sh. It is in the $PATH for my ordinary user. You need to run this in (or below) the site root.

Downloading and installing/updating manually

When using drush version 9, the commands for downloading (pm-download) and updating (pm-update) has been deprecated. However, if you do not want the project managed by composer, you may download and update manually.

First, if the package is managed by composer, remove it from the root composer.json and composer.lock:

$ composer remove drupal/examplemodule

Installing or updating manually involves the following steps:

  1. Make sure the old version is unistalled and physically removed from the project.
  2. Download a tarball with the package from the Drupal.org repo or from your own repo.
  3. Unpack it as per standard procedure when installing Drupal packages.
  4. Run the database update script.

The main use case for this is module development, when the version you want to test is not available via composer.

Final word

[mumble]


Last update: 2019-08-25.