Open KennethJoris opened 6 years ago
I made a small twig pagination that works with the Grav Collection Methods:
Example:
{% set collection = page.collection({
'items': '@self.children',
'pagination': true,
'order': {'by': 'title'},
'limit': 2})
%}
{% set itemsInCollection = page.collection({'items': collection.params.items})|length %}
{% set itemsPerPage = collection.params.limit %}
{% set pagesInCollection = (itemsInCollection / itemsPerPage)|round(0, 'ceil') %}
{% set currentPage = uri.param('page')|default('1') %}
<ul class="pagination">
{% for i in range(1, pagesInCollection) %}
<li {% if currentPage is same as('' ~ i ~ '') %} class="currentpage" {% endif %}>
<a href="{{ page.url ~ '/page' ~ system.param_sep ~ i }}">{{ i }}</a>
</li>
{% endfor %}
</ul>
{# Render the list of blog posts (automatically filtered when using pagination) #}
{% for child in collection %}
{{ child.title }} <br>
{% endfor %}
This problem takes a lot of my time at the moment. When I look inside the grav-skeleton-blog-site
the pagination param is a \Grav\Plugin\PaginationHelper
, in the flow of my templates it is only a boolean = true. I tried calls like do paginate( collection, limit )
like described in the README. This should do the magic, it calls paginateCollection
in grav-plugin-pagination/pagination.php
, which overwrites the pagination
param with a \Grav\Plugin\PaginationHelper
and slices the collection. The call does not work for me at the moment, I will investigate more. It is rather confusing, that a parameter is changed to another type and meaning, why not use another name?
Also I don't know where it is done in the blog skeleton. Any advice appreciated.
I think I found the reason. In the grav-skeleton-blog-site
the preparation of the collection is done by the onCollectionProcessed
-event, but, as I suppose, only for the default collection, not for another defined collection.
So the call to do paginate()
is essential, but really not working.
The reason is: the version 1.3.2 installed by bin/gpm install pagination
is different from the version 1.3.2 installed by the zip. The twig folder is missing and the onTwigExtensions
-event not registered. Also blueprints.yaml, README.md and other files are different.
When I install from ZIP, do paginate()
does it's job.
I'm having the same problem using v1.4.1
. I tried installing using gpm and zip (which was the same version).
The collection.params.pagination
never gets the "magic", just remains true
.
I figured out my proglem. I was including limit
in my collection()
call.
If I exclude the limit from my collection
parameters and only pass what my limit
is do the do paginate(collection, limit)
it works as expected.
If I exclude the limit from my collection parameters and only pass what my limit is do the do paginate(collection, limit) it works as expected.
can you explain this please?
I cannot find the way to get this strange unusable plugin work
I have exactly the same problem as @Genenenenaam and tried the do paginate( collection, limit )
as @tremel did : but I have a blank paginator, in raw HTML, without pages to paginate.
I tried again with excluding the limit:
from the frontmatter as @grantholle suggested, and this time, I have a Crikey error :
So it seems that the plugin is totally broken (no rendering + no CSS loaded in the assets in the <head>
).
Hello,
There is an issue with the pagination plugin, if you have a collection to has less items than the limit, you get empty pagination instead of not getting a paginator at all. The reason is the pagination variable is initialized to true, and then never changed to an empty array. There the pagination|length gives 4 because it counts the number of letters in the word true instead of counting an empty array.
There are 2 ways to fix this issue on line 124 of file pagination.php.
Solution 1: set the pagination variable to an empty array instead of true
$collection->setParams(['paginationEnabled' => array()]);
Solution 2: don't set the pagination variable unless there is enough item and instead to show there is pagination activated but not enough item to paginate set a variable called paginationEnabled to true.
$collection->setParams(['paginationEnabled' => 'true']);
Solution 1 makes has my preference.
Regards, Numa
How about a pull request?
Hi, I come back here to give more infos on what I discovered about the bugs. I'm not familiar with GIT pushes, and anyway I didn't find any PHP fixes, so it's pure workaround and good practice here :+1: . I just dump that, as a memo for further documentation edition.
1 - How to use the plugin correctly (conflict) 2 - Excerpt of a full template processing 3 - The problem with modular pages 4 - Insights of the PHP, for possible fixes
In short : there's two way of calling the plugin in a page, and we can't use both or it will conflicts !
The plugin necessitate two things :
pagination: true
field in the frontmatter. {% include... %}
of the plugin's template in order to insert it and to use what it has generated during the PHP page processing (due to any presence of its activation in a page).And it allows one thing :
{% do paginate() %}
, in order to tweak some variables.content:
pagination: true
limit: [integer]
{% do paginate() %}
.content:
pagination: true
limit:
field.{% do paginate() %}
.{% do paginate() %}
so its use is only triggered when the limit:
field is absent.{# *** Collection preprocessing *** #}
{% if page.collection %}
{% set collection = page.collection() %}
{% set limit = page.header.content.limit ?: '5' %}
{% else %}
{% set limit = '5' %}
{% set collection_options = { items: {'@page.children': page.url}, 'limit': limit, 'order': {'by': 'date', 'dir': 'desc'}, 'pagination': true } %}
{% set collection = page.collection(collection_options) %}
{% endif %}
{# *** /Collection preprocessing *** #}
{% if config.plugins.pagination.enabled and collection.params.pagination and not page.header.content.limit %}
{% do paginate(collection, limit) %}
{% endif %}
{% for item in collection %}
... Things to display the items...
{% endfor %}
{% if config.plugins.pagination.enabled and collection.params.pagination %}
{% include "partials/pagination.html.twig" with {'base_url':page.url, 'pagination':collection.params.pagination} %}
{% endif %}
Modular page are rendered differently, and some things can be impossible to reach in the PHP during the events.
So, because of this, the presence of a frontmatter pagination
field is just checked during the WHOLE page processing _( meaning, the parent page that a modular can have !) but not during the processing of the modular_ sub-page. Consequently, the pagination plugin doesn't find the frontmatter field, and doesn't load the CSS wich results in a raw <ul>
!
So as a solution, just load manually the asset in your template that extends the base.html.twig
, by rewritting any {% block %}
that would have been created (or that you can create) around the assets.css()
in the header of the base.html.twig
.
{% block assets %}
{{ parent() }}
{% do assets.addCss('plugin://pagination/css/pagination.css') %}
{% endblock %}
Or directly in the base.html.twig
, add inside the header :
{% if page.route == "/your_page" %}
{% do assets.addCss('plugin://pagination/css/pagination.css', {'group':'workaround'}) %}
{% endif %}
{{ assets.css('workaround') }}
I've conditioned it to a route, and assigned it to a group for more control, but that's totally optional.
PaginationTwigExtension.php
.
new \Twig_SimpleFunction('paginate', [$this, 'paginateFunc']),
$pag->paginateCollection(...)
method.paginateCollection()
method does nothing bad : it just rewrites the limit:
field with the thing that it received as a $limit
argument. It's strange, maybe a loop, but why not. I first thought it was bugging here.onCollectionProcessed(Event $event)
method is triggered first. In it, we can find :
$this->pagination = new PaginationHelper($collection);
$collection->setParams(['pagination' => $this->pagination]);
'/classes/paginationhelper.php'
, there is a _construct in wich :
$params = $collection->params();
...
$this->items_per_page = $params['limit'];
$this->page_count = ceil($collection->count() / $this->items_per_page);
But I don't understand why it would make the plugin to bug. :thinking:
Anyway, it is clearly here, at this moment when the _pagecount is done, that the plugin fails if we have a set a limit:
field in the frontmatter !
I tried to set an integer, or between quotes ' '; but nothing works.
On a twig template i use the 'Collection Object Methods' to difine a collection like it states in the GRAV documentation:
I pass this data to the plugin 'pagination.html.twig' template.
Here i have my issue:
In the plugin template '' the first condition will therefore always return false.
Looking inside the plugin template its unclear to me what correct data is expected. And how to pass this through?