作者:老葛 亚艾元软件
初级阶段:
1,会覆写模板的预处理函数
2,会自定义模块,定义菜单+回调 controller
3, 能够通过代码定义区块
4,定义表单区块,或者表单页面
5,能够操作数据库,
另外就是:加强主题模板复写的学习:
1,能够复写node 的模板
2,复写views的模板文件
作者:老葛 亚艾元软件
我在Drupal8的项目中,写了这样一段代码:
function mycustom_load_term_helper($name, $vocabulary){
$terms = taxonomy_term_load_multiple_by_name($name, $vocabulary);
$term = reset($terms);
if(!empty($term)){
//return $term;
}else{
$term = Term::create([
'name' => $name,
'vid' => $vocabulary,
]) ->save();
}
return $term;
}
在其他地方,调用了这里的代码:
//根据赛事文本,自动设置 赛事分类字段
if(!empty($entity->event->value) && empty($entity->field_event->target_id)){
$term = mycustom_load_term_helper($entity->event->value, 'event');
//drupal_set_message($entity->event->value);
if(!empty($term) ){
//\Drupal::logger('my_module')->notice(var_export($term, true));
$entity->field_event->target_id = $term->id();
}
}
大部分情况下,代码都是正确的,但是偶尔会报错。大致的错误信息,就是对于整数类型的数据调用了->id()函数。
这个错误信息偶尔能会出现,一直没有解决,因为很快下面的就正常了,我只需要再运行一下。
我今天仔细分析了这段代码。发现了这样的问题:
Term的save方法是继承自Entity的,在对应的说明里面。
Return value
int Either SAVED_NEW or SAVED_UPDATED, depending on the operation performed.
Entity::save返回的是整数。SAVED_NEW 和SAVED_UPDATED都是定义好的常量整数。
这下问题解决了,这是我改进的代码:
function mycustom_load_term_helper($name, $vocabulary){
$terms = taxonomy_term_load_multiple_by_name($name, $vocabulary);
$term = reset($terms);
if(!empty($term)){
//return $term;
}else{
$term = Term::create([
'name' => $name,
'vid' => $vocabulary,
]);
$term->save();
}
return $term;
}
使用Term::create创建一个$term,对它调用save方法,这时返回的term就是一个对象了。
为了让代码更多健壮一点,其实在调用的时候,可以这么改进:
if(!empty($entity->event->value) && empty($entity->field_event->target_id)){
$term = mycustom_load_term_helper($entity->event->value, 'event');
//if(!empty($term) ){
if ($term instanceof \Drupal\Core\Entity\ContentEntityInterface) {
$entity->field_event->target_id = $term->id();
}
}
这里使用instanceof判断一下,成立的时候调用->id()就不会出错了。
当我们使用Drupal构建一个大型项目的时候,我们常常会和各种业务系统打交道,而有的业务系统数据库用的是oracle,我们需要建立与oracle的连接,从里面查询我们需要的数据。
我们假定你已经配置好了,oracle的相关库。
windows下面参考:
Drupal 与Oracle集成时,oracle相关配置文档, http://www.thinkindrupal.com/node/6009
linux下面也需要安装oracle的客户端,然后安装PHP的oracle扩展,这个过程有点费事,网上有很多教程。
我们假定你已经完成了这些配置。我们封装的连接oracle的函数我们封装的连接oracle的函数,
/** * 从 Oracle 获取数据. * * @param string $sql * SQL 链接字符串. * @param array $column_names * 返回的数据列名. 依据列名返回数据. * @return array * 数据. */ function myoracle_retrieve_data($sql, array $column_names = array()) { $data = array(); $conn = oci_connect('username', 'password', 'dbname'); if (!$conn) { $e = oci_error(); \Drupal::logger('myoracle')->error("数据库连接时出错: " .var_export($e,true)); return $data; } \Drupal::logger('myoracle')->notice("查询SQL: " .var_export($sql,true)); // 编译sql语句. $ora = oci_parse($conn, $sql); oci_execute($ora, OCI_DEFAULT); while ($row = oci_fetch_array($ora)) { $tmp = array(); foreach ($column_names as $name) { $tmp[$name] = $row[$name]; } $data[] = $tmp; } return $data; }
在这个函数里面,设置用oracle的用户名,密码,数据库名,就可以连接oracle,给出一个oracle的sql语句,就能够查找到一个结果数组,剩下的就交给你自己处理了。
我们是直接连的,Drupal官方有oracle的数据库驱动,https://www.drupal.org/project/oracle ,它允许你将整个Drupal跑在oracle上,这个用的人很少,至少理论上是可行的。
1, 先用一段代码测试一下:
$conn = oci_connect('username', 'password', 'dbname');
if($conn) {
//echo"连接oracle成功!";
drupal_set_message('连接oracle成功!');
}else{
// echo"连接oracle失败!";exit;
drupal_set_message('连接oracle失败!');
}
报错:
The website encountered an unexpected error. Please try again later.
Error: Call to undefined function Drupal\mycustom\Controller\oci_connect() in Drupal\mycustom\Controller\MycustomController->testPage() (line 30 of modules/custom/mycustom/src/Controller/MycustomController.php).
参考文档:
https://www.cnblogs.com/xuzhengzong/p/9104700.html
第一步:
分别下载 oracle-instantclient11.2-basic-11.2.0.4.0-1.x86_64.rpm 和 oracle-instantclient11.2-devel-11.2.0.4.0-1.x86_64.rpm
放在/usr/packages/目录下,执行:
# cd /usr/packages/
# rpm -ivh oracle-instantclient*
此时会生成/usr/lib/oracle/11.2/client64/lib/目录
第2步:
二、修改/etc/ld.so.conf配置文件
追加以下内容 -- 上面生成文件的路径,没有64的写client/lib/:
/usr/lib/oracle/11.2/client64/lib/
保存、退出,执行命令 # ldconfig
第3步:
三、安装oci8
下载地址:http://pecl.php.net/package/oci8
下载 oci-2.0.8.tgz
放在/usr/packages/目录下,依次执行:
tar -xvzf oci-2.0.8.tgz
Can't find PHP headers in /usr/include/php
The php-devel package is required for use of this command.
安装php-dev以及依赖Perl(tap::parser)
对应于:
rpm -ivh perl-Test-Harness-3.28-3.el7.noarch.rpm
编辑php.ini
extension=oci8.so
这部分内容,以亚艾元CMS发行版为基础,讲述亚艾元团队在Drupal开发过程中,使用了哪些常用模板。主要讲述:
1,核心自带模块。
2,亚艾元CMS自带模块。
3,开发过程中常见的备用模块。
4,优秀发行包里面包含的模块。
亚艾元CMS发行版,是一个基于Drupal8/9版本基础上,亚艾元自主开发的一个Drupal发行包,主要根据中国用户实际情况,满足常见中国用户需求。
特色:
1,基于频道、栏目的内容管理、权限设置,更符合中国国情。
2,更丰富的多媒体支持,图片,附件、PDF、视频、音频,满足日常需要。
3,内置10多种列表模板,普通用户只需要选择哪种模板即可改变展现形式。
4,内置ludwig贝多芬模块,支持非composer模式,复合国内内网要求。
5,精选多个常用模块,对于编辑器、图片处理,等常用功能做了加强。
6,内置专题管理,快速搭建专题站。
7,默认符合中国习惯的默认配置。
8,基于bootstrap的响应式实现,兼容手机、平板、PC。
9,除了网站,默认携带微信小程序版本,基于React, material UI的H5版本。
亚艾元模板站,基于亚艾元CMS发行包打造,是亚艾元软件,针对中国用户,面向特定行业的解决方案。亚艾元CMS发行版目前不提供免费下载。
作者:亚艾元技术部
Protected Pages
项目地址:https://www.drupal.org/project/protected_pages
Drupal8模块安装量:6168
通过这个模块,管理员可以对网站的特定页面进行保护,只有提供了正确密码才能访问内容。支持设置全局密码,支持特定页面单独设置密码。
Shield
项目地址:https://www.drupal.org/project/shield
Drupal8模块安装量:8531
使用apache的Shield功能,保护开发站点,只有输入正确的用户名密码后才能访问站点。需要修改apache的配置。
Protected node
项目地址: https://www.drupal.org/project/protected_node
Drupal8模块安装量:暂无D8版本,Drupal8版本正在计划开发中。
与Protected Pages模块类似,但是只支持对节点的密码保护,在节点的编辑页面增加了一个tab配置选项,配置起来比较简单。
作者:亚艾元技术部
我们当前使用的版本是Drupal8.8,从D8开始,自身携带了Ckeditor编辑器。默认就提供了所见即所得编辑功能。默认启用的编辑器里面按钮不够丰富,我们为其做了加强。
1, 开启media、media library模块,启用多媒体上传按钮。
2, 增加对font,color的设置,安装模块colorbutton、ckeditor_font、panelbutton,下载对应的js存放到libraries目录.如果没有下载的话,会报警告信息:
Warning: file_get_contents(/libraries/font/plugin.js): failed to open stream: No such file or directory in _locale_parse_js_file() (line 1133 of core\modules\locale\locale.module).
_locale_parse_js_file('/libraries/font/plugin.js')
调整使用的按钮。
3, 字体,支持中文:
添加以下代码到libraries\font的plugin.js文件中:
CKEDITOR.config.font_names = '宋体/SimSun;新宋体/NSimSun;仿宋_GB2312/FangSong_GB2312;楷体_GB2312/KaiTi_GB2312;黑体/SimHei;微软雅黑/Microsoft YaHei;'+ 'Arial/Arial, Helvetica, sans-serif;' +
…
这样增强以后,Ckeditor的功能就比较丰富了。
上述的两个常见查找js库的时候,路径写死了,默认不支持子目录的形式,我在本地修改了一下。
public function getLibraryPath() { $path = '/zhanhui/libraries/colorbutton'; if (\Drupal::moduleHandler()->moduleExists('libraries')) { $path = libraries_get_path('colorbutton'); } return $path; }
作者:亚艾元技术部
我们在为客户实现一个很复杂的统计功能时,用到了views field view模块,通过多层的嵌套,使用views实现了按照分类统计节点数量、浏览量,还能基于日期筛选查找。
我们在解决问题的时候,遇到了一个问题,由于views创建的页面位于admin的管理界面,我们想给views指定一个主题模板,这个时候,由于使用的是核心主题,所以不能直接将模板文件放到主题的templates目录下面。
经过检查,我们可以这样实现。
Module文件中增加了以下代码:
function mycustom_theme() { $theme['views_view__statistic_helper'] = [ 'base hook' => 'views_view', ]; return $theme; }
创建一个temlates目录,里面放上我们的模板文件:
views-view--statistic-helper.html.twig
注意下划线和连字符之间的转换。
<div{{ attributes.addClass(classes) }}> {{ title_prefix }} {{ title }} {{ title_suffix }} {% if header %} <header> {{ header }} </header> {% endif %} {{ attachment_before }} {% if rows -%} {{ rows }} {% elseif empty -%} {{ empty }} {% endif %} {{ pager }} {{ attachment_after }} {{ more }} {% if footer %} <footer> {{ footer }} </footer> {% endif %} {{ feed_icons }} </div>
模板文件中,我删除了exposed对应代码:
{{ exposed }}
这样通过views field view嵌套进去的数据就干净了很多,同时,多个views之间的同名exposed filter,是可以同时起作用的。上面的日期筛选,就作用于了分类列表的节点统计上面。