Drupal 安装

Drupal 8 安装

先完成 www 目录维护 的指示;再继续。

安装 Drupal 条件

PHP 7.3.x

安装 Drupal 8
FileName=drupal-8.9.7 (1)
site=drupal (2)

cd /var/www
wget https://ftp.drupal.org/files/projects/$FileName.tar.gz

tar -xzf $FileName.tar.gz

# 改名为 $site
mv $FileName /var/www/$site

# 别忘了要修正权限
chwww $site

# 如果要创建数据库
mysqlpw='MySQL root 密码'
webdbpw='站台数据库密码'

mysql -uroot -p$mysqlpw --host=localhost --port=3306 --protocol=tcp -N << EOF
drop database if exists $site; (3)
create database $site;
grant all privileges on $site.* to '$site'@'localhost' identified by '$webdbpw';
use mysql;
update user set plugin='mysql_native_password' where user='$site';
EOF
1 查出 Drupal 8.9 之后的版本 Drupal 7.7 之后的版本
2 site 为站台目录及数据库名称亦为 Apache 的 .conf 文件名。
3 注意!删除站台数据库。
$site.conf
site=drupal

sudo a2dissite 000-default.conf (1)

sudo bash -c "cat > /etc/apache2/sites-available/$site.conf" << EOF
<VirtualHost *:80>
  ServerAdmin webmaster@localhost
  DocumentRoot /var/www/$site
  RewriteEngine on
</VirtualHost>

<Directory /var/www/$site>
  AllowOverride None
  Include /var/www/$site/.htaccess
</Directory>
EOF

sudo a2ensite $site
sudo service apache2 reload
1 取消 Apache 安装时创建的 000-default.conf 站台。

安装 Composer 及 Drupal Console (重要),再来就可以进入站台安装,安装英文 (别装中文)!

Composer

安装 Composer
sudo apt update
sudo apt install curl

# 会安装最新版, 可能跟目前的 drupal 8/9 不兼容
# curl -sS https://getcomposer.org/installer | php
# Composer (version 2.0.4) successfully installed to: /var/www/composer.phar
# sudo mv composer.phar /usr/local/bin/composer

# 采用指定版本
curl -sS https://getcomposer.org/download/1.10.17/composer.phar > composer.phar
sudo chmod +x composer.phar
sudo mv composer.phar /usr/local/bin/composer

composer --version
# Composer version 1.10.17 2020-10-30 22:31:58
Composer 常用指令 (除非是 global 否则在运行前必须将目录切换至 $site)
# composer 自我更新 (跟目前路径无关)
composer self-update (1)
# Use composer self-update --rollback to return to version <current version>

cd /var/www/$site

# 列出已下载的模块。
composer show | grep drupal

# 下载 drupal/pathauto,会自动下载相关模块。
composer require drupal/pathauto

# 指定版本下载
composer require drupal/pathauto:^1.8 (2)

# 移除模块 (Drupal 要先卸载,否则会造成 Drupal 当掉)
drush pmu pathauto
composer remove drupal/pathauto
1 运行 Composer 若出现 Killed 表示内存不足,Composer 运行时需要大量的内存。
2 实际文件名为 pathauto-8.x-1.8.tar.gz,8.x 表示 Drupal 8,这可忽略,1.8 即为版号。
:^1.8 下载 1.8 版本,:^1 下载 1.x 最新版,可能会比 1.8 还新。

Drupal Console

Composer 安装 console,安装的路径是站台目录,安装后会在 vendor/bin 创建一个 drupal 的链接档,为了方便运行, 可将 PATH 纳入该路径 vendor/bin (采用相对路径)。

安装 Drupal Console 常常出状况,在安装任何模块之前,先安装 Drupal Console,甚至在没有建置站台之前安装。
使用 Composer 在每个站台目录中安装 Drupal Console
# 将目录切换至 Drupal 站台目录
cd /var/www/$site

# Install Drupal Console Using Composer
composer require drupal/console --prefer-dist --optimize-autoloader

