avris / esse
Requires
- php: ^7.4|^8.0
- ext-gd: *
- ext-json: *
- avris/suml: ^0.3
- symfony/dependency-injection: ^4.3|^5.0
- symfony/string: ^5.0
README
基于文件系统、以Git为中心的CMS,只关注(我认为的)"基本"功能。
安装
composer require avris/esse
在 config/bundles.php
中启用组件
Avris\Esse\AvrisEsseBundle::class => ['all' => true],
config/routes.yaml
:
esse_image:
path: '/image/{filename}_{size}.{extension}'
requirements: { filename:'.+' }
controller: 'Avris\Esse\Controller\EsseController::image'
esse_file:
path: '/file/{filename}.{extension}'
requirements: { filename:'.+' }
controller: 'Avris\Esse\Controller\EsseController::file'
.gitignore
:
/public/image
(可选)在 config/packages/avris_esse
中覆盖默认配置
avris_esse:
entriesDir: '%kernel.project_dir%/content/entries'
imagesDir: '%kernel.project_dir%/content/images'
filesDir: '%kernel.project_dir%/content/files'
imageSizes:
big: { maxwidth: 960 }
small: { maxwidth: 480 }
micro: { maxwidth: 36, maxheight: 36}
使用方法
基本概念
内容基本上是一系列条目(SUML文件)。它们可以是不同类型
block
- 仅仅是一个通用的字符串或数组图片
文件
- 任何您想要的自定义类型
它们分别放入 /content/entries
、/content/images
和 /content/files
目录。例如,如果您在 /content/entries/about/skills.suml
中放置以下内容
content:
en:
programming:
php: 'PHP'
js: 'JavaScript'
soft:
teamwork: 'Teamwork'
pl:
soft:
teamwork: 'Praca zespołowa'
然后您可以这样获取它
public function foo(Esse $esse)
{
return $this->render('home/foo.html.twig', [
'skills' => $esse->get('about/skills'),
]);
}
您还可以使用 $esse->getPart('about/skills.soft.teamwork')
获取内容中的特定字段,或在模板中: {{ esse('about/skills.soft.teamwork') }}
。它将自动转换为当前请求的区域设置,使用 %locale%
并使用通用的 "language" _
作为后备。
您可以添加任何您想要的元数据(包括默认为 block
、image
或 file
的 type
,这取决于文件所在的目录,以及默认为 false
的 published
)
type: `article`
createdAt: 2020-03-11 12:34:56
content: [] # ...
这些可以通过 $entry->meta('createdAt')
访问。
图片
将图片放入 /content/images/album.png
,然后在 /content/images/album.suml
中的以下内容
type: 'image' # optional
filename: 'album.png'
alt: 'My photo album'
source: 'https://example.com/album.png'
Esse 将通过 $esse->getImage('album')
给您这个图片,并在 https://127.0.0.1:8000/image/album_sm.png
下提供该图片的 sm
版本(如配置中定义,在 imageSizes
下)。
文件
将文件放入 /content/files/foo.txt
,然后在 /content/files/foo.suml
中的以下内容
type: 'file' # optional
filename: 'foo.txt'
published: true # optional
title: 'The Foo file'
Esse 将通过 $esse->getFile('foo')
给您该文件,并在 https://127.0.0.1:8000/file/file.txt
下提供服务。
修改器
您可以通过实现 Avris\Esse\Interfaces\EsseModifier
来修改任何在Esse提供之前的内容,例如
<?php
namespace App\Article;
use App\Service\ArticleProcessor;
use Avris\Esse\Entity\Entry;
use Avris\Esse\Interfaces\EsseModifier;
final class ArticleModifier implements EsseModifier
{
private ArticleProcessor $articleProcessor;
public function __construct(ArticleProcessor $articleProcessor)
{
$this->articleProcessor = $articleProcessor;
}
public function modifyEntry(Entry $entry): ?Entry
{
if ($entry->type()->toString() !== 'article') {
return $entry;
}
if (!$entry->published() || $entry->meta('publishedAt') > new \DateTimeImmutable()) {
return null;
}
$data = $entry->allMeta();
$data['content'] = [];
foreach ($entry->versions() as $version) {
$data['content'][$version] = $this->articleProcessor->process($entry->content($version));
}
return $entry->with($data);
}
}
索引
您可以通过实现 Avris\Esse\Interfaces\EsseIndex
来创建条目的缓存索引,例如
<?php
namespace App\Article;
use Avris\Esse\Interfaces\EsseIndex;
final class TagIndex implements EsseIndex
{
public function id(): string
{
return 'tag';
}
public function build(iterable $rawFiles): array
{
$index = [];
foreach ($rawFiles as $key => $data) {
if (($data['type'] ?? null) !== 'article') {
continue;
}
foreach ($data['content'] ?? [] as $version => $content) {
foreach ($content['tags'] ?? [] as $tag) {
$tag = mb_strtolower($tag);
if (!isset($index[$tag])) {
$index[$tag] = [];
}
$index[$tag][] = $key;
}
}
}
return $index;
}
}
示例用法
/**
* @Route("/tag/{tag}")
*/
public function tag(string $tag, Esse $esse)
{
return $this->renderFormat('tag', [
'articles' => $esse->fromIndex('tag', mb_strtolower($tag)),
]);
}
版权
- 作者: Andre Prusinowski (Avris.it)
- 许可证: MIT