为什么这个组合?有人会说,使用它与服务器端语言一起破坏了静态站点生成器的目的,但在我看来,在某些情况下是有意义的。
我觉得我的情况是这些地方的一个没有任何意义:
最近,我建造了Sindorftrödelt,这是一个在我家乡镇每年停车场销售的网站,我以Jekyll / PHP的方式结合了。Jekyll为静态部分,因为我有很多的经验,而PHP为动态部分,因为我已经支付了能够运行它的网络空间。
该网站只有几个动态部分,真正需要用服务器端语言完成:
-
作为卖家参与的人员的登记表。
-
稍后更新注册,将其标记为“付费”,通过PayPal网络挂单自动或通过网络界面为那些通过银行转帐付款的用户。
-
已付款人员的地址列在表格中,并在Google地图上显示为标记。
该数据每天通过cronjob更新一次。
其他一切只是静态信息和更改只是偶尔。
乍一看,只需使用服务器端语言构建一个完整的动态网站就有意义,但有理由反对:
- 规模
当大多数页面(包括目标网页)只是静态HTML时,服务器上的负载就会减少很多。不需要在每个请求上浪费CPU周期,重新生成几乎从不改变的东西。这对于比我的访问者更多的网站可能更重要,但另一方面,您可以在真正便宜的网络空间上运行具有普通访客数量的网站。
- 熟悉工具
我对Jekyll比PHP更有经验,特别是在布局/模板方面,根据环境(dev / staging / prod)设置大量(和我的意思是很多)配置值。如果你知道如何做到这一点,这在PHP中可能同样容易,但是我已经知道如何在Jekyll中做到这一点。
这主要是为什么我决定使用Jekyll / PHP组合方法的第二个原因。尽管这是我业余兴建的一个业余爱好项目,但由于跳蚤市场的日期已经固定,我们还有一个截止日期,人们应该可以在X个月前注册。
此外,我的业余时间仍然是我的业余时间,所以我不想在PHP中花时间学习模板框架,当我已经知道如何在Jekyll / Liquid中执行我需要的一切。
基本思想
我正在建立一个常规Jekyll网站的大部分网站 - 它具有配置文件,布局,包含,简单的动态菜单等。
PHP页面也是使用Jekyll创建的,所以它们可以包含前端,包括,配置变量等,它们只是它们是.php文件并包含<?php ... ?>
部分。
这里有一个例子,/ register/index.php:
---
title: Seller Registration
layout: default
---
{% if site.registration_enabled == 0 %}
Registration is not possible at the moment!
{% include under_construction.html %}
{% else %}
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// save registration in database
} else {
// process "registration page" Mustache template
}
?>
{% endif %}
在我的本地机器上构建站点时,将渲染Jekyll部件。所以到服务器上的文件已经有了我的站点的布局等等,除了<?php ... ?>
服务器在运行时执行的部分,大部分都是静态的,但如果配置值registration_enabled
被设置为0
,整个<?php ... ?>
部分被省略输出。
这意味着我必须重新构建并重新上传网站才能启用/禁用注册,但是我可以与之同住。
显然,我不使用GitHub页面,因为网站的一部分是用PHP编写的,但是我已经编写了过去建立和FTP的Jekyll网站的过程,我也在这个网站上做了同样的工作。所以更新网站只是意味着:运行一个批处理文件并等待一分钟。
使其在XAMPP上运行
一个刚刚显示的Jekyll / PHP页面就可以在任何便宜的LAMP webhoster上托管。但是,为了能够在上传之前测试本地机器上的PHP部件,我需要做更多的工作。
jekyll serve
基本上可以在本地构建和运行本地,但是Jekyll的内置Web服务器当然无法处理PHP页面。
所以因为我已经知道XAMPP,我在XAMPP中运行该站点。
整个项目需要在XAMPP的htdocs文件夹中才能使用XAMPP的网络服务器。在我的机器上,它是C:\ xampp \ htdocs \ sindorf-troedelt \ src。
完成的网站将转到C:\ xampp \ htdocs \ sindorf-troedelt \ site,这意味着本地机器上的URL将是localhost / sindorf-troedelt / site。
因此,所有链接和URL都必须通过前缀{{site.url}}
和多个 配置文件来创建,例如:
/_config-xampp.yml
url: http://localhost/sindorf-troedelt/web/site
/_config-prod.yml
url: https://sindorf-troedelt.de
标记页面中的示例链接:
[Link text]({{site.url}}/register/)
在PHP中使用Jekyll Config变量
说到多个配置文件:我的网站有很多配置变量,其中大部分取决于当前的环境(local / staging / prod)。
其中一些变量只适用于Jekyll (site.registration_enabled
如上图所示),但有些则在PHP代码中使用。
在PHP中使用Jekyll变量很简单:
<?php
$site_url = '{{site.url}}';
?>
...但是我不想像这样的PHP代码(内置Jekyll / Liquid),洒在整个地方。
所以我创建了一个中央的PHP包含文件,我在这里声明了PHP中需要的所有“ config ”变量:
/inc/config.inc.php:
---
layout: null
---
<?php
// basics
$site_url = '{{site.url}}';
$site_environment = '{{site.environment}}';
// database
$db_host = '{{site.db_host}}';
$db_name = '{{site.db_name}}';
$db_user = '{{site.db_user}}';
$db_pass = '{{site.db_pass}}';
?>
要在另一个PHP文件中使用这些值,您需要包含第一个文件并声明变量global:
<?php
require_once '../inc/config.inc.php';
global $site_url;
echo $site_url;
?>
另外,还可以在PHP中使用更复杂的配置值。
我的网站在配置文件中列出了可能的付款选项:
payment_options:
- Bank transfer
- PayPal
这些值对于dev / staging / prod始终是相同的,但是我需要它们在Jekyll / Liquid代码和PHP代码中,我想避免在两个不同的地方定义它们。
所以我把它放到上面显示的inc / config.inc.php文件中:
$payment_options = array();
{% for p in site.payment_options %}$payment_options [] = '{{p}}';
{% endfor %}
Jekyll提交了PHP文件后,它将如下所示:
$payment_options = array();
$payment_options [] = 'Bank transfer';
$payment_options [] = 'PayPal';
服务器端包含
除了PHP,我还在一个页面上使用服务器端包含。
我之前已经提到我的车库销售网站有一个cronjob,每天运行一次,加载所有注册的地址,标记为“付费”,并创建:
注意:这两个页面仅在车库销售前(通常为9月)的月份启用,因此您可能无法看到地图和列表,具体取决于您访问链接的时间。
第二个文件是我使用SSI。有人说,SSI 是没有意义的,当你能够使用PHP的include
还是file_get_contents
,但我喜欢这里SSI因为我包括表为静态HTML页面。我必须把它改成一个PHP文件来包含PHP表,这个页面在车库销售日和前几天都会受到很大的打击,所以我更喜欢静态的HTML和SSI来最小化服务器上的负载。
在技术上,它类似于之前显示的组合Jekyll / PHP页面,但为了使SSI工作,文件通常必须是.shtml或.shtm文件(取决于服务器配置)。
这里有一个例子:
/addresses/index.shtml
---
title: Address List
layout: default
---
{% if site.list_enabled == 0 %}
List is disabled at the moment
{% include under_construction.html %}
{% else %}
{{site.address_include}}
{% endif %}
最困难的部分是{{site.address_include}}
在配置文件中获取正确的值。
该路径必须与根相对,但根根据环境而不同:
在真正的服务器上,它位于根目录的子目录中:
address_include: '<!--#include virtual="/data/addresses.html" -->'
...但是对于XAMPP,这个目录在下面的几个级别htdocs
:
address_include: '<!--#include virtual="/sindorf-troedelt/web/site/data/addresses.html" -->'
胡子模板
Mustache和Jekyll都使用双大括号作为占位符,所以您应该从外部文件加载您的Mustache模板,无需前端,所以他们绝对不会被Jekyll感动!
我知道这是因为我犯了同样的错误。我只想运行一个小例子来看看Mustache是否正常工作,所以我将Mustache文档中的一个例子直接复制到我的PHP源代码中:
<?php
$m = new Mustache_Engine;
echo $m->render('Hello {{planet}}', array('planet' => 'World!')); // "Hello World!"
...和Mustache显示“ Hello
”,并没有呈现变量。
我没有考虑的事实是,这个特定的PHP页面有YAML的前端,所以在Jekyll构建站点时,它被处理。
Jekyll替换{{planet}}
为一个空字符串,因为它没有一个名为的变量planet
。当胡子最终执行时,模板“ Hello
”不再包含任何变量,所以Mustache没有做任何事情,而是Hello
显示“ ”。
当您从外部文件运行时加载模板时,这个整个问题就消失了。因此,为了能够以绝对最小的代码量渲染模板,我创建了这个帮助函数:
class Data {
// empty helper class for Mustache
}
function template($template, $data) {
$tpl_path = '{{site.template_path}}';
$tpl = new Mustache_Engine(array(
'loader' => new Mustache_Loader_FilesystemLoader($tpl_path.'tpl'),
'cache' => $tpl_path.'tplcache',
));
return $tpl->render($template, $data);
}
site.template_path
(你猜到它)是一个来自配置文件的值,再次取决于环境。
对于XAMPP,它只是:
template_path: C:\xampp\htdocs\sindorf-troedelt\web\site\templates\
但是对于我的网络空间,它必须是整个服务器根目录的完整部分:
template_path: /www/htdocs/my-user-name/sindorftroedelt/templates/
/ www / htdocs / my-user-name /是服务器的“我的部分”的根目录。所以当我FTP进入我已经租用的网络空间,我看到的目录是/ sindorftroedelt / templates /。
有了这个帮助函数,我可以从PHP渲染一个Mustache模板,如下所示:
$data = new Data();
$data->whatever = 'blah';
echo template('foo', $data);
假定在/ templates / tpl目录下的名为foo.mustache的文件中有一个模板。
本篇文章翻译者:
猪猪冰
如有外文不理解可联系猪猪冰:QQ-2911776312
妹子哦!