vendor/bin/drupal --version
# Drupal Console version 1.9.5
# [ERROR] The specified database connection is not defined: default (1)
1 因为还没有建置站台。

Drush 安装

Composer 安装 Drush,安装的路径是站台目录。安装后会在 vendor/bin 创建一个 Drush 的链接档, 为了方便运行,可将 PATH 纳入该路径 vendor/bin,采用相对路径如 export PATH="vendor/bin:…​"

安装 Drush
# php -v
# PHP 7.3.x (1)
cd /var/www/$site
composer require drush/drush (2)
1 确定 PHP CLI 的版本为 7.3,运行 sudo update-alternatives --config php 切换。
2 不指定版本表示会安装最新版本,可指定版本如下
composer require drush/drush:10.x
composer require drush/drush:9.x
composer require drush/drush:8.x

Drupal 8 应采用 drush 版本 10,如果是 drush 8.x,drush 的命令会缺少。如果出问题再指定版本安装即可。
在安装的过程中若出现黄底的警告,如 Failed to download symfony/polyfill-ctype from dist: The zip extension and unzip command are both missing, skipping. 别怕!已说明缺少 zip unzip,就按指示安装套件 (apt install)。

Drush 7 安装

安装 Drush 7
site=drupal7
cd /var/www/$site
composer require drush/drush:7.x

# 运行 drush, 会出现下列消息
# count(): Parameter must be an array or an object that implements Countable Table.php:789
# 安装 新版的 console_table
# 实际的 drush 7 目录是在 $site/vendor/drush/drush
cd /var//www/$site/vendor/drush/drush
composer require pear/console_table

cd /var/www/$site
drush

Drupal 更新

更新前应看一下 <site>/admin/reports/updates 中的 Release notes 或者是 Update Drupal core via Composer , 不过如果是测试站台或者是 VM 可以 snapshot,那么出错再找文档吧。

事先得知 composer 会更新什么
cd /var/www/$site
composer update --dry-run
更新 Drupal
cd /var/www/$site
chwww .

# composer 自我更新 (别在更新 Drupal 时运行)
# composer self-update (1)
# Use composer self-update --rollback to return to version <current version>

# 依据依赖项目更新内核及模块
composer update --with-dependencies

# 运行数据库更新
# 别一起贴,可能询问,另外也不要加入 -y,应看一下提示或错误!
drush updb

drush cr
chwww .
1 如果更新成 Composer version 2.x 若无法继续运行,参阅 Composer 安装指定版本。

Drupal 8 配置

安装后,Drupal 相关设置在 $site/sites/default/settings.php,进入网页,如果网域不符则会出现 The provided host name is not valid for this server.

Trusted Host
$settings['trusted_host_patterns'] = [
  '^yoursite\.com$',
  '^.+\.yoursite\.com$',
];
logo.svg 及 favicon.ico

logo.svg 放在主题根目录,favicon.ico 放在网站根目录 (/var/www/$site),sitemap.xml 是读取网站根目录的 favicon.ico。

如何检查网页是否支持 gzip

采用 Firefox 或 Chrom 按下 Ctrl+Shift+I, 打开「开发人员工具」,点击 网络(Network),然后刷新页面,将列出该页面的所有响应标题。在列表中找到 Content-Encoding: gzip,则表示该页面进行 gzip 压缩。

Firefox 检查支持 gzip 图例
Screenshot of the Firefox inspector

Drupal 激活调试

采用 drupal 切换
cp sites/default/default.services.yml sites/default/services.yml (1)
drupal site:mode dev (2)
drupal site:mode prod (3)
1 第一次运行时,services.yml 不存在;将 default.services.yml 拷贝到 services.yml。
2 Drupal 激活调试模式。
3 Drupal 回复成一般模式。

会激活 Twig 调试的站台表示为测试站台,在切换是可能出现下列错误:
[ERROR] Error copying file : $site/sites/default/services.yml
可参考后文的「权限强化」来解决。

