15. Rutas por defecto
• /{content-type-plural} -> listado de contenidos
• /{content-type-singular}/{slug} -> detalle de
contenido
16. Rutas por defecto
/libros -> listado de contenidos de tipo libro
1. Si está configurado un archivo twig en el
listing_template para ese tipo de contenido, se usa este.
2. Si no, buscará el archivo libros.twig por convención
3. Si no, se buscará el parámetro listing_template en la
configuración general del config.yml.
4. Si no ha encontrado nada de lo anterior, utilizará el
archivo listing.twig.
17. Personalizando rutas
Las rutas por defecto para las páginas serían:
/pages/{slug_de_la_página}
Para que sean solamente el /slug_de_la_página configuraríamos en el routing:
ruta_de_páginas:
path: /{slug_de_la_página}
defaults:
_controller: ‘BoltControllersFrontend::record'
contenttypeslug: 'page'
contenttype: pages
22. {% include '_header.twig' %}
<article>
<h1><a href="{{ content.link }}">{{ content.title }}</a></h1>
{% if content.image!="" %}
<img src="{{ content.image|thumbnail(320, 240) }}">
{% endif %}
{{ content.body }}
Posted by {{ content.user.displayname }}
on {{ content.datecreated|date("M d, ’y")}}
</article>
{% include '_footer.twig' %}
23. {% for content in records %}
<h1><a href="{{ content.link }}">{{ content.title }}</a></h1>
{{ page.video.responsive }}
{{ page.geolocation.latitude }},
{{ page.geolocation.longitude }}
{% for content_related in content.related_contents %}
<h2>{{content_related.title}}</h2>
{% endfor %}
{% endfor %}
24. {% for content in records %}
<h1><a href="{{ content.link }}">{{ content.title }}</a></h1>
{% for image in content.slider %}
<a href="{{ image.filename|image }}">
<img src="{{ image.filename|thumbnail(100,100) }}">
</a>
{% endfor %}
{% endfor %}
25. Malas prácticas
Recuperar una página:
{% setcontent about = 'page/about' %}
{{ about.title }}
Recuperar las 4 últimas entradas de un contenido:
{% setcontent records = 'books/latest/5' %}
28. Live Editor
En la configuración se activa con:
liveeditor: true
En Twig basta con indicar de esta forma
<h1 data-bolt-field=“title">
{{ record.title }}
</h1>
30. Crear extensión
Las extensiones se basan son personalizaciones del
Bolt Extension Starter https://github.com/bolt/bolt-
extension-starter
composer create-project --no-install bolt/bolt-extension-starter <extensión>
31. namespace BoltExtensionYourNameExtensionName;
use BoltApplication;
use BoltBaseExtension;
class Extension extends BaseExtension
{
public function initialize()
{
$this->addCss('assets/extension.css');
$this->addJavascript('assets/start.js', true);
}
public function getName()
{
return "ExtensionName";
}
}
32. Añadir un filtro para twig
function initialize(){
$this->addTwigFunction(
'EUR2USD',
'convertEuroToUSD'
);
}
//en twig
{{ number|EUR2USD }}
33. Añadir un html a la vista
function initialize(){
$this->addSnippet(
'endofbody',
'<!-- un código HTML -->'
);
}
34. Añadir un html a la vista
startofhead - after the <head>-tag.
aftermeta - after the last <meta [..] >-tag.
aftercss - after the last <link [..] >-tag.
beforejs - before the first <script [..] >-tag.
afterjs - after the last <script [..] >-tag.
endofhead - before the </head>-tag.
startofbody - after the <body>-tag.
endofbody - before the </body>-tag.
endofhtml - before the </html>-tag.
afterhtml - after the </html>-tag.
39. class Extension extends BaseExtension{
public function __construct(Application $app)
{
parent::__construct($app);
$this->app[‘config']->getFields()->addField( new ColourPickField() );
if ($this->app['config']->getWhichEnd()=='backend') {
$this->app['htmlsnippets'] = true;
$this->app['twig.loader.filesystem']->prependPath(__DIR__."/twig");
}
}
public function initialize() {
$this->addCss('assets/colourpicker.css');
$this->addJavascript('assets/colourpicker.js', true);
}
public function getName()
{
return "colourpicker";
}
}
40. class ColourPickField implements FieldInterface{
public function getName()
{
return 'colourpicker';
}
public function getTemplate()
{
return '_colourpicker.twig';
}
public function getStorageType()
{
return 'text';
}
public function getStorageOptions()
{
return array('default'=>'');
}
}
41. {% set attr_opt = {
class: field.class|default(''),
name_id: key,
required: field.required|default(false),
readonly: field.readonly|default(false)
}%}
<fieldset class="colourpicker">
<div class="col-sm-12">
<div>
<label class="control-label">{{field.label|default(key)}}</label>
</div>
<select data-colourpicker {{ macro.attr(attr_opt) }}>
{% for key, value in field.values %}
{% set isSelected = (key == context.content.get(key|capitalize)) %}
<option value=“{{key}}"
{% if isSelected %} selected="selected"{% endif %}>
{{value}}
</option>
{% endfor %}
</select>
</div>
</fieldset>
48. i18n e i10n
• La i18n del contenido no se soporta por
defecto :(
• La i18n de la interfaz se consigue con una
extensión llamada labels https://github.com/bolt/
labels