cspray / blogisthenics
用Blogisthenics让你的博客生成器减肥!
Requires
- php: ^8.1
- adbario/php-dot-notation: ^3.1
- cspray/annotated-container: ^1.2
- laminas/laminas-escaper: ^2.10.0
- league/commonmark: ^2.3
- minicli/command-help: ^0.1.0
- minicli/minicli: ^3.2
- monolog/monolog: ^3.1
- rdlowrey/auryn: ^1.4
- voku/stringy: ^6.5
Requires (Dev)
- mikey179/vfsstream: ^1.6
- phpunit/phpunit: ^9.5
This package is auto-updated.
Last update: 2024-09-22 02:06:44 UTC
README
您正在寻找具有以下功能的静态网站生成器吗?
- 使用最新的JavaScript Web Components的SPA?
- 内置最新的CSS框架?
- 访问最时尚、最现代的模板引擎?
- 与您最喜欢的框架集成?
那么这个项目不适合您,因为Blogisthenics不提供这些功能!永远不会!我们给您什么?
- 一种使用HTML、Markdown和少量CSS创建无聊的多页应用程序的方法;点击链接会使整个页面刷新。太老式了!
- 经过20多年使用的强大、无附加功能的模板引擎。PHP本身!
- 使用Front Matter自定义您的动态内容... 不是YAML!
- 绝对没有JavaScript或相关工具。非常感谢,我只希望在我的网站生成器中只有1种糟糕的语言!
- 用于以编程方式控制您网站内容的协调、类型安全、可测试的机制!
使用说明
哦,见鬼。你还在这里?说实话,你可能不应该使用这个软件!有大量的网站生成器,几乎所有这些都会比这个垃圾球得到更多的支持。下面我写的都是为了我自己,这样当我6个月后回来时,我就能弄清楚到底发生了什么。
目录结构
Blogisthenics遵循的原则是,您的网站配置有一些合理的默认值,但您可以覆盖任何默认值来定制您的安装。您的目录结构应类似于以下内容
/.blogisthenics
config.json # Configure Blogisthenics, if not provided default config will be used
/content # The actual content for your site goes here
/assets # CSS, JS, images ... isn't treated specially, convention to put stuff here
/blog # Your blog articles ... could be named whatever you want
index.md # Markdown files are ok. Front-matter parsing and layouts are supported
about.html # HTML files are ok too, you won't get any parsing or layout support though
contact.html.php # Add a PHP extension to enable front-matter parsing and layout support
/data
... # Store JSON files here to access in the KeyValueStore
/layouts
main.html.php # Store PHP template files here to use as layouts
article.html.php # Layouts can be nested as deep as you want, but probably a logical limit
foo.md.php # Support Markdown templates
/src
/ContentGeneratedHandler
... # Any ContentGeneratedHandler instances
/ContentWrittenHandler
... # Any ContentWrittenHandler instances
/DataProvider
... # Any DataProvider instances
/DynamicContentProvider
... # Any DynamicContentProvider instances
/Formatter
... # Any Formatter instances
/TemplateHelperProvider
... # Any TemplateHelperProvider instances
内容概述
您的网站内容分为三个类别
- 静态资产
- 布局
- 页面
静态资产
静态资产是指您的网站中不应该动态渲染的任何内容,文件中的内容将被精确复制,路径不变,当网站构建时。具体来说,以下功能不支持静态资产。
- 前端解析
- 模板处理,即没有变量
- 多扩展格式支持
页面
页面是.html
、.md
和.php
文件,用作特定路径的具体内容,该路径将添加到您的网站中。页面应仅是部分HTML文档,并必须定义一个布局。如果一个页面中没有明确定义布局,我们将使用网站配置中的默认布局。
布局
布局是.md
和.php
文件,用作页面的外层框架。布局可以插入到其他布局中。以下示例展示了最小布局,通常命名为main.html.php
或default.html.php
。
<!DOCTYPE html> <html> <head> <title><?= $this->title ?? 'Blogisthenics' ?></title> </head> <body> <?= $this->yield() ?> </body> </html>
注意调用$this->yield()
,当在一个布局中时这是必需的,以输出被注入的内容。如果您尝试从一个非布局的内容中调用$this->yield()
,将会抛出异常。有关使用页面和布局的更多详细信息,请查看下面的“模板”部分。
模板
Blogisthenics使用PHP本身作为模板引擎。在此基础上,我们添加了一些功能以实现以下功能
- 嵌套任意级别的布局
- 自动转义所有值,包括上下文相关的转义能力。
- 提供对布局和页面FrontMatter的访问权限
- 提供对加载数据的只读访问
- 允许创建用于输出常见内容片段的辅助方法
本节中描述的大多数功能都涉及 Cspray\Blogisthenics\Context
对象。在您的模板中,该对象被定义为 $this
。最简单的模板可能看起来像以下这样。
<!-- Stored in the layouts directory with the filename `main.html.php` --> <!DOCTYPE html> <html> <head> <title><?= $this->title ?? 'Blogisthenics README' ?></title> </head> <body> <?= $this->yield() ?> </body> </html>
<!-- Stored in the content directory with the filename `index.md` --> { "title": "Home Page" } # <?= $this->title ?> Yep, that's right. The Front Matter is just a JSON object. Slap a new line on the end of that bad boy, then start writing your content. The values available in the page are the values found in your Front Matter.
构建后,您的网站将包括一个类似于以下的 index.html
文件
<!DOCTYPE html> <html> <head> <title>Home Page</title> </head> <body> <h1>"Home Page"</h1> <p> Yep, that's right. The Front Matter is just a JSON object. Slap a new line on the end of that bad boy, then start writing your content. The values available in the page are the values found in your Front Matter. </p> </body> </html>
模板辅助工具
有时,您想做的事情可能超出了静态FrontMatter的能力,或者如果封装在可以在模板中调用的方法中,将更容易在许多页面和布局中共享,那么使用 TemplateHelperProvider
,您可以轻松地添加模板辅助方法,然后在模板中访问它们。
要利用模板辅助工具,您将不得不实现一些PHP代码。除了您的辅助工具所做的任何事情,您还需要确保它与Blogisthenics集成。幸运的是,这很容易做到,多亏了 Annotated Container。此代码应位于您的Blogisthenics站点 src
目录中的某个位置。
<?php declare(strict_types=1); namespace Acme\BlogisthenicsDemo; use Cspray\AnnotatedContainer\Attribute\Service;use Cspray\Blogisthenics\Template\MethodDelegator;use Cspray\Blogisthenics\Template\TemplateHelperProvider; #[Service] final class MyTemplateHelperProvider implements TemplateHelperProvider { public function addTemplateHelpers(MethodDelegator $methodDelegator) : void { $methodDelegator->addMethod('myHelper', function() { return 'This is my helper content!'; }); } }
现在,您可以在模板中调用 $this->myHelper()
!
<!-- some file ending in .md --> <?= $this->myHelper() ?>
自动转义
由于内容可以在运行时生成,可能包括来自外部来源的数据,因此Blogisthenics认为您的所有数据都应该得到适当的转义。通过使用 laminas/escaper 项目,我们自动转义来自上下文对象的全部值。这意味着,您的所有FrontMatter、方法辅助工具和加载的JSON数据都会在输出时自动进行HTML转义。如果您不想自动转义辅助方法中的值,请将其包装在值对象 Cspray\Blogisthenics\SafeToNotEncode
中。
未来的更新将添加一个模板API,以实现上下文相关的转义。换句话说,您将能够隐式和显式地根据它是CSS数据、JS数据还是HTML数据来转义数据片段。
模板格式化
如前所述,我们支持从Markdown文档创建页面的功能。具体来说,Blogisthenics使用由 GitHub Flavored Markdown 提供的 league/commonmark 包。毕竟,只使用HTML来写博客会开始变得相当过时...博客文章非常适合Markdown。我们不是将Markdown支持嵌入到Blogisthenics中,而是公开了一个名为 Cspray\Blogisthenics\Formatter
的接口,为渲染模板提供了应用一些额外格式化的机会。《Cspray\Blogisthenics\GitHubFlavoredMarkdownFormatter》是负责Markdown的实现。如果您发现Blogisthenics的简约方法对您来说过于简陋,您可以自己实现 Formatter
实例。我们将利用Annotated Container轻松地将您的格式化器集成到Blogisthenics中。此代码应位于您的Blogisthenics站点 src
目录中的某个位置。
<?php declare(strict_types=1); namespace Acme\BlogisthenicsDemo; use Cspray\AnnotatedContainer\Attribute\Service;use Cspray\Blogisthenics\Template\Formatter; #[Service] final class MyCustomFormatter implements Formatter { public function getFormatType() : string { return 'my-type'; } public function format(string $contents) : string { return 'my formatted ' . $contents; } }
现在,任何以 my-type
或 my-type.php
结尾的模板都将传递给 MyCustomFormatter
,然后再将内容写入磁盘。
动态内容
有时无法在静态文件中提前创建所有必要的内容。您可能需要访问网站内容或某些其他信息,这要求您在运行时提供内容。您可以在Blogisthenics中通过实现Cspray\Blogisthenics\DynamicContentProvider
接口来处理此问题。我们将使用注解容器来轻松集成您的实现。此代码应位于Blogisthenics网站的src
目录中的某个位置。
<?php declare(stric_types=1); use Cspray\AnnotatedContainer\Attribute\Service;use Cspray\Blogisthenics\Site;use Cspray\Blogisthenics\SiteGeneration\DynamicContentProvider; #[Service] final class MyContentProvider implements DynamicContentProvider { public function addContent(Site $site) : void { // Construct your Content and call $site->addContent($content) } }
程序性数据
有时您的博客或网站可能需要包含一些程序性加载的数据。在Blogisthenics内部,这些数据存储在Cspray\Blogisthenics\KeyValueStore
中。您可以在自己的#[Service]
中依赖此服务,并将可变实现注入。在模板上下文中,您可以通过Context::kv()
方法,或模板中的$this->kv()
获取对不可变存储的访问权限。您可以通过以下两种方法之一将数据加载到KeyValueStore
中;静态或通过程序性调用。
加载静态文件
在您的数据目录中,默认情况下是网站根目录下的/data
,所有JSON文件都将被加载并存储在KeyValueStore
中。所有数据都使用文件名进行命名空间,JSON对象中的键可以通过点符号访问。例如,如果您有一个以下JSON文件存储在/data/foo.json
中,您可以在模板中调用以下方法。
{
"bar": {
"baz": {
"qux": "whatever"
}
}
}
// Inside a Page or Layout <?= $this->kv()->get('foo/bar.baz.qux') ?>
加载动态数据
也许您事先不知道需要加载什么数据。在这些情况下,您应实现一个Cspray\Blogisthenics\DataProvider
实例。我们将利用注解容器轻松集成此实例。在您的/src
目录中,您应该实现以下内容
<?php declare(strict_types=1); use Cspray\AnnotatedContainer\Attribute\Service;use Cspray\Blogisthenics\SiteData\DataProvider; #[Service] class MyDataProvider implements DataProvider { public function addData(KeyValueStore $keyValue) : void { // add whatever data is appropriate } }
就像静态加载的文件一样,您可以通过点符号访问存储在商店中的任何数据。与静态加载的文件不同,没有任何自动命名空间。如果您的数据需要命名空间,请确保您在使用设置数据时使用该键。
为什么?
显然,我知道它们。我包括了对它们网站的链接!我这样做有四个主要原因。
-
我是一个自虐狂。
-
当我查看现有的网站生成器时,我看到许多库,从我的角度来看,它们有以下缺点
- 不是用PHP编写的
- 使用SPA架构创建网站
- 需要我使用Laravel或Symfony
我想用PHP构建我的网站,而且不需要Laravel或Symfony。我没有找到针对无框架受众的产品,所以我自行构建了它。
-
有机会使用Annotated Container。
-
通过创建事物来学习它们的工作原理或我如何实现它们,这是我的学习方式。这对我来说是一种乐趣。