激活调试模式
  • 在网页中显示 FILE NAME SUGGESTIONS。

  • 网页出错时除了显示「网站遇到非预期错误。请稍后再试」之外,也会显示 PHP 的错误消息。

权限强化

Druapl 在进入管理页面 <site>/admin/config 时,会将下列文件改变权限为 555。
stat -c "%a %n" $(find -type d -not -perm 775 -o -type f -not -perm 775)
555 ./sites/default
555 ./sites/default/services.yml
555 ./sites/default/settings.php
可在 $sites/default/settings.php 中加入下列,取消权限强化。
$settings['skip_permissions_hardening'] = TRUE;
<site>/admin/structure/menu/item/1/edit
  • Show as expanded 在菜单项目中激活展开

还有一个重点在 Block layout  Main navigation 项目中配置显示阶层,每个主题都要配置。

<site>/admin/structure/block/manage/bootstrap_custom_main_menu (改为 主题名称_main_menu)
Configure block
MENU LEVELS

Initial visibility level
1
Number of levels to display
1 修改为 Unlimited

搜索字符由 3 个字改为 2 个字

<site>/admin/config/search/pages
Search pages
DEFAULT INDEXING SETTINGS

Minimum word length to index
3 修改为 2

Drupal 8 多国语言

开始安装站台时只安装英文,而且站台的缺省语言及管理者语言必须为英文,在运作期间不可更改。

English (original) 变成 English (英文) (original) 可能是更新或其他不明原因。 Configuration language being overwritten during module install 提到可能缺省语言是非英文造成的, 实测的情况除了站台缺省语言外也跟管理者语言有关,管理者在非英文的情况下安装模块或主题

安装语言模块
<site>/admin/modules

安装 Content Translation 及 Configuration Translation (自动安装 language/Interface Translation)。

增加语言
<site>/admin/config/regional/language
Languages

+Add language 安装语言 Chinese, TraditionalChinese, Simplified

站台必须缺省为英文。
注:在安装 Language 时由网络重新下载各式 .po 翻译档保存在 /var/www/$site/sites/default/files/translations

语言侦测及选择

<site>/admin/config/regional/language/detection
Detection and selection
Interface text language detection
Content language detection
  • Customize Content language detection to differ from Interface text language detection settings

修正维护 Translate (翻译) 时,只显示原始语言,无法输入翻译。
暂时激活 Customize Content language detection。
<site>/admin/config/regional/language/detection
Detection and selection
Content language detection
  • Customize Content language detection to differ from Interface text language detection settings

    DETECTION METHOD
    • Content language

    • URL (激活 URL 内容侦测)

    • Sessoin

    • User

    • Browser

    • Interface

    • Selected language

Save settings

需要 Content language detection 中的 URL 侦测功能才能输入翻译,按下 Save settings 让该功能处于激活状态。之后取消 Customize Content language detection 再次按下 Save settings,不需要 Content language detection 的整个功能。

为什么会有 Language switcher (Interface text)、Language switcher (Content)?

那是因为 Detection and selection 中激活了 Content language detection, 未激活时只有 Language switcher 即为 Language switcher (Interface text)。 当激活 Content language detection 应以 Language switcher (Content) 做为选择器。

那 Language switcher (User interface text) 跟 Language switcher (Content) 有何不同?

Language switcher (User interface text) VS Language switcher (Content)
上面提到的两种分别涉及接口语言和内容语言,有关更多深入的解释,请查看 Language Negotiation API

用户页面显示英文

除了激活前面的 User 之外,需配置帐户的语言。

<site>/user/1/edit

LANGUAGE SETTINGS

Site language

English

URL 语言检测设置

Drupal 侦测语言的方式有多种,采用 URL language detection configuration 是比较合适的选项, 将 English prefix 改为 en,Chinese, Traditional 则没有 prefix,可避免站台 URL 需附加 zh-hant。

<site>/admin/config/regional/language/detection/url
URL language detection configuration

PATH PREFIX CONFIGURATION

English (en) path prefix (Default language)

http://site/ en

Chinese, Traditional (zh-hant) path prefix

http://site/

