Working on menu, pager and helpers

This commit is contained in:
Bob den Otter
2019-08-24 14:23:41 +02:00
parent c0e6c4ebb7
commit 8fcd049318
11 changed files with 156 additions and 84 deletions
+9 -1
View File
@@ -11,6 +11,7 @@ use Bolt\Configuration\Parser\ContentTypesParser;
use Bolt\Configuration\Parser\GeneralParser;
use Bolt\Configuration\Parser\MenuParser;
use Bolt\Configuration\Parser\TaxonomyParser;
use Bolt\Configuration\Parser\ThemeParser;
use Psr\SimpleCache\CacheInterface;
use Symfony\Component\Stopwatch\Stopwatch;
use Tightenco\Collect\Support\Collection;
@@ -108,11 +109,18 @@ class Config
$menu = new MenuParser($this->projectDir);
$config['menu'] = $menu->parse();
// If we're parsing the config, we'll also need to pre-initialise
// the PathResolver, because we need to know the theme path.
$this->pathResolver = new PathResolver($this->projectDir, [], $config->get('general')->get('theme'));
$theme = new ThemeParser($this->projectDir, $this->getPath('theme'));
$config['theme'] = $theme->parse();
// @todo Add these config files if needed, or refactor them out otherwise
//'permissions' => $this->parseConfigYaml('permissions.yml'),
//'extensions' => $this->parseConfigYaml('extensions.yml'),
$timestamps = $this->getConfigFilesTimestamps($general, $taxonomy, $contentTypes, $menu);
$timestamps = $this->getConfigFilesTimestamps($general, $taxonomy, $contentTypes, $menu, $theme);
return [
DeepCollection::deepMake($config),
+26
View File
@@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace Bolt\Configuration\Parser;
use Tightenco\Collect\Support\Collection;
class ThemeParser extends BaseParser
{
public function __construct(string $projectDir, string $path, string $filename = 'theme.yaml')
{
$this->path = $path;
parent::__construct($projectDir, $filename);
}
/**
* Read and parse the theme.yml configuration file.
*/
public function parse(): Collection
{
$theme = $this->parseConfigYaml($this->path . '/theme.yaml', true);
return new Collection($theme);
}
}
+5
View File
@@ -53,6 +53,11 @@ class TwigAwareController extends AbstractController
// Set User in global Twig environment
$parameters['user'] = $parameters['user'] ?? $this->getUser();
// if theme.yaml was loaded, set it as global.
if ($this->config->has('theme')) {
$parameters['theme'] = $this->config->get('theme');
}
$this->setThemePackage();
$this->setTwigLoader();
+5 -5
View File
@@ -59,7 +59,7 @@ final class FrontendMenuBuilder implements FrontendMenuBuilderInterface
private function setUris(array $item): array
{
$item['uri'] = $this->generateUri($item['link']);
[$item['title'], $item['uri']] = $this->generateUri($item['link']);
if (is_iterable($item['submenu'])) {
$item['submenu'] = array_map(function ($sub): array {
@@ -70,25 +70,25 @@ final class FrontendMenuBuilder implements FrontendMenuBuilderInterface
return $item;
}
private function generateUri(string $link = ''): string
private function generateUri(string $link = ''): array
{
$trimmedLink = trim($link, '/');
// Special case for "Homepage"
if ($trimmedLink === 'homepage') {
return $this->urlGenerator->generate('homepage');
return ['Home', $this->urlGenerator->generate('homepage')];
}
// If it looks like `contenttype/slug`, get the Record.
if (preg_match('/^[a-zA-Z\-\_]+\/[0-9a-zA-Z\-\_]+$/', $trimmedLink)) {
$content = $this->getContent($trimmedLink);
if ($content) {
return $this->contentExtension->getLink($content);
return [$this->contentExtension->getTitle($content), $this->contentExtension->getLink($content)];
}
}
// Otherwise trust the user. ¯\_(ツ)_/¯
return $link;
return ['', $link];
}
private function getContent(string $link): ?Content
+1 -1
View File
@@ -38,7 +38,7 @@ class FrontendMenuExtension extends AbstractExtension
return $this->menuBuilder->buildMenu($name);
}
public function renderMenu(Environment $twig, ?string $name = null, string $template = '_sub_menu.twig', string $class = '', bool $withsubmenus = true): string
public function renderMenu(Environment $twig, ?string $name = null, string $template = 'helpers/_menu.html.twig', string $class = '', bool $withsubmenus = true): string
{
$context = [
'menu' => $this->menuBuilder->buildMenu($name),
+10 -3
View File
@@ -9,6 +9,8 @@ use Bolt\Entity\Field;
use Bolt\Repository\TaxonomyRepository;
use Doctrine\Common\Collections\Collection;
use Pagerfanta\Pagerfanta;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Tightenco\Collect\Support\Collection as LaravelCollection;
use Twig\Environment;
use Twig\Extension\AbstractExtension;
@@ -24,9 +26,13 @@ class RecordExtension extends AbstractExtension
/** @var TaxonomyRepository */
private $taxonomyRepository;
public function __construct(TaxonomyRepository $taxonomyRepository)
/** @var Request */
private $request;
public function __construct(TaxonomyRepository $taxonomyRepository, RequestStack $requestStack)
{
$this->taxonomyRepository = $taxonomyRepository;
$this->request = $requestStack->getCurrentRequest();
}
/**
@@ -52,13 +58,14 @@ class RecordExtension extends AbstractExtension
return 'list_templates placeholder';
}
public function pager(Environment $twig, Pagerfanta $records, string $template = '_sub_pager.twig', string $class = 'pagination', string $theme = 'default', int $surround = 3)
public function pager(Environment $twig, Pagerfanta $records, string $template = 'helpers/_pager_basic.html.twig', string $class = 'pagination', int $surround = 3)
{
$context = [
'records' => $records,
'surround' => $surround,
'class' => $class,
'theme' => $theme,
'route' => $this->request->get('_route'),
'routeParams' => $this->request->get('_route_params'),
];
return $twig->render($template, $context);
+3 -1
View File
@@ -1,9 +1,11 @@
{# Sub-block for 'text' field such as 'text', 'textarea', or 'html' #}
{% block text_field %}
<div data-bolt-field="{{ field.name }}">
<{{tag}}>
{%- autoescape false -%}
{{ field.twigValue() }}
{%- endautoescape -%}
</{{tag}}>
</div>
{% endblock %}
@@ -31,7 +33,7 @@
{# HTML, Textarea, Text fields #}
{% if type in ['html', 'textarea', 'text'] %}
{% set tag = (field.name in ['title', 'name', 'caption', 'subject', 'heading']) ? 'h3' : 'p' %}
<{{tag}}>{{ block('text_field') }}</{{tag}}>
{{ block('text_field') }}
{% endif %}
{# Markdown fields #}
+29
View File
@@ -0,0 +1,29 @@
{% macro display_menu_item(item, loop) %}
{% if item.submenu %}
{% set class = 'navbar-link' %}
<div class="navbar-item has-dropdown is-hoverable">
{% else %}
{% set class = 'navbar-item' %}
{% endif %}
<a href='{{ item.link }}' {% if item.title is defined %}title='{{ item.title|escape }}'{% endif %}
class='{{ class }} {% if item.current %}current {% endif %}{% if item.class is defined %}{{item.class}}{% endif %} index-{{ loop.index }}{% if loop.first %} first{% endif %}{% if loop.last %} last{% endif %}'>
{% if item.label is defined %}{{item.label}}{% else %} - {% endif %}
</a>
{% if item.submenu %}
<div class="navbar-dropdown">
{% for submenu in item.submenu %}
{{ _self.display_menu_item(submenu, loop) }}
{% endfor %}
</div>
</div>
{% endif %}
{% endmacro %}
{% for item in menu %}
{{ _self.display_menu_item(item, loop, 'navbar-link') }}
{% endfor %}
-43
View File
@@ -1,43 +0,0 @@
{% if records.haveToPaginate|default() %}
{% set route = 'listing' %}
{% set routeParams = app.request.get('_route_params') %}
{# The Pagerfanta function allows you to configure what is paginated,
the theme (template) to use for it, as well as a number of other options.
See: https://github.com/whiteoctober/WhiteOctoberPagerfantaBundle #}
<div class="{{ class }}">
{{ pagerfanta(records, theme, {
'proximity': surround
}) }}
</div>
<div class="navigation text-center">
<ul class="pagination">
{% if records.hasPreviousPage %}
{% set p = routeParams|merge({page: records.previousPage}) %}
<li class="prev"><a href="{{ path(route, p) }}" rel="previous"><i class="fa fw fa-long-arrow-left"></i> Previous</a></li>
{% else %}
<li class="prev disabled"><span><i class="fa fw fa-arrow-left"></i> Previous</span></li>
{% endif %}
{% for i in 1 .. records.nbPages %}
{% if i == records.currentPage %}
<li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
{% else %}
{% set p = routeParams|merge({page: i}) %}
<li><a href="{{ path(route, p) }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
{% if records.hasNextPage %}
{% set p = routeParams|merge({page: records.nextPage}) %}
<li class="prev"><a href="{{ path(route, p) }}" rel="next">Next <i class="fa fw fa-arrow-right"></i></a></li>
{% else %}
<li class="next disabled"><span>Next <i class="fa fw fa-arrow-right"></i></span></li>
{% endif %}
</ul>
</div>
{% endif %}
+38
View File
@@ -0,0 +1,38 @@
{#
Predefined variables:
- `records`: The records to iterate over
- `route`: The name of the route, to use in `{{ path() }}`
- `routeParams`: Parameters to pass in to `{{ path() }}` to create the correct url
- `surround`: The amount of items to show around the 'current' one. "3" by default.
- `class`: The main CSS class to apply to the pager. "pagination" by default
#}
{% if records.haveToPaginate|default() %}
<ul class="{{ class }}">
<li>
{% if records.hasPreviousPage %}
{% set p = routeParams|merge({page: records.previousPage}) %}
<a href="{{ path(route, p) }}">Previous</a>
{% else %}
<a disabled>Previous</a>
{% endif %}
</li>
{% for i in 1 .. records.nbPages %}
<li>
{% set p = routeParams|merge({page: i}) %}
<a href="{{ path(route, p) }}" {{ (i == records.currentPage) ? 'class="current"' }}>{{ i }}</a>
</li>
{% endfor %}
<li>
{% if records.hasNextPage %}
{% set p = routeParams|merge({page: records.nextPage}) %}
<a href="{{ path(route, p) }}">Next page</a>
{% else %}
<a disabled>Next page</a>
{% endif %}
</li>
</ul>
{% endif %}
+30 -30
View File
@@ -1,43 +1,43 @@
{#
Predefined variables:
- `records`: The records to iterate over
- `route`: The name of the route, to use in `{{ path() }}`
- `routeParams`: Parameters to pass in to `{{ path() }}` to create the correct url
- `surround`: The amount of items to show around the 'current' one. "3" by default.
- `class`: The main CSS class to apply to the pager. "pagination" by default
#}
{% if records.haveToPaginate|default() %}
{% set route = 'listing' %}
{% set routeParams = app.request.get('_route_params') %}
<nav class="pagination {{ class != 'pagination' ? class }}" role="navigation" aria-label="pagination">
{% if records.hasPreviousPage %}
{% set p = routeParams|merge({page: records.previousPage}) %}
<a href="{{ path(route, p) }}" class="pagination-previous">Previous</a>
{% else %}
<a class="pagination-previous" disabled>Previous</a>
{% endif %}
{# The Pagerfanta function allows you to configure what is paginated,
the theme (template) to use for it, as well as a number of other options.
See: https://github.com/whiteoctober/WhiteOctoberPagerfantaBundle #}
<div class="{{ class }}">
{{ pagerfanta(records, theme, {
'proximity': surround
}) }}
</div>
<div class="navigation text-center">
<ul class="pagination">
{% if records.hasPreviousPage %}
{% set p = routeParams|merge({page: records.previousPage}) %}
<li class="prev"><a href="{{ path(route, p) }}" rel="previous"><i class="fa fw fa-long-arrow-left"></i> Previous</a></li>
{% else %}
<li class="prev disabled"><span><i class="fa fw fa-arrow-left"></i> Previous</span></li>
{% endif %}
{% if records.hasNextPage %}
{% set p = routeParams|merge({page: records.nextPage}) %}
<a href="{{ path(route, p) }}" class="pagination-next">Next page</a>
{% else %}
<a class="pagination-next" disabled>Next page</a>
{% endif %}
<ul class="pagination-list">
{% for i in 1 .. records.nbPages %}
<li>
{% if i == records.currentPage %}
<li class="active"><span>{{ i }} <span class="sr-only">(current)</span></span></li>
<a class="pagination-link is-current" aria-label="Page {{ i }}" aria-current="page">{{ i }}</a>
{% else %}
{% set p = routeParams|merge({page: i}) %}
<li><a href="{{ path(route, p) }}">{{ i }}</a></li>
<a href="{{ path(route, p) }}" class="pagination-link" aria-label="Goto page {{ i }}">{{ i }}</a>
{% endif %}
</li>
{% endfor %}
{% if records.hasNextPage %}
{% set p = routeParams|merge({page: records.nextPage}) %}
<li class="prev"><a href="{{ path(route, p) }}" rel="next">Next <i class="fa fw fa-arrow-right"></i></a></li>
{% else %}
<li class="next disabled"><span>Next <i class="fa fw fa-arrow-right"></i></span></li>
{% endif %}
</ul>
</div>
</nav>
{% endif %}