Content Management in Flood\Canal
Content management is about managing the content that is structured in to sections which hold articles.
An article is any page that will be displayed. The <article-id>.json
is the meta
file and the <article-id>.md
the content file.
Classes
For handling the content, four main classes are responsible.
- Namespace:
Flood\Canal\Feature\Content
Content\Content
beholds the whole content and serves as api/containermatch()
determines the active content from the request and matchgetArticle($id)
single article fetcher by ID, usesindex
getSection($id)
single section gettergetSection($id)->getArticle($id)
single article getter, used to get article of that section
Content\Section
beholds which section exist and for each section the article, is accessible fromContent
Content\Article
beholds the main content of one page, is accessible fromSection
andContent
, depends on what data you have to get the articlegetBlock($id = null)
gets one or all blocks
Content\DocTree\Block
beholds single blocks, like sidebar banners etc. which where assigned to one article, is accessible fromArticle
Default Folders
Default folder for templating.
The feature file will setup default paths and namespaces.
Blocks and Markdown files are Twig enabled by default.
Section and Articles
Adding new Content
A section is a collection of articles, but each article is also independent in some ways.
They are added in _content.php
:
They could directly be set as an array during the initializing of a section addSection
, or later with getSection($id)
. As both are returning an instance of Section
. A section could only be added once, if there will be added another section with the same name, it will be overwritten.
The ID of the section will be used as the folder containing the article files, you could specify for each section another folder that will be added before the section. Need to be with trailing slash.
<setPath-path/><section-id>/
<section-id>/
The ID of the article will be used to as the file name, when file
not defined as parameter.
Section->addArticle
could receive ($id, $folder = '', $file = '', $tag = [])
and Section->addArticleList
the array like:
<?php
[
[
'id' => '<article-id>',
'tag' => [], // optional, recommended
'folder' => '<article-folder>', // optional
'file' => '<article-file>', // optional
]
];
Example
<?php
/*
* Folder structure will be defaults, 'folder_structure' = 'same'
*/
$frontend->content->addSection('page')->setPath('demo/')->addArticleList([
[
'id' => 'home',
],
]);
/*
* /data/content/demo/home.json
* /data/content/demo/home.md
*/
$frontend->content->addSection('law')->setPath('law/');
$frontend->content->getSection('law')->addArticle(/*id*/ 'imprint-en', /*tag*/ ['path' => 'law/imprint'], /*folder*/ 'imprint');
/*
* /data/content/law/imprint/imprint-en.json
* /data/content/law/imprint/imprint-en.md
*/
$frontend->content->addSection('misc');
$frontend->content->getSection('misc')->addArticle('contact');
/*
* /data/content/contact.json
* /data/content/contact.md
*/
Tag's and Wiring to Routes
The easiest way for small pages is to use autowiring. For complex routes or more than a handful articles it is recommended to use tag's.
autowiring
At autowiring the article ID is treated as unique at all existing articles, meaning an article overview
can only be existing in any section, only the last added article will be matched.
The article id could be made of:
- the path part of the request URL
- the ID of the route
$frontend->match['_route']
, that's the index of the route you have set in$route->addList()|add()
see_route.php
The path part wiring will win if both would match.
Tag
Tags are controlling exactly when an article is active, instead of using the article id for autowiring, using tags on all routes results the possibility to name multiple articles with the same id (in different sections).
{
"path":"string",
"marker": "string|array",
"route": "string"
}
- path: will be matched against the URL path part
- marker: for adding custom logic on searching articles
- route: the id of the route
Parsed Content
After setting an article, creating the meta and content files, to get the content for one or the active article is easy:
access content from the controller
getContent is deprecated and will be switched with getMainText
<?php
$this->frontend->content->getActiveArticle()->getContent(); // deprecated
$this->frontend->content->getActiveArticle()->getMainText();
$this->frontend->content->getSection('page')->getArticle('about')->getMainText();
$this->frontend->content->getArticle('page', 'about')->getMainText();
access content from the template
{{ content.getActiveArticle().getMainText()|raw }}
{{ content.getSection('page').getArticle('about').getMainText()|raw }}
{{ content.getArticle('page', 'about').getMainText()|raw }}
This will execute the .md content file at first with Twig and then with Parsedown.
Meta Information
The meta file will be read in each article and not only when needed.
A minimal meta file:
{
"date": {
"create": "2017-12-13 12:00",
"update": "2017-12-14 12:00"
},
"meta": {
"lang": "en"
}
}
Recommended minimum:
{
"date": {
"create": "2017-12-13 12:00",
"update": "2017-12-14 12:00"
},
"head": {
"title": "About | New Flood\\Canal Project",
},
"meta": {
"lang": "en",
"description": "This is the meta description content."
}
}
With those automatically used in canal-view:
{
"date": {
"create": "2017-12-13 12:00",
"update": "2017-12-14 12:00"
},
"head": {
"title": "About | New Flood\\Canal Project",
"author": "You",
"font": "https://fonts.googleapis.com/css?family=Barlow"
},
"meta": {
"lang": "en",
"description": "This is the meta description content."
}
}
Getting the meta information
access meta from controller
<?php
$this->frontend->content->getActiveArticle()->meta('date');
$this->frontend->content->getActiveArticle()->meta('date')['create'];
$this->frontend->content->getSection('page')->getArticle('about')->meta('date')['create'];
$this->frontend->content->getArticle('about')->meta('date')['create'];
access meta from template
{{ content.getActiveArticle().meta('date')['create'] }}
{{ content.getSection('page').getArticle('about').meta('date')['create'] }}
{{ content.getArticle('about').meta('date')['create'] }}
Only for `meta` and `head` informations of active article:
{{ head.title }}
{{ meta.description }}
DocTree, Block
The tree is a way of arranging the content of an article in a way so it is possible to change it through another program and split data from the view.
A tree will hold which part should be rendered when, composing meta with templates, using blocks and more.
Block
Modules, Plugins: Any Reusable Component which should be able to use in the Tree.
Needs a block.json
where the block is defined, blocks are saved in /data/content/_block/<block-id>
, where the folder /data/content/_block/
is added to the View/Templating system as the namespace content_block
.
A block needs to be added programmatically, like in _content.php
:
<?php
// Adds this block to index: /data/content/_block/intro/block.json
$content->addBlock('intro');
Block Types
Different types of blocks are relying on different type of data, e.g. meta
can only receive information which is saved for the meta of the current article.
Types are:
- meta
- mainText
- block
Created | Last Update