Chinese, Simplified (zh-hans) path prefix

http://site/ zh-hans

Selected language 所选语言配置

设置为中文这是重点,就算是站台缺省语这为英文,在 URL 中没有前缀语言路径时就是中文。

<site>/admin/config/regional/language/detection/selected
Selected language configuration
Language

Chinese, Traditional

让 Browser 运作正确

激活浏览器语言检测,在 Interface text language detection 激活 (勾选) Browser (Content language detection 中的 Browser 不需激活)。 另外在 URL 检测 中的每一个语言都要有 path prefix,把 Chinese, Traditional 设置为 zh-hant, 如果其中有一个语言的没有 path prefix,按 URL 顺序 会将没有 path prefix 的网址内定为 URL 检测 的结果,那么 Browser 检测已无作用。激活 Browser 检测,站台 URL 必需附加 zh-hant
不过!当激活 Browser 检测后,菜单 (menu) 中的 URL 并没有前缀语言路径,就算网址为 <site>/zh-hans 菜单语言路径还是空的, 在简体中文页面,去点击菜单又回到了正体中文,Drupal 处理方式并不正确。
安装 Translatable menu link uri 来解决该问题。 安装 (modi translatable_menu_link_uri) 后在 Content language 中有 Link override (已启动)。

<site>/admin/config/regional/content-language
Content language
Custom menu link
  • Link override

在菜单项目的维护页面中会多出了 Link override

site>/admin/structure/menu/item/1/edit
Link (all languages)

/blog

Link override

/blog 该字段就拷贝原来 (上面) 的 Link 即可。

注: 在上述中只要改变了语言设置,每次都要运行 dursh cr 才不会误判。

Disable language

可将网页去掉特定语言如 English。

<site>/admin/config/regional/language

English 按下 Edit 后,勾选

  • Disable language

安装
modi disable_language
Language Switcher Extended

隐藏当前语言、若目前网页没有翻译则隐藏语言切换器项目。

<site>/admin/config/regional/language/language-switcher-extended
  • Alter the language switcher for untranslated content entities

    Untranslated Handler

    Hide the language switcher link

    Current language mode

    Hide the language switcher link

安装
modi language_switcher_extended

翻译问题

<site>/sites/default/files/translations/drupal-8.x.x.zh-hant.po 有错误
msgid "1 comment"
msgid_plural "@count comments"
msgstr[0] "1 篇回应" (1)
msgstr[1] "@count 篇回应"
msgid "1 new comment"
msgid_plural "@count new comments"
msgstr[0] "1 则新回应"
msgstr[1] "@count 则新回应"
1 msgstr[0] "1 篇回应" 实际上应为 "0 篇回应"。
但这并不能怪翻译,在 <site>/admin/config/regional/translate 中 Filter 出 comment 可以发现
Singular form
1 comment (1)

Plural form
@count comments
1 Drupal 已错误,实际应为 0 comment,不过它是 msgid 所以 …​ 要不 Druapl 大可把它去掉即可,0 篇回应 也不需要显示。

虽然 Configuration export / import 可导出、导入翻译,不过某些翻译却是采用文本对应的方式,只能由 User interface translation 修改,若找出的内容有多笔,按下 Save translations 事实上是多笔异动,当异动了不可修改的项目则会出错。
Include customized translations 只会导出自订的翻译内容,但也会导出部份的 Configuration translation,导入时可能出错,这时只好自行处理。

zh-hant-cust-fixed.po
msgid "1 comment"
msgid_plural "@count comments"
msgstr[0] " "
msgstr[1] "@count 篇回应"

msgid "1 new comment"
msgid_plural "@count new comments"
msgstr[0] " "
msgstr[1] "@count 则新回应"

msgid "Contact"
msgstr "联系"

导入上述文件时,将 Overwrite non-customized translations 、 Overwrite existing customized translations 或者 Treat imported strings as custom translations 打勾才会覆盖现有翻译,更新 Drupal 可能需再做一次。

只能导入整理过的文件,否则可能会造成语言错乱。

