标签归档:Laravel

Yaf集成Eloquent——使用事务以及DB Facade

TL;DR

集成方法参见 Yaf集成Eloquent

集成基类的多个 Model 如果要正确的运行事务,需要保证各个 Model 的实例使用的是同一个数据库连接,在代码上可以通过共用同一个 Illuminate\Database\Capsule\Manager 对象实现。

使用 DB Facade 需要为 Facade 提供已经关联了 db 作为键,以 Illuminate\Database\Capsule\Manager 的实例为值的容器。

继续阅读

编写 October CMS Form Widget

 

概述

近期接触 Laravel 这一框架之后,对使用便捷性和功能的丰富感到十分满意,同时开发者与相关的社区都相当活跃,这样的框架算是相当之理想的了。

了解了框架的使用之后,自然是希望能够找到这一框架构建的应用进行进一步的学习。CMS作为常见的系统,模式上个人理解起来比较容易,同时涉及面也比较多,同时还有一定的实用性,学习起来有价值。

使用 Laravel 的 CMS 不少,有本文的主角October CMSAsgard CMSLavalite,但是后续的这些,无论从 GitHub star数目上,还是更新频率上,以及社区活跃度上,完全无法与 October CMS 相提并论。

于是决定简单了解一下October CMS(以下将会用October表示,二者不做区分)。希望通过开发一个表单部件的方式,开始二次开发的学习。

本文写作的前提是:

  • 使用过基本的OctoberCMS的Ajax框架
  • 基本了解后端管理界面的组织方式
  • 了解基本的jQuery/CSS知识
  • 了解基本的Laravel使用

需求

October宣传自身是一个简单、现代、以人为本、通用的、可拓展的、有趣的、可靠地、易学、节省时间的CMS。

对于OctoberCMS,对于一对多的关系,可以在model层进行处理。

然而,处于对体验优化的考虑,简单的关联记录的效果并不能满足。譬如需要完成一个相关文章的编辑表单,如果能够以card的形式展现相关文章的头图标题摘要等内容,那么会更加便于后台人员的操作,提供更好的体验。

同时,可以通过这一个简单的表单插件,熟悉October CMS表单插件的二次开发。

总而言之,需求如下:

  • 开发一个相关记录的表单插件
  • 表单插件可以显示相关记录的头图标题摘要
  • 相关记录可以调整顺序

OctoberCMS 表单部件

OctoberCMS的有一类组件,被称为Form组件,为后台操作数据提供了极大的方便,通过配置各种Form插件的组合,可以对数据进行操作。

常规的管理界面的开发,一种模式是通过编写接口,提供修改对应数据的功能,并且前端开发需要构建对应的操作界面。对于CMS系统,这样无疑是一个低效的行为,使得管理平台开发也成为了开发工作的一大负担,提供更为简便的管理平台开发方式,对于减少开发工作量有很大意义。

OctoberCMS的表单部件通过yaml配置文件的形式,将数据库字段与前端编辑表单部件关联起来,为快速构建针对于数据的管理界面提供了可能。

针对于基本的字符串,时间选择器,富文本编辑器,单选/复选框,OctoberCMS也都默认提供了。

组件设计

对于表单部件,功能上可以一言概之,即通过图形方式构建JSON格式的字符串,并写入数据库。

设计细化

细化需求来说,关键点在于表单,数据格式,图形界面。

对于表单,最简单的情况即通过一个input标签,在进行form提交时,带上需要提交的数据。

对于数据格式,我们需要记录的是相关记录的数据库中的自增ID,存储格式会整编为JSON格式。

对于图形界面,考虑到操作的便捷性,同时考虑到显示足够的有效信息,通过显示blog的头图、标题、摘要等信息的card的形式,表现关联记录。

进一步细化[表单]

对于表单来说,只需要确定表单中的name属性即可。

新增的情况,无需填充记录的默认值,而在更新的情况,则需要进行填充,相关PHP代码的说明会在后续提及。

进一步细化[数据格式]

选用JSON作为数据格式,记录各个关联记录的自增ID。

进一步细化[图形界面]

同时显示头图,标题,摘要,通过card形式展现。

操作上,需要有增加删除调整顺序三种。

  • 增加操作可以通过弹出记录列表的形式,选取后展现。
  • 删除则直接通过点击card上的删除按钮/文字即可。
  • 调整顺序通过前移/后移按钮完成。

组件目录结构

OctoberCMS的表单插件需要符合一定的目录结构规则。

可以通过直接创建对应的目录以及文件,也可以通过内置的工具进行初始化:

rainlab.blog 是将要创建这一组件的插件的名称,这里可以换成自己插件的名字。关于插件,参见OctoberCMS的手册

