View and Templates in Flood\Canal
Flood\Canal uses Twig as main template language. Content is defined as Twig enabled MarkDown, you could use Twig variables inside the .md content files.
How to install Canal:
composer create-project flood/canal-structure . -s DEV
Pre-installed in Canal, the component's template files could also be installed with:
composer require flood/canal-view
Turn on debug function for twig with setting
$option['debug'] = true
in config.php of Canal
Usage with Canal
This will explain and demonstrate how the view files are controlled with Canal and where you find what.
The project flood/canal-view just contains default template files. We will use those, but you could of cause build your own stack.
The logic is in flood/canal, the configuration is done in config.php of flood/canal-structure
Translating to folder structure:
All files of flood/canal-structure are located after installation in:
/*
/flow.php
/view/_meta.twig
Where composer installs flood/canal-view in
/vendor/flood/canal-view/
See also the default asset file structure.
Default Folders
This controls where Twig will look after files, use absolute paths. Twig has a fallback logic, it will always look from the first folder down and executes the first existing file found. Only when namespaces are applied this don't work, don't apply namespaces on the default/first entry. The content
namespace is for content files that have twig enabled MarkDown, this namespace should not be used within other templates.
See also the default content folder.
<?php
$frontend->path_view = [
getcwd() . '/view/',
getcwd() . '/vendor/flood/canal-view/src',
$frontend->content->path => 'content',
];
- the first one must be the default folder for your files
- when no key is defined, value will be used as namespace for that folder
{% extends '@namespace/default.twig' %}
evaluates to/some-dir/folder
- for usage of flood/canal-view logic, just copy the example above.
Entry Point
For the ease of this guide we will use the route/controller.response variant that is as example already in _route.php
.
You could set the template file from:
- all classes that extend
\Flood\Canal\Controller\Base
- through parameter of
response($tpl)
, overwrites property, executesrender($tpl)
- through parameter of
render($tpl)
, overwrites property - through property
$this->path_template
- through parameter of
In _route.php
this is the part I refer to:
<?php
$route->addList([
'about' => [
'path' => '/about',
'controller' => function ($frontend) {
$controller = new \Flood\Canal\Controller\Base($frontend);
return $controller->response('_meta.twig');
},
],
]);
The _meta
file, is in /view/_meta.twig
, this file only extends canal-view's default_content_plain.twig
, which is /vendor/flood/canal-view/src/default_content_plain.twig
.
In /vendor/flood/canal-view/src/
are multiple default_*
files, these are used to provide a simple way of deciding which layout is needed.
default.twig
: provides the main blocks and defines a few block basics, all otherdefault_*
files are extending this filedefault_content.twig
: full-width content layout, removes sidebarsdefault_content_plain.twig
: full-width content layout, removes sidebars, header, footer and other default blocks that are not content relateddefault_sidebar_both.twig
: layout with two sidebars and contentdefault_sidebar_left.twig
: layout the left sidebar and contentdefault_sidebar_right.twig
: layout the right sidebar and content
This is done by overriding the main base.twig
blocks with empty blocks.
Until now, no main structure or anything exists. The structure is build in canal-view's general/base.twig
. This has the main html markup, more is included through overwriting the blocks/creating block files.
In the default_
files the used blocks are including twig files. Only create those you use, e.g. for block content_begin
add content-begin.twig
as /view/block/content-begin.twig
. It will now automatically be displayed in the block.
default_content.twig
excerpt:
{% block content_begin %}
{% include 'block/content-begin.twig' ignore missing %}
{% endblock %}
The Canal view files aren't using namespaces in extends/include, giving you the possibility to simply overwrite them, even the base.twig
, just add a file with the same relative path in your view folder and this will be used.
Blocks
Blocks are defined in a way that most changes only require to add one or two blocks in the page template or adding a block file at all. They are completely nested and provide default contents and logic for the basic needed things most pages need. Some blocks are just designed to get content, if the implementation needs them. So no extra block or complex changes are needed, those blocks listed below as empty, user
.
head
The head provides different blocks for those parts which often need to be changed. They in complete are in the block head
:
<head>
{% block head %}
{# more blocks here #}
{% endblock %}
</head>
These blocks are available, in the order they are defined:
head_begin
empty, user blockhead_meta
defines charset, provides setting of meta keywords and titlehead_misc
empty, user blockhead_style
outputs the link to the css file, usesurl.asset
andfrontend.debug
to generate the route to a file namedstyle.css
orstyle.min.css
, makes usage ofhead.font
variablehead_js
empty at base, should contain needed JS file links, there is afoot_js
alsohead_end
empty, user block
At the most use cases only head_js
need to be used.
body
The body is surrounded by a block:
{% block body %}
<body class="body"{% if meta.lang %} lang="{{ meta.lang }}"{% endif %}>
</body>
{% endblock %}
And contains a lot of blocks containing blocks, take a look at the reference sheet or look for yourself, below are the most important explained.
Block Reference Sheet:
Decorator blocks:
body_start
: includesblock/body-start.twig
when exists and is meant for information banner/cookie notice etc.header_inside
: includesblock/header.twig
when exists, is meant for the page headerfooter_inside
: includesblock/footer.twig
when exists and is used as the page footerfooter_copyright
: includesblock/footer-copyright.twig
when exists and is used as the page copyright noticebody_end
: includesblock/body-end.twig
when exists and is meant for information banner/cookie notice etc.foot_js
: here should be added JS files and scripts which need to be embedded before</body>
Content blocks, they consist of groups of three:
sidebar_left_begin
: includesblock/sidebar-left-begin.twig
when existssidebar_left_inside
: includesblock/sidebar-left.twig
when existssidebar_left_end
: includesblock/sidebar-left-end.twig
when existscontent_begin
: includesblock/content-begin.twig
when existscontent_inside
: includesblock/content.twig
when existscontent_end
: includesblock/content-end.twig
when existssidebar_right_begin
: includesblock/sidebar-right-begin.twig
when existssidebar_right_inside
: includesblock/sidebar-right.twig
when existssidebar_right_end
: includesblock/sidebar-right-end.twig
when exists
Default values
Defaults that will be set
The base controller sets a few defaults, these are:
requestContext
: instance of Symfony RequestContext, e.g.{{ requestContext.getHost() }}
content
: instance ofFlood\Canal\Content\Content
, provides method for fetching the content and meta information about the current articlefrontend
: instance ofFlood\Canal\Frontend
, provides the active runtimematch
: result of the uri matcher, contains the result like which placeholders where set, the callback is also within, with which the controller was buildurl
: arrayasset
: the path to the asset folder, only not blocked folder/file accesshome
: link to the home page, it MUST exist a routehome
!generator
: instance of the UrlGenerator, easily generate with{{ generator.generate('id', {'article': 'value'}) }}
, the id is the key of the route in$frontend->route_list
, the second paramters will not be needed most times, only when using placeholders/parameters
Example
{{ url.asset }}
will print at default:
https://your-domain.tld/view/out/
All available variables
see the components Canal\View documentation
Fragments
Fragments are small code parts which are written for a dynamic use, the most need to get parameters.
They should be inserted with:
{% include 'fragment/some-fragment.twig' with {'key': 'val'} %}
PHP explanation
Setting Values
Getting a variable from your controller to the template is easy, just $this->assign('key',$value);
and you could access it with {{ key }}
.
Created | Last Update