采用管理接口操作,实在不方便,常常忘记要勾选那些选项,而且当正体中文跟简体中文一起处理时容易出错,采用 Drush Language Commands 以 CLI 来导入导出。

安装 drush_language
modi drush_language
导出导入示例
# 导出 (1)
drush langexp --statuses=customized --langcodes=zh-hant --file=/var/www/files/config/translate/zh-hant.po

# 导入整理的文件
drush langimp --langcode=zh-hant /var/www/files/config/translate/zh-hant-cust-fixed.po
1 --statuses 的默认值为 customized,同时一并导出其他类型时;虽然 drush langexp 的 --statuses 参数说明中提到可以采用以逗号分隔列表,但测试时会错误,可改用多个 --statuses 参数,如 --statuses=customized --statuses=not-customized 来解决。
导入时出现下列消息
[warning] trim() expects parameter 1 to be string, array given PoStreamReader.php:223 (1)
1 trim 预期参数 1 为字符串,但给予数组,不过这只是警告。在导入档的 msgid 有多行的情况下,测试结果合乎预期,并没有问题。

Drupal 8 模块

为什么要采用 composer 来下载或移除模块?

因为会一起下载相依模块,另外移除时也会一并删除相关模块,强列建议采用 composer 来维护模块文件。

drush 模块安装及卸载

drush 安装是指 Druapl 是否使用该模块,卸载后该模块的组态则被删除 (模块创建某些字段或数据会消失,重新安装模块需再次输入), 但是模块文件还是存在,因为尚未以 composer 移除。
drush 采用 uninstall (pmu) 来命名卸载,不过却采用 enable (en) 来命名安装, 在网页中倒是很明确是 Install、Uninstall。看到 enable (en) 要想成 install。

应先在测试站台安装模块,一开始就测试卸载,有些模块卸载会出错,测试无误后才在实际站台安装。
模块安装及移除
# site=drupal
site=try1
extension=pathauto

cd /var/www/$site
composer require drupal/$extension
# Install
drush en $extension -y
chwww $site

# Uninstall
drush pmu $extension -y (1)

# Remove
composer remove drupal/$extension (2)
1 别忘了要测试卸载不会引发错误,如果出错,表示这个模块并没有正确移除 Drupal 组态。
2 移除模块前,记得 Drupal 要先卸载,否则会造成 Drupal 当掉。
以 Drush 安装模块,要注意文件权限问题。
cd /var/www/$site
# 安装模块 Language / Configuration Translation / Content Translation / Interface Translation
drush en language, config_translation, content_translation, locale -y

find . ! -user www-data -ls
# ubuntu ubuntu $site/sites/default/files/translations
chwww $site (1)
1 采用 drush 安装模块会创建相关路径及文件而拥有者为 ubuntu。 由 drush 安装模块后,记得!每次都要以 chwww $site 重设拥有者为 www-data,最好!composer 下载模块后也重设拥有者。

若需要更多模块数据参阅:Drupal 模块介绍

模块维护脚本

模块维护指令范例
# 安装模块
modi 模块

# 安装模块时一并测试卸载
modi 模块 --test

# 模块卸载
modu 模块
modi 安装模块
# 如果要指定 composer 的自订版本, 指定本参数
# CustomVersion=8

bind "set disable-completion on"

bash -c "cat > /var/www/bin/modi$CustomVersion" << EOF
#!/bin/bash

tab='	'
nl='
'
IFS=" \$tab\$nl"

usage="Usage: \${0##*/} [OPTION] MODULE[:^VERSION]

Require module and install.

options:
  -t, --test		Test uninstall
  -c, --cr   		Clear cache"

Uninstall=0
clearCache=0
while [ "\$#" -gt 0 ]; do
  case "\$1" in
    -t|--test) Uninstall=1; shift;;
    -c|--cr) clearCache=1; shift;;
    -h|--h*) echo "\$usage"; exit 1;;
    -*|--*) echo "unknown option: \$1" >&2; exit 1;;
    *)
      if [[ -z "\$Mod" ]]; then
        Mod=\$1;
      else
        echo "Too many modules!" >&2;
        exit 1;
      fi
      shift;;
  esac