自动建立的目录结构如下:

文件不多,简而言之,RelatedRecords.php用来描述表单部件以及编写处理逻辑,relatedrecords.css自然是控制表单后台操作样式,relatedrecords.js则是实现表单项目在后台的前端操作逻辑,最后partials中的_relatedrecords.htm则定义了表单部件在后台的html展示部分。

如果不想通过内置工具生成表单部件,同样也可以直接在对应plugin的目录中中的widgets子目录中直接新增插件的方式完成,仿照October默认的modules/backend中表单插件的结构即可:

本文的demo即是通过这种方式生成的,结构如下:

可以看到,二者并无太大差别,都需要有css/js/partial以及主要的逻辑所在的.php文件,后续以demo中的文件组织结构进行描述。

组件实现细节简述

主要逻辑文件RelatedRecords.php

这一文件要直接放置于widgets的目录之下。

需要继承Backend\Classes\FormWidgetBase这一基类,同时我们需要实现一些关键的方法,以便完成逻辑以及正确显示组件。

下面,将会说明几个关键的方法。

init()

init()方法顾名思义,即初始化表单部件,一些组件自身需要进行的变量定义,参数定义等操作可以在这里编写。

在使用过程中,每个表单部件都或多或少有一些自定义的参数,譬如富文本编辑器的大小等,这些参数通过yaml文件配置,但是如何才能在表单部件中的读取到呢?

可以在init()中调用fillFromConfig()这一成员方法,通过数组的形式,将参数名传入,之后将会出现同名的成员变量,其值就是传入的参数名称。如果没有设定,那么也可以指定默认值。

为了完成需求,我们需要允许配置:

  • titleField card的标题域数据库字段名
  • imageField card的图片域数据库字段名
  • contentField card的正文域数据库字段名
  • modelClass 需要操作的Model名称
  • whereClause 查询数据时的WHERE子句内容
  • recordsPerPage 弹出列表页每页显示个数

在实际使用中,在models/yourmodel/下的fields.yaml文件中指定使用这一表单部件时,可以通过指定这些参数的形式,影响展现以及效果,形如:

render()

render()方法,即完成组件的渲染,如果已经设定好了模板中需要的值,那么只需要通过makePartial这一个成员方法即可对当前组件渲染完成。

实现以上两个方法之后,几乎这一组件就能基本上完成数据获取并展现的功能了。其他方法,也可以按照默认生成的文件的模式进行组织。

模板文件_relatedrecords.htm

模板文件作为一个partial,文件名需要以下划线开头,放置在组件的partials目录下。

由于实际要修改的数值是一个JSON格式的数组,提交时,实际上是作为表单的一对键值。为了完成表单提交,需要设定input标签的name属性。

那么问题来了,如何才能设定正确的name属性呢?

OctoberCMS框架在实现表单部件时,会根据表单部件所对应的Model和列的名称,生成key的名字,即input标签的name属性,可以通过成员变量formField的方法getName()获取。

在主逻辑文件RelatedRecords.phprender()(或者其他被这一方法调用的方法之中),为name属性赋值:

在partial中进行相应变量赋值代码编写即可。

而展现上,使用了部分materialize的样式,实现了图文card的显示效果。

弹出列表模板文件_list_related_records_sample.htm

图文card的底部,有添加记录的按钮,但是如何才能最便捷的展现出可以加入的记录呢?

这里可以借用OctoberCMS内置的一个特性:Remote popups

实现简要说明

想要通过列表展示数据对于OctoberCMS来说简直是轻而易举。从操作步骤上来看,可以描述如下:

  • 点击添加
  • 触发Ajax请求,请求对应Controller上的方法
  • 对应方法获取指定数据,渲染partial返回

Ajax请求如何能够返回并显示html呢?作为OctoberCMS的一个重要特性,简要来说即通过特定的请求方法发出请求,指定操作的handler。这里可以通过js完成。

参见下的assets/js/relatedrecords.js文件:

通过popup方法,指定了handler为onLoadRelatedRecords方法。

handler方法归属的Controller,即当前编辑对象所对应的

Controller,所以,需要在Controller中实现对应的同名方法。demo中编辑的是Sample这一个对象,那么方法实现起来将会类似:

考虑到不能重复加入关联记录,所以每次请求要通过excludeIds传入已加入的id,进行排除。

通过popup方式弹出列表之后,选择加入这些操作就相当容易实现了。

其他如前端的操作、样式的编写等等不在赘述。

注册表单部件

完成上述工作之后,还需要关键的一步,即在Plugin.php中的registerFormWidgets()方法注册编写完成的组件。

组件效果

通过弹出的Modal窗口添加关联:

select related records

选择后可供调整顺序或移除:

selected