OctoberCms学习笔记中文文档翻译
发布时间:2018-08-07, 09:13:22 分类:PHP | 编辑 off 网址 | 辅助
图集1/1
正文 17920字数 1,439,091阅读
安装 install
项目源码地址
安装后删除文件 install.php
文件夹 install_files
官方文档
登录后台,可以切换到中文模式:
点击右上角的用户图标,可以选择“back-end preferences” 选择 简体中文 和 UTC+8 Asia/Shanghai
点击下方的save,F5刷新页面即可转换为中文界面
项目源码地址
/install.php
Run code
Cut to clipboard
安装后删除文件 install.php
文件夹 install_files
官方文档
登录后台
/backend
Run code
Cut to clipboard
点击右上角的用户图标,可以选择“back-end preferences” 选择 简体中文 和 UTC+8 Asia/Shanghai
点击下方的save,F5刷新页面即可转换为中文界面
基本概念
在October系统中所构建的每一个页面都是由Layout(布局)、Page(页面)、Partials(部件)和Content blocks(内容块)组成。最简单的情况就是只有一个Page也是可以的。
在October系统中所构建的每一个页面都是由Layout(布局)、Page(页面)、Partials(部件)和Content blocks(内容块)组成。最简单的情况就是只有一个Page也是可以的。
Layouts
Layout定义了一个页面的结构。布局文件layouts/default.htm定义了页面的结构,以及在每个页面上重复的部分,诸如HTML、Head和Body标签,样式表和JS文件引用。
在Demo主题中的菜单和页脚也是在布局中定义的。
Layout定义了一个页面的结构。布局文件layouts/default.htm定义了页面的结构,以及在每个页面上重复的部分,诸如HTML、Head和Body标签,样式表和JS文件引用。
在Demo主题中的菜单和页脚也是在布局中定义的。
Pages
页面保存了每一个页面的内容。
页面文件pages/home.htm 定义页面URL(/当前页面)和页面内容。 页面在布局中渲染,这个函数“page”应该在布局代码中被调用:
为页面使用布局是可选的,您可以在页面文件中定义所有的内容,而不使用布局。
页面保存了每一个页面的内容。
页面文件pages/home.htm 定义页面URL(/当前页面)和页面内容。 页面在布局中渲染,这个函数“page”应该在布局代码中被调用:
{% page %}
Run code
Cut to clipboard
为页面使用布局是可选的,您可以在页面文件中定义所有的内容,而不使用布局。
Partials
包含了可以重复使用的HTML标记块。这些标记块定义在一个一个的单独的问题件中,可以被使用在任何地方。
Partials的渲染方式为:
Partial文件可以放到Partials目录里面的任何文件夹下,比如:我们将页脚的内容放到了partials/site/footer.htm这个partial里面了。 则引用的方法就是:
Partials可以被pages、layouts或者其他的partials引用。没有限制。
包含了可以重复使用的HTML标记块。这些标记块定义在一个一个的单独的问题件中,可以被使用在任何地方。
Partials的渲染方式为:
{% partial "partial-name" %}
Run code
Cut to clipboard
Partial文件可以放到Partials目录里面的任何文件夹下,比如:我们将页脚的内容放到了partials/site/footer.htm这个partial里面了。 则引用的方法就是:
{% partial "site/footer" %}
Run code
Cut to clipboard
Partials可以被pages、layouts或者其他的partials引用。没有限制。
Content Blocks
内容块是独立于pages、layouts的文本、可编辑的html代码块。
比如content/welcome.htm文件。 渲染格式如下:
内容块是独立于pages、layouts的文本、可编辑的html代码块。
比如content/welcome.htm文件。 渲染格式如下:
{% content "content-name.htm" %}
Run code
Cut to clipboard
Placeholders
placeholders允许Pages注入内容到Layout中。
一般情况下,是把js和样式表注入到layout的head标签中。placeholder在layout中定义,页面中执行注入操作。
Layout file:
Page file:
placeholders允许Pages注入内容到Layout中。
一般情况下,是把js和样式表注入到layout的head标签中。placeholder在layout中定义,页面中执行注入操作。
Layout file:
<head>
...
{% placeholder head %}
</head>
Run code
Cut to clipboard
Page file:
{% put head %}
<link href="css/theme.css" rel="stylesheet">
<script src="js/script.js"></script>
{% endput %}
Run code
Cut to clipboard
Assets
存储的是诸如JavaScript, StyleSheet, images, fonts, 等 资源文件,当然也可以引入第三方包。
存储的是诸如JavaScript, StyleSheet, images, fonts, 等 资源文件,当然也可以引入第三方包。
主题 themes
介绍
主题定义了October构建的网站或Web应用程序的外观。主题完全基于文件定义,可以使用任何版本控制软件管理。
主题存储在项目的themes目录的对应子目录中。主要包含以下部分:
Description名称 描述
Pages 网站的页面
Partials 可以重用的HTML标记块
Layouts 定义页面的结构
Content files 可以是文本,HTML代码和Markdown 代码块,主要用于与Page和Layout进行分开编辑维护。
Asset files 资源文件包含图片、样式表和JS脚本文件。
主题的目录结构
每个主题都有一个独立的目录,只有激活的主题才会显示在网站上。基本结构的例子:
激活主题的方式有后台操作和修改配置文件两种方式,修改config/cms.php文件中的activeTheme的设置值。或者,采取后台设置,操作步骤为:设置——内容管理——前端主题——选择一个主题激活即可。
子目录
October支持单层子目录,有Pages、Partials、Layouts、Content和Assets目录。这样简化了大型网站的目录结构。
要从子目录引用Partial文件或者Content文件,格式为:{% 名称 + 路径 %},比如:
上述表示,引入一个Partial部件,部件的位置及文件为:Partials/blog/category-list.htm。注意,模板路径总是绝对的,在同一个Partial目录中,引用同目录中的另外一个Partial,也必须写完整的子目录名称。
模板结构
对于Page、Partial和Layout他们所对应的模板结构,都是包含了三个部分:Configuration,PHP Code,Twig markup。各个部分之间通过 " == " 进行分割开来。
配置部分用于设置模板参数,具体参数与不同的模板相关,因类型而不同。配置部分使用简化的" ini "格式,字符串参数值必须包含在双引号中。
在模板每次渲染之前,PHP代码部分都是先执行。PHP代码是可选的部分,可以省略。PHP代码可以使用代码开始和结束标记"<? ?>",这个标记仅仅是用于语法高亮。而且标记和==不在同一行。
在PHP部分,只能定义函数,允许使用use引入名称空间。但是除了这些不允许其他PHP代码。
访问变量可以使用$this,通过数据方式可以设置或者读取变量,使用对象方式则只能读取变量的值。
Twig是一个灵活,快速,安全的PHP模板语言。 Twig标记部分定义要由模板呈现的内容。在这个部分可以使用October提供的函数、标记或者过滤器。其内容取决于模板类型(page、layout、partial)。
主题日志记录
主题日志记录是一个非常有用的功能,默认情况下是禁用的。由于布局和页面的内容存储在文件中,可能会发生丢失内容的情况,主题日志记录可以将这些修改产生的变化都记录下来。
启用主题日志记录,可以进入设置——日志——日志设置——启用主题更改。设置完成后,保存设置,刷新页面则可以看见在日志——主题日志,点击可以查看。
介绍
主题定义了October构建的网站或Web应用程序的外观。主题完全基于文件定义,可以使用任何版本控制软件管理。
主题存储在项目的themes目录的对应子目录中。主要包含以下部分:
Description
Pages 网站的页面
Partials 可以重用的HTML标记块
Layouts 定义页面的结构
Content files 可以是文本,HTML代码和Markdown 代码块,主要用于与Page和Layout进行分开编辑维护。
Asset files 资源文件包含图片、样式表和JS脚本文件。
主题的目录结构
每个主题都有一个独立的目录,只有激活的主题才会显示在网站上。基本结构的例子:
themes/
website/ <=== 主题的目录
pages/ <=== Pages(页面目录)
home.htm
layouts/ <=== Layouts(布局目录)
default.htm
partials/ <=== Partials(部件目录)
sidebar.htm
content/ <=== Content(内容目录)
intro.htm
assets/ <=== Assets (资源目录)
css/
my-styles.css
js/
images/
Run code
Cut to clipboard
激活主题的方式有后台操作和修改配置文件两种方式,修改config/cms.php文件中的activeTheme的设置值。或者,采取后台设置,操作步骤为:设置——内容管理——前端主题——选择一个主题激活即可。
子目录
October支持单层子目录,有Pages、Partials、Layouts、Content和Assets目录。这样简化了大型网站的目录结构。
themes/
website/
pages/
home.htm
blog/ <=== Subdirectory
archive.htm
category.htm
partials/
sidebar.htm
blog/ <=== Subdirectory
category-list.htm
content/
footer-contacts.txt
home/ <=== Subdirectory
intro.htm
...
Run code
Cut to clipboard
要从子目录引用Partial文件或者Content文件,格式为:{% 名称 + 路径 %},比如:
{% partial "blog/category-list" %}
Run code
Cut to clipboard
上述表示,引入一个Partial部件,部件的位置及文件为:Partials/blog/category-list.htm。注意,模板路径总是绝对的,在同一个Partial目录中,引用同目录中的另外一个Partial,也必须写完整的子目录名称。
模板结构
对于Page、Partial和Layout他们所对应的模板结构,都是包含了三个部分:Configuration,PHP Code,Twig markup。各个部分之间通过 " == " 进行分割开来。
url = "/blog"
layout = "default"
==
function onStart()
{
$this['posts'] = ...;
}
==
<h3>Blog archive</h3>
{% for post in posts %}
<h4>{{ post.title }}</h4>
{{ post.content }}
{% endfor %}
COnfiguration Section 【配置部分】
Run code
Cut to clipboard
配置部分用于设置模板参数,具体参数与不同的模板相关,因类型而不同。配置部分使用简化的" ini "格式,字符串参数值必须包含在双引号中。
url = "/blog"
layout = "default"
[component]
parameter = "value"
PHP Code (PHP代码部分)
Run code
Cut to clipboard
在模板每次渲染之前,PHP代码部分都是先执行。PHP代码是可选的部分,可以省略。PHP代码可以使用代码开始和结束标记"<? ?>",这个标记仅仅是用于语法高亮。而且标记和==不在同一行。
url = "/blog"
layout = "default"
==
<?
function onStart()
{
$this['posts'] = ...;
}
?>
==
<h3>Blog archive</h3>
{% for post in posts %}
<h4>{{ post.title }}</h4>
{{ post.content }}
{% endfor %}
Run code
Cut to clipboard
在PHP部分,只能定义函数,允许使用use引入名称空间。但是除了这些不允许其他PHP代码。
url = "/blog"
layout = "default"
==
<?
use Acme\Blog\Classes\Post;
function onStart()
{
$this['posts'] = Post::get();
}
?>
==
Run code
Cut to clipboard
访问变量可以使用$this,通过数据方式可以设置或者读取变量,使用对象方式则只能读取变量的值。
// Write via array
$this['foo'] = 'bar';
// Read via array
echo $this['foo'];
// Read-only via object
echo $this->foo;
Twig Markup Section(Twig标记部分)
Run code
Cut to clipboard
Twig是一个灵活,快速,安全的PHP模板语言。 Twig标记部分定义要由模板呈现的内容。在这个部分可以使用October提供的函数、标记或者过滤器。其内容取决于模板类型(page、layout、partial)。
主题日志记录
主题日志记录是一个非常有用的功能,默认情况下是禁用的。由于布局和页面的内容存储在文件中,可能会发生丢失内容的情况,主题日志记录可以将这些修改产生的变化都记录下来。
启用主题日志记录,可以进入设置——日志——日志设置——启用主题更改。设置完成后,保存设置,刷新页面则可以看见在日志——主题日志,点击可以查看。
页面 Pages
Pages:页面;网站页面的内容由Page模板定义。模板文件位置:themes/theme_name/pages目录下。页面文件的扩展名为htm。文档结构中,Configuration(配置)和Twig Markup(标记)部分是必须的,PHP代码部分是可选的。
最简单的例子
页面配置
页面配置在Configuration Section中定义。主要定义一下内容:
参数 描述
URL 页面网址,必填。
title 页面标题,必填。
Layout 页面布局可选。如果指定,应包含布局文件的名称,不带扩展名,例如:default。
Description 后端接口的页面描述,可选。
URL设置语法
URL以正斜杠" / "开头,可以包含参数也可以不包含。比如:
url = "/blog"
带参数的URL以" : "开头。比如下面的url表示,/blog/post/...斜杠后面的就是参数。这个参数可以被October组件或者PHP代码部分访问。
url = "/blog/post/:post_id"
PHP代码部分访问的例子如下:参数名与php变量名要求一致。
可选参数:只需要在其后面加?即可。
url = "/blog/post/:post_id?"
URL中间的参数不能是可选的。在下一个示例中,该:post_id参数被标记为可选,但会当做必须的处理。
url = "/blog/:post_id?/comments"
可选参数运行有默认值。在没有提供参数的时候,这些默认值作为POST的值。默认值不能包含任何" 星号 管道符 问号 "
url = "/blog/category/:category_id?10"
还可以使用正则表达式验证参数。添加验证表达式需要 [ 参数名 ] 或者 [ 问号 ] 后面添加管道符号 [ | ] 。表达式中不能包含正斜杠符号 [ / ] 。
可以通过在参数后面加星号来使用特殊的通配符参数。与常规参数不同,通配符参数可以匹配一个或多个URL。URL只能包含单个通配符参数,不能使用正则表达式,或者后跟可选参数。
url = "/blog/:category*/:slug"
比如下面的例子:
/color/:color/make/:make*/edit
可以匹配:
/color/brown/make/volkswagen/beetle/retro/edit
其中:
color: 匹配了 brown
make: 匹配了 volkswagen/beetle/retro
动态页面
在模板的Twig标记部分,可以使用October提供的函数,过滤器和标签。其中的变量在页面中是必须的,这些变量在 page和layout中,由PHP代码或者组件提供变量的值。
页面执行的声明周期
onInit当所有组件被初始化并且在处理AJAX请求之前,该函数被执行。
onStart 函数在页面开始执行时执行。
onEnd函数在页面渲染之前和执行页面Components之后执行。
在onStart和onEnd函数中,您可以将变量注入到Twig环境中。使用array notation将变量传递给页面:
下面的例子说明了如何从数据库加载文章的集合,并显示在页面上。
发送自定义响应
页面执行声明周期中定义的所有函数都可以暂停执行进程,发送自定义的响应。从生命周期函数中返回响应是很简单的,下面的例子中,页面将不载入任何页面内容,只是仅仅返回一个Hello world字符串到浏览器。
Handling Forms
处理表单:可以在page或者layout中的PHP代码部分定义处理表单的函数。使用form_open()函数来定义什么函数来处理这个表单。
上述定义的来处理表单的函数为onHandleForm函数,这个函数是在PHP代码部分进行定义的:
这个函数使用POST获取表单提交的值,并把这个值给当前页面的变量 lastValue ,然后在上面的Twig代码中的最后一行中,把这个值给显示出来。
关于重名:如果在page、layout和component中定义了具有相同名称的函数,October将根据如下顺序确定优先级:Page > Layout > Component。总是前面的优先被执行。
如果引用组件中的函数,则使用组件名或者别名,后跟 [ :: ] ,再加函数名。
404 Page
当系统找不到目标页面时,系统将显示404页面内容,URL为 /404 。
Error Page
默认情况下,任何错误都会显示一个详细的错误页面,其中包含错误发生处的文件内容,行号和堆栈跟踪。
我们可以显示一个自定义的错误页面。首先在配置文件config/app.php中找到字段debug,并设置为false。然后建立一个URL为:" /error "的页面。
Page Variables
PHP/Component访问:页面的属性可以被PHP代码部分或者组件部分通过 $this->page 来进行访问。比如:
程序化方式注入资源到页面
可以使用 addCss addJs 两个方法,分别注入样式表和js脚本到页面中。只需要在页面或者布局的PHP代码部分,通过 onStart 函数进行注入操作。
关于路径,如果以 / 开头,则说明是网站的根目录,如果不是 / 开头,则是指主题目录。同时,这些路径支持数组模式,以便提供多个文件的注入。
支持SCSS和LESS:
注入的文件如何在页面或者布局中输出呢,通过 {% styles %} 和 {% scripts %}就可以了。
Pages:页面;网站页面的内容由Page模板定义。模板文件位置:themes/theme_name/pages目录下。页面文件的扩展名为htm。文档结构中,Configuration(配置)和Twig Markup(标记)部分是必须的,PHP代码部分是可选的。
最简单的例子
url = "/"
==
<h1>Hello, world!</h1>
Run code
Cut to clipboard
页面配置
页面配置在Configuration Section中定义。主要定义一下内容:
参数 描述
URL 页面网址,必填。
title 页面标题,必填。
Layout 页面布局可选。如果指定,应包含布局文件的名称,不带扩展名,例如:default。
Description 后端接口的页面描述,可选。
URL设置语法
URL以正斜杠" / "开头,可以包含参数也可以不包含。比如:
url = "/blog"
带参数的URL以" : "开头。比如下面的url表示,/blog/post/...斜杠后面的就是参数。这个参数可以被October组件或者PHP代码部分访问。
url = "/blog/post/:post_id"
PHP代码部分访问的例子如下:参数名与php变量名要求一致。
url = "/blog/post/:post_id"
==
function onStart()
{
$post_id = $this->param('post_id');
}
==
Run code
Cut to clipboard
可选参数:只需要在其后面加?即可。
url = "/blog/post/:post_id?"
URL中间的参数不能是可选的。在下一个示例中,该:post_id参数被标记为可选,但会当做必须的处理。
url = "/blog/:post_id?/comments"
可选参数运行有默认值。在没有提供参数的时候,这些默认值作为POST的值。默认值不能包含任何" 星号 管道符 问号 "
url = "/blog/category/:category_id?10"
还可以使用正则表达式验证参数。添加验证表达式需要 [ 参数名 ] 或者 [ 问号 ] 后面添加管道符号 [ | ] 。表达式中不能包含正斜杠符号 [ / ] 。
url = "/blog/:post_id|^[0-9]+$/comments" - this will match /blog/10/comments
...
url = "/blog/:post_id|^[0-9]+$" - this will match /blog/3
...
url = "/blog/:post_name?|^[a-z0-9\-]+$" - this will match /blog/my-blog-post
Run code
Cut to clipboard
可以通过在参数后面加星号来使用特殊的通配符参数。与常规参数不同,通配符参数可以匹配一个或多个URL。URL只能包含单个通配符参数,不能使用正则表达式,或者后跟可选参数。
url = "/blog/:category*/:slug"
比如下面的例子:
/color/:color/make/:make*/edit
可以匹配:
/color/brown/make/volkswagen/beetle/retro/edit
其中:
color: 匹配了 brown
make: 匹配了 volkswagen/beetle/retro
动态页面
在模板的Twig标记部分,可以使用October提供的函数,过滤器和标签。其中的变量在页面中是必须的,这些变量在 page和layout中,由PHP代码或者组件提供变量的值。
页面执行的声明周期
onInit当所有组件被初始化并且在处理AJAX请求之前,该函数被执行。
onStart 函数在页面开始执行时执行。
onEnd函数在页面渲染之前和执行页面Components之后执行。
在onStart和onEnd函数中,您可以将变量注入到Twig环境中。使用array notation将变量传递给页面:
url = "/"
==
function onStart()
{
$this['hello'] = "Hello world!";
}
==
<h3>{{ hello }}</h3>
Run code
Cut to clipboard
下面的例子说明了如何从数据库加载文章的集合,并显示在页面上。
url = "/blog"
==
use Acme\Blog\Classes\Post;
function onStart()
{
$this['posts'] = Post::orderBy('created_at', 'desc')->get();
}
==
<h2>Latest posts</h2>
<ul>
{% for post in posts %}
<h3>{{ post.title }}</h3>
{{ post.content }}
{% endfor %}
</ul>
Run code
Cut to clipboard
发送自定义响应
页面执行声明周期中定义的所有函数都可以暂停执行进程,发送自定义的响应。从生命周期函数中返回响应是很简单的,下面的例子中,页面将不载入任何页面内容,只是仅仅返回一个Hello world字符串到浏览器。
function onStart()
{
return 'Hello world!';
}
比较有用的例子是做重定向:
public function onStart()
{
return Redirect::to('http://google.com');
}
Run code
Cut to clipboard
Handling Forms
处理表单:可以在page或者layout中的PHP代码部分定义处理表单的函数。使用form_open()函数来定义什么函数来处理这个表单。
{{ form_open({ request: 'onHandleForm' }) }}
Please enter a string: <input type="text" name="value"/>
<input type="submit" value="Submit me!"/>
{{ form_close() }}
<p>Last submitted value: {{ lastValue }}</p>
Run code
Cut to clipboard
上述定义的来处理表单的函数为onHandleForm函数,这个函数是在PHP代码部分进行定义的:
function onHandleForm()
{
$this['lastValue'] = post('value');
}
Run code
Cut to clipboard
这个函数使用POST获取表单提交的值,并把这个值给当前页面的变量 lastValue ,然后在上面的Twig代码中的最后一行中,把这个值给显示出来。
关于重名:如果在page、layout和component中定义了具有相同名称的函数,October将根据如下顺序确定优先级:Page > Layout > Component。总是前面的优先被执行。
如果引用组件中的函数,则使用组件名或者别名,后跟 [ :: ] ,再加函数名。
{{ form_open({ request: 'myComponent::onHandleForm' }) }}
Run code
Cut to clipboard
404 Page
当系统找不到目标页面时,系统将显示404页面内容,URL为 /404 。
Error Page
默认情况下,任何错误都会显示一个详细的错误页面,其中包含错误发生处的文件内容,行号和堆栈跟踪。
我们可以显示一个自定义的错误页面。首先在配置文件config/app.php中找到字段debug,并设置为false。然后建立一个URL为:" /error "的页面。
Page Variables
PHP/Component访问:页面的属性可以被PHP代码部分或者组件部分通过 $this->page 来进行访问。比如:
function onEnd()
{
$this->page->title = 'A different page title';
}
Twig标记访问:这些变量也可以被Twig标记访问,方式为 this.page.variable ;
<p>The title of this page is: {{ this.page.title }}</p>
Run code
Cut to clipboard
程序化方式注入资源到页面
可以使用 addCss addJs 两个方法,分别注入样式表和js脚本到页面中。只需要在页面或者布局的PHP代码部分,通过 onStart 函数进行注入操作。
function onStart()
{
$this->addCss('assets/css/hello.css');
$this->addJs('assets/js/app.js');
}
Run code
Cut to clipboard
关于路径,如果以 / 开头,则说明是网站的根目录,如果不是 / 开头,则是指主题目录。同时,这些路径支持数组模式,以便提供多个文件的注入。
function onStart()
{
$this->addCss(['assets/css/hello.css', 'assets/css/goodbye.css']);
$this->addJs(['assets/js/app.js', 'assets/js/nav.js']);
}
Run code
Cut to clipboard
支持SCSS和LESS:
function onStart()
{
$this->addCss(['assets/less/base.less']);
}
Run code
Cut to clipboard
注入的文件如何在页面或者布局中输出呢,通过 {% styles %} 和 {% scripts %}就可以了。
部件 Partials
partials 我们这里简称【部件】,是可以重复使用的Twig标记块。可以用于网站的任何位置。比如页眉页脚或者其他Ajax内容。
partials模板文件存储在模板目录的partials子目录中。扩展名是htm。最简单的例子:
<p>This is a partial</p>
partials 的配置部分是可选的,其中可选参数description,用于给后端用户提供功能说明。
在配置部分可以定义组件,将在后续的组件部分学习。
部件的渲染
渲染部件的方式:{% partial "partial-name" %} 。这里只有一个必须的参数,就是【文件名】这里的文件名是指文件的名称部分,不包含扩展名部分。如果在子目录中,则需要写明路径。部件可以被页面、布局或者其他部件使用。
下面就是一个部件引用了另一个部件。
将变量传递给部件
部件的一个强大的功能是,我们可以给部件传递变量参数。比如我们拥有一个渲染博客列表的部件,我们可以将帖子的集合传递给中国博客列表部件。这时候这个部件就可以使用到多个不同的页面或者布局中。传递方式:部件名称 后面 跟 部件的变量名和传递值得变量名:
当然也可以一次指定多个变量,进行传递
在部件的内部,可以和使用其他标记变量一样的,使用这些变量。
动态部件
部件和页面一样,也可以使用Twig标记。
部件的执行生命周期
onStart函数在部件渲染之前和部分执行之前执行。
onEnd函数在部件渲染之前和部件执行之后执行。
在onStart和onEnd函数中,您可以将变量注入到Twig环境中。使用array notation将变量传递给页面:
声明周期限制
由于部件的实例化时间比较晚,在页面渲染期间,部件的生命周期会受到一些限制。
AJax事件没有被注册,不能执行。
生命周期函数不能返回任何值。
表单常规的POST操作在部件渲染的时候执行。
一般来讲,部件中的组件一般设计为基本组件,用来渲染一些没有复杂处理的情况,比如按钮等。
partials 我们这里简称【部件】,是可以重复使用的Twig标记块。可以用于网站的任何位置。比如页眉页脚或者其他Ajax内容。
partials模板文件存储在模板目录的partials子目录中。扩展名是htm。最简单的例子:
<p>This is a partial</p>
partials 的配置部分是可选的,其中可选参数description,用于给后端用户提供功能说明。
description = "Demo partial"
==
<p>This is a partial</p>
Run code
Cut to clipboard
在配置部分可以定义组件,将在后续的组件部分学习。
部件的渲染
渲染部件的方式:{% partial "partial-name" %} 。这里只有一个必须的参数,就是【文件名】这里的文件名是指文件的名称部分,不包含扩展名部分。如果在子目录中,则需要写明路径。部件可以被页面、布局或者其他部件使用。
下面就是一个部件引用了另一个部件。
<div class="sidebar">
{% partial "sidebar-contacts" %}
</div>
Run code
Cut to clipboard
将变量传递给部件
部件的一个强大的功能是,我们可以给部件传递变量参数。比如我们拥有一个渲染博客列表的部件,我们可以将帖子的集合传递给中国博客列表部件。这时候这个部件就可以使用到多个不同的页面或者布局中。传递方式:部件名称 后面 跟 部件的变量名和传递值得变量名:
<div class="sidebar">
{% partial "blog-posts" posts=posts %}
</div>
Run code
Cut to clipboard
当然也可以一次指定多个变量,进行传递
<div class="sidebar">
{% partial "sidebar-contacts" city="Vancouver" country="Canada" %}
</div>
Run code
Cut to clipboard
在部件的内部,可以和使用其他标记变量一样的,使用这些变量。
<p>Country: {{ country }}, city: {{ city }}.</p>
Run code
Cut to clipboard
动态部件
部件和页面一样,也可以使用Twig标记。
部件的执行生命周期
onStart函数在部件渲染之前和部分执行之前执行。
onEnd函数在部件渲染之前和部件执行之后执行。
在onStart和onEnd函数中,您可以将变量注入到Twig环境中。使用array notation将变量传递给页面:
==
function onStart()
{
$this['hello'] = "Hello world!";
}
==
<h3>{{ hello }}</h3>
Run code
Cut to clipboard
声明周期限制
由于部件的实例化时间比较晚,在页面渲染期间,部件的生命周期会受到一些限制。
AJax事件没有被注册,不能执行。
生命周期函数不能返回任何值。
表单常规的POST操作在部件渲染的时候执行。
一般来讲,部件中的组件一般设计为基本组件,用来渲染一些没有复杂处理的情况,比如按钮等。
布局 Layout
概述
Layout,此处称为布局。定义了一个页面框架,即页面上的所有的重复的内容,例如header部分和footer部分。Layout通常包含HTML标签、HEAD标签、TITLE标签和BODY标签。
位置:安装的主题的目录,layout子目录中。
扩展名:htm
Layout中输出内容应该使用page标签进行页面内容输出。{% page %};最近简单的方式:
Page与Layout关系,Page可以使用不同的Layout,Layout也可以通过Page来引用多个page页面。但是,他们之间建立联系的是Page中的设置,然后Layout中的{% page %}才能正确的引用这个page,才可以通过Page的URL结合Layout布局把页面显示出来。
要为一个Page使用Layout,Page的Configuration Section部分必须引用Layout文件名称(不带扩展名)。请记住,如果从子目录引用Layout,则应指定子目录名称。使用default.htm的Layout的示例页面模板:
当请求该页面时,其内容与Layout合并,或者更确切地说 - Layout的{% page %}标签被页面内容替换。前面的示例会生成以下标记:
请注意,您可以在Layout中渲染部件。这使您可以在不同的Layout之间共享常用元素。例如,您可以有一个输出网站CSS和JavaScript链接的部件。这种方法简化了资源的管理。 如果你想添加一个JavaScript引用,你应该修改一个小部件,而不是编辑所有的Layout。
布局中的配置区域是可选的,支持name和description。
Placeholders
Placeholders这里称为【占位符】,可以允许页面将内容注入到布局中。占位符在布局模板中用{% placeholder %}标签定义。下面的例子显示了一个在HTML HEAD部分中定义了一个叫head的【占位符】的Layout模板。
页面可以使用{% put %}和{% endput %}标签将内容注入【占位符】。以下示例演示了一个简单的页面模板,它将CSS链接注入前一示例中定义的叫head占位符。
动态布局
和Page一样,Layout可以使用任何Twig特性。
布局的执行生命周期
布局中的PHP代码部分,可以定义页面周期函数:
onInit当所有组件被初始化并且在处理AJAX请求之前,该函数被执行。
onStart功能在页面处理开始时执行。
onBeforePageStart函数在Layout组件运行后执行,但在页面的onStart函数执行之前执行。
onEnd函数在页面呈现后执行。
处理程序执行的顺序如下:
概述
Layout,此处称为布局。定义了一个页面框架,即页面上的所有的重复的内容,例如header部分和footer部分。Layout通常包含HTML标签、HEAD标签、TITLE标签和BODY标签。
位置:安装的主题的目录,layout子目录中。
扩展名:htm
Layout中输出内容应该使用page标签进行页面内容输出。{% page %};最近简单的方式:
<html>
<body>
{% page %}
</body>
</html>
Run code
Cut to clipboard
Page与Layout关系,Page可以使用不同的Layout,Layout也可以通过Page来引用多个page页面。但是,他们之间建立联系的是Page中的设置,然后Layout中的{% page %}才能正确的引用这个page,才可以通过Page的URL结合Layout布局把页面显示出来。
要为一个Page使用Layout,Page的Configuration Section部分必须引用Layout文件名称(不带扩展名)。请记住,如果从子目录引用Layout,则应指定子目录名称。使用default.htm的Layout的示例页面模板:
url = "/"
layout = "default"
==
<p>Hello, world!</p>
Run code
Cut to clipboard
当请求该页面时,其内容与Layout合并,或者更确切地说 - Layout的{% page %}标签被页面内容替换。前面的示例会生成以下标记:
<html>
<body>
<p>Hello, world!</p>
</body>
</html>
Run code
Cut to clipboard
请注意,您可以在Layout中渲染部件。这使您可以在不同的Layout之间共享常用元素。例如,您可以有一个输出网站CSS和JavaScript链接的部件。这种方法简化了资源的管理。 如果你想添加一个JavaScript引用,你应该修改一个小部件,而不是编辑所有的Layout。
布局中的配置区域是可选的,支持name和description。
description = "Basic layout example"
==
<html>
<body>
{% page %}
</body>
</html>
Run code
Cut to clipboard
Placeholders
Placeholders这里称为【占位符】,可以允许页面将内容注入到布局中。占位符在布局模板中用{% placeholder %}标签定义。下面的例子显示了一个在HTML HEAD部分中定义了一个叫head的【占位符】的Layout模板。
<html>
<head>
{% placeholder head %}
</head>
...
Run code
Cut to clipboard
页面可以使用{% put %}和{% endput %}标签将内容注入【占位符】。以下示例演示了一个简单的页面模板,它将CSS链接注入前一示例中定义的叫head占位符。
url = "/my-page"
layout = "default"
==
{% put head %}
<link href="/themes/demo/assets/css/page.css" rel="stylesheet">
{% endput %}
<p>The page content goes here.</p>
Run code
Cut to clipboard
动态布局
和Page一样,Layout可以使用任何Twig特性。
布局的执行生命周期
布局中的PHP代码部分,可以定义页面周期函数:
onInit当所有组件被初始化并且在处理AJAX请求之前,该函数被执行。
onStart功能在页面处理开始时执行。
onBeforePageStart函数在Layout组件运行后执行,但在页面的onStart函数执行之前执行。
onEnd函数在页面呈现后执行。
处理程序执行的顺序如下:
Layout onInit() function.
Page onInit() function.
Layout onStart() function.
Layout components onRun() method.
Layout onBeforePageStart() function.
Page onStart() function.
Page components onRun() method.
Page onEnd() function.
Layout onEnd() function.
Run code
Cut to clipboard
内容块 Content Blocks
Content Blocks 这里我们称为内容块。内容块是可以编辑的文本、HTML代码或者Markdown块。主要用来保存静态内容,并支持基本的模板变量。与Partial(部件)相比,部件则更加灵活,一般用于生成动态内容。
介绍
内容块存储在主题目录的content子目录中。支持以下扩展名的文件:
Extension Description
htm 使用HTML标记语言
txt 使用纯文本语言
md 使用Markdown语法
这些扩展名决定了在后端系统界面中的编辑及显示方式。也决定了在网站前端的显示方式。Markdown块在显示之前会转换为HTML格式再显示。
渲染内容块
使用{% content 'file.htm' %}标签在Page、Partial 或 Layout 中渲染内容块。渲染Content Blocks的页面示例:
将变量传递给内容块
内容块不支持Twig标记,但是支持基本的变量,可以通过变量传递值给内容块。
在Content Blocks中,可以使用单个大括号 { } 访问变量:
全局变量
可以使用该View::share方法注册一个全局变量,可用于所有Content Blocks。
这段代码可以在 插件注册文件 的注册或启动方法中调用。使用上面的例子,变量{site_name}将在所有Content Blocks中可用。
Content Blocks 这里我们称为内容块。内容块是可以编辑的文本、HTML代码或者Markdown块。主要用来保存静态内容,并支持基本的模板变量。与Partial(部件)相比,部件则更加灵活,一般用于生成动态内容。
介绍
内容块存储在主题目录的content子目录中。支持以下扩展名的文件:
Extension Description
htm 使用HTML标记语言
txt 使用纯文本语言
md 使用Markdown语法
这些扩展名决定了在后端系统界面中的编辑及显示方式。也决定了在网站前端的显示方式。Markdown块在显示之前会转换为HTML格式再显示。
渲染内容块
使用{% content 'file.htm' %}标签在Page、Partial 或 Layout 中渲染内容块。渲染Content Blocks的页面示例:
url = "/contacts"
==
<div class="contacts">
{% content 'contacts.htm' %}
</div>
Run code
Cut to clipboard
将变量传递给内容块
内容块不支持Twig标记,但是支持基本的变量,可以通过变量传递值给内容块。
{% content 'welcome.htm' name='John' %}
Run code
Cut to clipboard
在Content Blocks中,可以使用单个大括号 { } 访问变量:
<h1>This is a demo for {name}</h1>
Run code
Cut to clipboard
全局变量
可以使用该View::share方法注册一个全局变量,可用于所有Content Blocks。
View::share('site_name', 'OctoberCMS');
Run code
Cut to clipboard
这段代码可以在 插件注册文件 的注册或启动方法中调用。使用上面的例子,变量{site_name}将在所有Content Blocks中可用。
组件 Components
Components这里我们称之为组件。
组件是可以配置的构建元素。可以附加到Pages(页面)、Layouts(布局)、Partials(部件)中。组件是October的核心特性。每个组件都可以对网站的功能进行扩展。组件可以在页面上输出HTML代码,但是这不是主要的,组件的一个重要功能是处理Ajax请求、处理表单提交回调,处理页面执行周期。允许向页面注入变量或者实现网站安全性。
介绍
启用组件,如果是后端管理系统中,可以选择组件面板,将组件拖动添加到页面、部件和布局中。如果是采用文本编辑模式,则可以将组件的对应模板的名称添加到对应的模板的配置部分。比如:下面的例子演示了如何将todolist组件添加到页面中。
当您引用Components时,它会自动创建一个与Components名称匹配的Page变量(在前面的示例中为demoTodo)。提供HTML标记的Components可以使用标记在Page上呈现{% component %},如下所示:
如果具有相同名称的两个组件分配给Page和Layout,Page中的组件将覆盖布局中的组件。
组件的别名
如果有两个注册Components的名称相同,则可以使用完全限定的名称引用组件,并为其指定一个别名:
第一个参数是类名,第二个参数是注入到Page时使用的组件的别名。如果您指定了组件的别名,那么在引用组件时,可以页面代码中的任何地方使用。下一个示例引用Components别名:
允许给同一个组件定义多个别名,以实现在同一个页面上使用一个组件的多个实例。
组件使用外部属性值
默认情况下,属性值在定义组件的配置部分会进行初始化,这时候属性值是静态的,如下所示:
不过有一个办法可以使用外部的参数为组件属性进行初始化。可以是URL参数,Partial部件参数。使用{{ paramName }}从外部变量加载的值的语法:
假设在上面的示例中,组件 demoTodo 在部件中使用,则部件的变量maxItems**将为组件的变量进行初始化:
如果是URL参数,则使用的方式略有不同:使用{{ :paramName }}名称以冒号(:)开头的语法
组件对应的页面在配置部分,应该具有相应的URL参数定义:
在October的后端,您可以使用Inspector工具将外部值分配给Components属性。在Inspector中,您不需要使用大括号输入参数名称。Inspector中的每个字段在右侧都有一个图标,用于打开外部参数名称编辑器。输入paramName部分变量或:paramNameURL参数的参数名称。
自定义默认标记
http://octobercms.com/docs/cms/components#moving-default-markup
Components这里我们称之为组件。
组件是可以配置的构建元素。可以附加到Pages(页面)、Layouts(布局)、Partials(部件)中。组件是October的核心特性。每个组件都可以对网站的功能进行扩展。组件可以在页面上输出HTML代码,但是这不是主要的,组件的一个重要功能是处理Ajax请求、处理表单提交回调,处理页面执行周期。允许向页面注入变量或者实现网站安全性。
介绍
启用组件,如果是后端管理系统中,可以选择组件面板,将组件拖动添加到页面、部件和布局中。如果是采用文本编辑模式,则可以将组件的对应模板的名称添加到对应的模板的配置部分。比如:下面的例子演示了如何将todolist组件添加到页面中。
title = "Components demonstration"
url = "/components"
[demoTodo]
maxItems = 20
==
...
Run code
Cut to clipboard
当您引用Components时,它会自动创建一个与Components名称匹配的Page变量(在前面的示例中为demoTodo)。提供HTML标记的Components可以使用标记在Page上呈现{% component %},如下所示:
{% component 'demoTodo' %}
Run code
Cut to clipboard
如果具有相同名称的两个组件分配给Page和Layout,Page中的组件将覆盖布局中的组件。
组件的别名
如果有两个注册Components的名称相同,则可以使用完全限定的名称引用组件,并为其指定一个别名:
[October\Demo\Components\Todo demoTodoAlias]
maxItems = 20
Run code
Cut to clipboard
第一个参数是类名,第二个参数是注入到Page时使用的组件的别名。如果您指定了组件的别名,那么在引用组件时,可以页面代码中的任何地方使用。下一个示例引用Components别名:
{% component 'demoTodoAlias' %}
Run code
Cut to clipboard
允许给同一个组件定义多个别名,以实现在同一个页面上使用一个组件的多个实例。
[demoTodo todoA]
maxItems = 10
[demoTodo todoB]
maxItems = 20
Run code
Cut to clipboard
组件使用外部属性值
默认情况下,属性值在定义组件的配置部分会进行初始化,这时候属性值是静态的,如下所示:
[demoTodo]
maxItems = 20
==
...
Run code
Cut to clipboard
不过有一个办法可以使用外部的参数为组件属性进行初始化。可以是URL参数,Partial部件参数。使用{{ paramName }}从外部变量加载的值的语法:
[demoTodo]
maxItems = {{ maxItems }}
==
...
Run code
Cut to clipboard
假设在上面的示例中,组件 demoTodo 在部件中使用,则部件的变量maxItems**将为组件的变量进行初始化:
{% partial 'my-todo-partial' maxItems='10' %}
Run code
Cut to clipboard
如果是URL参数,则使用的方式略有不同:使用{{ :paramName }}名称以冒号(:)开头的语法
[demoTodo]
maxItems = {{ :maxItems }}
==
...
Run code
Cut to clipboard
组件对应的页面在配置部分,应该具有相应的URL参数定义:
url = "/todo/:maxItems"
Run code
Cut to clipboard
在October的后端,您可以使用Inspector工具将外部值分配给Components属性。在Inspector中,您不需要使用大括号输入参数名称。Inspector中的每个字段在右侧都有一个图标,用于打开外部参数名称编辑器。输入paramName部分变量或:paramNameURL参数的参数名称。
自定义默认标记
http://octobercms.com/docs/cms/components#moving-default-markup
nginx
Added blacklist rules for nginx
.htaccess nginx
Added blacklist rules for nginx
location / {
try_files $uri /index.php$is_args$args;
}
rewrite ^themes/.*/(layouts|pages|partials)/.*.htm /index.php break;
rewrite ^bootstrap/.* /index.php break;
rewrite ^config/.* /index.php break;
rewrite ^vendor/.* /index.php break;
rewrite ^storage/cms/.* /index.php break;
rewrite ^storage/logs/.* /index.php break;
rewrite ^storage/framework/.* /index.php break;
rewrite ^storage/temp/protected/.* /index.php break;
rewrite ^storage/app/uploads/protected/.* /index.php break;
Run code
Cut to clipboard
.htaccess nginx
server {
listen 80;
server_name oc.com alias ;
location / {
root e:/oc.com;
index index.html index.htm default.html default.htm index.php default.php app.php u.php;
include e:/oc.com/up-*.conf;
try_files $uri /index.php$is_args$args;
}
include e:/oc.com/.htaccess;
autoindex off;
include advanced_settings.conf;
#include expires.conf;
location ~* .*\/(attachment|attachments|uploadfiles)\/.*\.(php|php5|PHP7|phps|asp|aspx|jsp)$ {
deny all;
}
location ~ ^.+\.php {
root e:/oc.com;
fastcgi_pass bakend;
fastcgi_index index.php;
fastcgi_split_path_info ^((?U).+\.php)(/?.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
include fastcgi.conf;
}
}
#server oc.com end}
Run code
Cut to clipboard
(支付宝)给作者钱财以资鼓励 (微信)→
有过 10 条评论 »
nginx可以include任何文件,而不仅仅是.htaccess
在 nginx/nginx.conf的server{}中引入 .htaccess 文件:
include /vhosts/quany.info/.htaccess;
//运行select查询 $users = Db::select(‘select * from users where active = ?‘, [1]); 传递给该select方法的第一个参数是原始SQL查询,而第二个参数是需要绑定到查询的任何参数绑定。通常,这些是where子句约束的值。参数绑定提供了针对SQL注入的保护。 该select方法将始终返回一个array结果。数组中的每个结果将是一个PHP stdClass对象,允许您访问结果的值: foreach ($users as $user) { echo $user->name; } //使用命名绑定 $results = Db::select(‘select * from users where id = :id‘, [‘id‘ => 1]); //运行一个insert语句 要执行一个insert语句,你可以使用insert在Db立面上的方法。像这样select,这个方法将原始SQL查询作为第一个参数,绑定作为第二个参数: Db::insert(‘insert into users (id, name) values (?, ?)‘, [1, ‘Joe‘]); //运行更新语句 该update方法应用于更新数据库中的现有记录。该语句受影响的行数将由方法返回: $affected = Db::update(‘update users set votes = 100 where name = ?‘, [‘John‘]); //运行delete语句 该delete方法应用于从数据库中删除记录。喜欢update,将返回删除的行数: $deleted = Db::delete(‘delete from users‘); //运行一般声明 某些数据库语句不应返回任何值。对于这些类型的操作,您可以使用立面上的statement方法Db Db::statement(‘drop table users‘); //多个数据库连接 当使用多个连接时,您可以通过立面上的connection方法访问每个连接Db。在name传递给connection方法应该对应于您列出的其中一个连接config/database.php组态文件中 $users = Db::connection(‘foo‘)->select(...); $pdo = Db::connection()->getPdo(); //数据库事务 Db::transaction(function () { Db::table(‘users‘)->update([‘votes‘ => 1]); Db::table(‘posts‘)->delete(); }); //手动使用交易 如果您想手动开始事务并完全控制回滚和提交,您可以使用立面上的beginTransaction方法Db: Db::beginTransaction(); 您可以通过以下rollBack方法回滚事务: Db::rollBack(); 最后,您可以通过以下commit方法提交事务: Db::commit(); //数据库事件 如果要接收应用程序执行的每个SQL查询,可以使用该listen方法。此方法对于记录查询或调试很有用。 Db::listen(function($sql, $bindings, $time) { // }); //查询记录 启用查询日志记录时,将记录所有已为当前请求运行的查询的内存。调用该enableQueryLog方法启用此功能 Db::connection()->enableQueryLog(); 要获取执行查询的数组,可以使用以下getQueryLog方法: $queries = Db::getQueryLog(); 然而,在某些情况下,例如当插入大量行时,这可能导致应用程序使用多余的内存。要禁用日志,您可以使用以下disableQueryLog方法: Db::connection()->disableQueryLog();
检索结果
//从表中检索所有行--get来看一下表中的所有记录 $users = Db::table(‘users‘)->get(); //通过访问列作为对象的属性来访问每列的值: foreach ($users as $user) { echo $user->name; } //从表中检索单个行/列 $user = Db::table(‘users‘)->where(‘name‘, ‘John‘)->first(); echo $user->name; //如果您甚至不需要整行,您可以使用该value方法从记录中提取单个值。此方法将直接返回列的值: $email = Db::table(‘users‘)->where(‘name‘, ‘John‘)->value(‘email‘); //分块结果从一张桌子 Db::table(‘users‘)->chunk(100, function($users) { foreach ($users as $user) { // } }); //您可以通过以下方式返回false来阻止进一步处理的块Closure: Db::table(‘users‘)->chunk(100, function($users) { // Process the records... return false; }); //检索列值列表 //如果要检索包含单列值的数组,则可以使用该lists方法 $titles = Db::table(‘roles‘)->lists(‘title‘); foreach ($titles as $title) { echo $title; } //您还可以为返回的数组指定自定义键列: $roles = Db::table(‘roles‘)->lists(‘title‘, ‘name‘); foreach ($roles as $name => $title) { echo $title; } //骨料 $users = Db::table(‘users‘)->count(); $price = Db::table(‘orders‘)->max(‘price‘); $price = Db::table(‘orders‘) ->where(‘is_finalized‘, 1) ->avg(‘price‘); //选择 $users = Db::table(‘users‘)->select(‘name‘, ‘email as user_email‘)->get(); //该distinct方法允许您强制查询返回不同的结果: $users = Db::table(‘users‘)->distinct()->get(); $query = Db::table(‘users‘)->select(‘name‘); $users = $query->addSelect(‘age‘)->get(); //原始表达式 $users = Db::table(‘users‘) ->select(Db::raw(‘count(*) as user_count, status‘)) ->where(‘status‘, ‘<>‘, 1) ->groupBy(‘status‘) ->get(); //加盟 $users = Db::table(‘users‘) ->join(‘contacts‘, ‘users.id‘, ‘=‘, ‘contacts.user_id‘) ->join(‘orders‘, ‘users.id‘, ‘=‘, ‘orders.user_id‘) ->select(‘users.*‘, ‘contacts.phone‘, ‘orders.price‘) ->get(); $users = Db::table(‘users‘) ->leftJoin(‘posts‘, ‘users.id‘, ‘=‘, ‘posts.user_id‘) ->get(); Db::table(‘users‘) ->join(‘contacts‘, function ($join) { $join->on(‘users.id‘, ‘=‘, ‘contacts.user_id‘)->orOn(...); }) ->get(); Db::table(‘users‘) ->join(‘contacts‘, function ($join) { $join->on(‘users.id‘, ‘=‘, ‘contacts.user_id‘) ->where(‘contacts.user_id‘, ‘>‘, 5); }) ->get(); //where子句 $users = Db::table(‘users‘)->where(‘votes‘, ‘=‘, 100)->get(); $users = Db::table(‘users‘)->where(‘votes‘, 100)->get(); $users = Db::table(‘users‘) ->where(‘votes‘, ‘>=‘, 100) ->get(); $users = Db::table(‘users‘) ->where(‘votes‘, ‘<>‘, 100) ->get(); $users = Db::table(‘users‘) ->where(‘name‘, ‘like‘, ‘T%‘) ->get(); //“或”声明 $users = Db::table(‘users‘) ->where(‘votes‘, ‘>‘, 100) ->orWhere(‘name‘, ‘John‘) ->get(); //“之间”之间的陈述 $users = Db::table(‘users‘) ->whereBetween(‘votes‘, [1, 100])->get(); $users = Db::table(‘users‘) ->whereNotBetween(‘votes‘, [1, 100]) ->get(); //“在哪里”声明 $users = Db::table(‘users‘) ->whereIn(‘id‘, [1, 2, 3]) ->get(); $users = Db::table(‘users‘) ->whereNotIn(‘id‘, [1, 2, 3]) ->get(); //“null”语句 $users = Db::table(‘users‘) ->whereNull(‘updated_at‘) ->get(); $users = Db::table(‘users‘) ->whereNotNull(‘updated_at‘) ->get(); //排序 $users = Db::table(‘users‘) ->orderBy(‘name‘, ‘desc‘) ->get(); //分组 $users = Db::table(‘users‘) ->groupBy(‘account_id‘) ->having(‘account_id‘, ‘>‘, 100) ->get(); //该havingRaw方法可用于将原始字符串设置为having子句的值。例如,我们可以找到销售额超过$ 2,500的所有部门: $users = Db::table(‘orders‘) ->select(‘department‘, Db::raw(‘SUM(price) as total_sales‘)) ->groupBy(‘department‘) ->havingRaw(‘SUM(price) > 2500‘) ->get(); //限制和抵消 //要限制从查询返回的结果数,或者在查询(OFFSET)中跳过给定数量的结果,可以使用skip和take方法: $users = Db::table(‘users‘)->skip(10)->take(5)->get(); //插入 Db::table(‘users‘)->insert( [‘email‘ => ‘john@example.com‘, ‘votes‘ => 0] ); Db::table(‘users‘)->insert([ [‘email‘ => ‘taylor@example.com‘, ‘votes‘ => 0], [‘email‘ => ‘dayle@example.com‘, ‘votes‘ => 0] ]); //自动递增ID $id = Db::table(‘users‘)->insertGetId( [‘email‘ => ‘john@example.com‘, ‘votes‘ => 0] ); //更新 Db::table(‘users‘) ->where(‘id‘, 1) ->update([‘votes‘ => 1]); //递增/递减 Db::table(‘users‘)->increment(‘votes‘); Db::table(‘users‘)->increment(‘votes‘, 5); Db::table(‘users‘)->decrement(‘votes‘); Db::table(‘users‘)->decrement(‘votes‘, 5); Db::table(‘users‘)->increment(‘votes‘, 1, [‘name‘ => ‘John‘]); //删除 Db::table(‘users‘)->delete(); Db::table(‘users‘)->where(‘votes‘, ‘<‘, 100)->delete(); Db::table(‘users‘)->truncate(); //悲观锁定 Db::table(‘users‘)->where(‘votes‘, ‘>‘, 100)->sharedLock()->get(); Db::table(‘users‘)->where(‘votes‘, ‘>‘, 100)->lockForUpdate()->get(); //缓存查询 //持久缓存 $users = Db::table(‘users‘)->remember(10)->get(); //内存缓存 Db::table(‘users‘)->get(); // Result from database Db::table(‘users‘)->get(); // Result from database Model::all(); // Result from database Model::all(); // Result from in-memory cache //您可以使用enableDuplicateCache或disableDuplicateCache方法启用或禁用重复缓存 Db::table(‘users‘)->enableDuplicateCache()->get(); //如果查询存储在缓存中,则当使用insert,update,delete或truncate语句时,它将自动被清除。但是您可以使用该flushDuplicateCache方法手动清除缓存 Db::table(‘users‘)->enableDuplicateCache()->get();
models:
//介绍 plugins/ acme/ blog/ models/ user/ <=== Model config directory columns.yaml <=== Model config files fields.yaml <==^ User.php <=== Model class Plugin.php //定义模型 namespace Acme\Blog\Models; use Model; class Post extends Model { /** * The table associated with the model. * * @var string */ protected $table = ‘acme_blog_posts‘; } //支持的属性 class User extends Model { protected $primaryKey = ‘id‘; public $exists = false; protected $dates = [‘last_seen_at‘]; public $timestamps = true; protected $jsonable = [‘permissions‘]; protected $guarded = [‘*‘]; } //首要的关键 class Post extends Model { /** * The primary key for the model. * * @var string */ protected $primaryKey = ‘id‘; } //时间戳 class Post extends Model { /** * Indicates if the model should be timestamped. * * @var bool */ public $timestamps = false; } //如果您需要自定义时间戳的格式,请设置$dateFormat模型上的属性。此属性确定日期属性如何存储在数据库中,以及当模型序列化为数组或JSON时的格式: class Post extends Model { /** * The storage format of the model‘s date columns. * * @var string */ protected $dateFormat = ‘U‘; } //值存储为JSON class Post extends Model { /** * @var array Attribute names to encode and decode using JSON. */ protected $jsonable = [‘data‘]; } //访问列值 foreach ($flights as $flight) { echo $flight->name; } //添加附加约束 $flights = Flight::where(‘active‘, 1) ->orderBy(‘name‘, ‘desc‘) ->take(10) ->get(); //集合 foreach ($flights as $flight) { echo $flight->name; } //分块结果 Flight::chunk(200, function ($flights) { foreach ($flights as $flight) { // } }); //检索单个模型 // Retrieve a model by its primary key $flight = Flight::find(1); // Retrieve the first model matching the query constraints $flight = Flight::where(‘active‘, 1)->first(); //找不到例外 $model = Flight::findOrFail(1); $model = Flight::where(‘legs‘, ‘>‘, 100)->firstOrFail(); Route::get(‘/api/flights/{id}‘, function ($id) { return Flight::findOrFail($id); }); //检索聚合 $count = Flight::where(‘active‘, 1)->count(); $max = Flight::where(‘active‘, 1)->max(‘price‘); //基本插入 $flight = new Flight; $flight->name = ‘Sydney to Canberra‘; $flight->save(); //基本更新 $flight = Flight::find(1); $flight->name = ‘Darwin to Adelaide‘; $flight->save(); //还可以针对与给定查询匹配的任意数量的模型执行更新。在这个例子中,所有的航班active,有一个destination的San Diego将被标记为延迟: Flight::where(‘is_active‘, true) ->where(‘destination‘, ‘Perth‘) ->update([‘delayed‘ => true]); //质量分配 class Flight extends Model { /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [‘name‘]; } //一旦我们赋予了属性质量分配,我们可以使用该create方法在数据库中插入新的记录。该create方法返回保存的模型实例: $flight = Flight::create([‘name‘ => ‘Flight 10‘]); //其他创作方法 $flight = Flight::make([‘name‘ => ‘Flight 10‘]); // Functionally the same as... $flight = new Flight; $flight->fill([‘name‘ => ‘Flight 10‘]); // Retrieve the flight by the attributes, otherwise create it $flight = Flight::firstOrCreate([‘name‘ => ‘Flight 10‘]); // Retrieve the flight by the attributes, or instantiate a new instance $flight = Flight::firstOrNew([‘name‘ => ‘Flight 10‘]); //删除模型 $flight = Flight::find(1); $flight->delete(); //按键删除现有的模型 Flight::destroy(1); Flight::destroy([1, 2, 3]); Flight::destroy(1, 2, 3); //通过查询删除模型 $deletedRows = Flight::where(‘active‘, 0)->delete(); //查询范围 class User extends Model { /** * Scope a query to only include popular users. */ public function scopePopular($query) { return $query->where(‘votes‘, ‘>‘, 100); } /** * Scope a query to only include active users. */ public function scopeActive($query) { return $query->where(‘is_active‘, 1); } } //利用查询范围 $users = User::popular()->active()->orderBy(‘created_at‘)->get(); //动态范围 class User extends Model { /** * Scope a query to only include users of a given type. */ public function scopeApplyType($query, $type) { return $query->where(‘type‘, $type); } } //现在您可以在调用范围时传递参数: $users = User::applyType(‘admin‘)->get();
变量:
{{variable}} {{isAjax?'Yes':'No'}} {{'Your name:' ~ name}}
标签:
{%tag%} {%if stormCloudComing%} Stay inside {else %} Gooutside and play {%endif%} {%set activePage='blog'%}
过滤器:
{{‘string’|filter}} {{price |currency('USD')}} {{'October Glory'|upper|replace({'October':'Morning'})}}
功能:
{{function()}} {{dump(variable)}}
this.page:
//布局: {{this.page.layout}} //id:文件名称和文件夹名称转换为css友好标识符 <body class="page-{{this.page.id}}"> //标题 <h1>{{this.page.title}}</h1> //描述 <p>{{ this.page.description }}</p> //meta_title <title>{{ this.page.meta_title }}</title> //meta_description <meta name="description" content="{{ this.page.meta_description }}"> //隐:隐藏的页面只能由登录的后端用户访问。 {% if this.page.hidden %} <p>Note to other admins: We are currently working on this page.</p> {% endif %}
this.layout:
//属性:您可以通过访问当前的布局对象,this.layout并返回该对象Cms\Classes\Layout //ID: <body class="layout-{{ this.layout.id }}"> //描述 <meta name="description" content="{{ this.layout.description }}"> this.theme: //属性 :this.theme将提供直接访问表单字段值,由任何主题定制定义。它本身也具有以下特性 //ID <body class="theme-{{ this.theme.id }}"> //配置 <meta name="description" content="{{ this.theme.config.description }}">
this.param:
//您可以通过this.param它访问当前的URL参数,并返回一个PHP数组 //访问页面参数 //如何访问tab页面中的URL参数。 url = "/account/:tab" == {% if this.param.tab == 'details' %} <p>Here are all your details</p> {% elseif this.param.tab == 'history' %} <p>You are viewing a blast from the past</p> {% endif %} //如果参数名称也是一个变量,那么可以使用数组语法 url = "/account/:post_id" == {% set name = 'post_id' %} <p>The post ID is: {{ this.param[name] }}</p>
this.environment
//您可以通过访问当前环境对象,this.environment并返回引用当前环境配置的字符串 //如果网站在测试环境中运行,以下示例将显示横幅: {% if this.environment == 'test' %} <div class="banner">Test Environment</div> {% endif %}
{%partial%}
{% partial "footer" %} {% partial "sidebar/menu" %} {% set tabName = "profile" %} {% partial tabName %} % partial "blog-posts" posts=posts %} {% partial "location" city="Vancouver" country="Canada" %} <p>Country: {{ country }}, city: {{ city }}.</p>
{%content%}
{% content "contacts.htm" %} {% content "sidebar/content.htm" %} {% content "readme.txt" %} {% content "changelog.md" %} {% put sidebar %} {% content 'sidebar-content.htm' %} {% endput %} {% content "welcome.htm" name=user.name %} {% content "location.htm" city="Vancouver" country="Canada" %} <p>Country: {country}, city: {city}.</p> {% content "welcome.htm" likes=[ {name:'Dogs'}, {name:'Fishing'}, {name:'Golf'} ] %} <ul> {likes} <li>{name}</li> {/likes} </ul>
{%占位符%}
{% placeholder name %} {% put name %} <p>Place this text in the name placeholder</p> {% endput %} {% placeholder sidebar default %} <p><a href="/contacts">Contact us</a></p> {% endplaceholder %} {% put sidebar %} <p><a href="/services">Services</a></p> {% default %} {% endput %} //检测占位符是否存在 {% if placeholder('sidemenu') %} <!-- Markup for a page with a sidebar --> <div class="row"> <div class="col-md-3"> {% placeholder sidemenu %} </div> <div class="col-md-9"> {% page %} </div> </div> {% else %} <!-- Markup for a page without a sidebar --> {% page %} {% endif %} //自定义属性 {% placeholder ordering title="Ordering information" type="text" %} {% placeholder ordering default title="Ordering information" type="text" %} There is no ordering information for this product. {% endplaceholder %}