done

if [[ -z "\$Mod" ]]; then
  echo "\$usage"
  exit 1
fi

if [ "\${PWD%/*}" != "/var/www" ]; then
  echo 'Not site directory!' >&2
  exit 1
fi

echo composer require drupal/\$Mod
set -e
composer$CustomVersion require drupal/\$Mod
echo drush en \${Mod%%:*} -y
drush en \${Mod%%:*} -y

if [ \$Uninstall -eq 1 ]; then
  echo drush pmu \${Mod%%:*} -y
  drush pmu \${Mod%%:*} -y
  echo drush en \${Mod%%:*} -y
  drush en \${Mod%%:*} -y
fi

if [ \$clearCache -eq 1 ]; then
  echo drush cr
  drush cr
fi

if [ "\$USER" != "www-data" ]; then
  echo sudo sh -c "chown -R www-data:www-data \$PWD; chmod -Rf 775 \$PWD"
  sudo sh -c "chown -R www-data:www-data \$PWD; chmod -Rf 775 \$PWD"
fi
EOF

bind "set disable-completion off"
sudo chmod +x /var/www/bin/modi$CustomVersion
modu 解除模块及移除
# 如果要指定 composer 的自订版本, 指定本参数
# CustomVersion=8

bash -c "cat > /var/www/bin/modu$CustomVersion" << EOF
#!/bin/bash -e

nl='
'
IFS=" \$nl"

usage="Usage: \${0##*/} MODULE [OPTIONS]

Uninstall the module and remove.

OPTIONS:
  -r, --remove	Remove MODULE
  -c, --cr   		Clear cache"

RemoveModule=0
clearCache=0

while [ "\$#" -gt 0 ]; do
  case "\$1" in
    -h|--h*) echo "\$usage"; exit;;
    -r|--r*) RemoveModule=1; shift;;
    -c|--cr) clearCache=1; shift;;
    -*|--*) echo "unknown option: \$1" >&2; exit 1;;
    *)
      if [[ -z "\$Mod" ]]; then
        Mod=\$1;
      else
        echo "Too many modules!" >&2;
        exit 1;
      fi
      shift 1;;
  esac
done

if [ -z "\$Mod" ]; then
  echo "\$usage"
  exit 1
fi

if [ "\${PWD%/*}" != "/var/www" ]; then
  echo 'Not site directory!' >&2
  exit 1
fi

echo drush pmu \$Mod -y
drush pmu \$Mod -y
if [ \$RemoveModule -eq 1 ]; then
  echo composer$CustomVersion remove drupal/\$Mod
  composer$CustomVersion remove drupal/\$Mod
fi

if [ \$clearCache -eq 1 ]; then
  echo drush cr (1)
  drush cr
fi
EOF

sudo chmod +x /var/www/bin/modu$CustomVersion
1 composer 移除模块后 drush pm-list 该模块还是存在列表之中,若需要下达参数 -c

Drupal Modules 目录结构

$site
└── modules
    ├── contrib (1)
    │   ├── config_filter
    │   ├── config_split
    │   └─ ...
    ├── custom (2)
    │   ├── myfeatures
    │   └─ ...
    ├── migrate_d7alias (2)
    └─ ...
1 官方模块安装目录
2 自订模块安装目录
手动安装及移除 admin_toolbar
cd /var/www/$site
tar -xzf /var/www/files/d8mod/admin_toolbar-8.x-2.4.tar.gz --directory=modules/contrib (1)
drush en admin_toolbar (2)
drush pmu admin_toolbar
rm -r /var/www/$site/modules/contrib/admin_toolbar
1 假设 Admin Toolbar 已经下载至 /var/www/files/d8mod,tar 解压至 modules/contrib。
2 如果安装时出现下列消息,表示没有下载相关模块,无法安装。
Unable to install modules: module <Module Machine name> is missing its dependency module config_update.