picocms / Pico

Pico is a stupidly simple, blazing fast, flat file CMS.
http://picocms.org/
MIT License
3.83k stars 617 forks source link

Trigger plugin for certain page #440

Closed PulsarFX closed 6 years ago

PulsarFX commented 6 years ago

Is there a way to get the plugin handlers rolling when iterating over the pages in a twig? I have a plugin which loads images for a page.md into dedicated vars with onRequestFile.

So I'd like to show a teaser image in the pages list, like:

for page in pages 
   page.images[0] 
   page.title 
   page.description
endfor
PhrozenByte commented 6 years ago

I'm sorry, but I'm not sure what you're trying to do. What do you mean by "get the plugin handlers rolling"? What does your plugin do? What do you want it to do? Where can I find the plugin's source code? How does your content file look like? How does your Twig template do?

PulsarFX commented 6 years ago

What I want to achieve is, to put a teaser image to each entry of a blog list.


The image should be provided by the pico-pages-images plugin (https://github.com/nliautaud/pico-pages-images)

This plugin uses onPageRendering to add images to twig:

public function onPageRendering(Twig_Environment &$twig, array &$twigVariables, &$templateName)
    {
        $twigVariables['images'] = $this->images_list();
    }

so they can be accessed in the twig template like

{% for image in images %}
    <img src="{{ image.url }}" alt="{{ image.name }}" {{ image.size }}>
{% endfor %}

The code to get a list of blog style entries is from http://picocms.org/docs/#blogging

{% for page in pages %}
            <h3><a href="{{ page.url }}">{{ page.title }}</a></h3>
            <p class="excerpt">{{ page.description }}</p>
{% endfor %}

I am looking for a way to get the image part into this loop ;-) so I can write like

{% for page in pages %}
            <h3><a href="{{ page.url }}">{{ page.title }}</a></h3>
            <img src="{{ page.images[0].url }}">    <<<<------- image I want to get
           <p class="excerpt">{{ page.description }}</p>
{% endfor %}
PhrozenByte commented 6 years ago

The plugin only loads images of the current page, what is IMO pretty reasonable because it has a significant performance impact. Anyway, since it looks like you won't need the metadata provided by the plugin anyway, I'd suggest to simply not use this plugin. Add a teaser meta variable to your YAML Front Matter and use that meta variable in your Twig template.

---
title: My first blog post
description: This is my first blog post.
teaser: assets/first-blog-post-image.png
---

%meta.description%

Isn't this great?
{% for page in pages %}
    <h3><a href="{{ page.url }}">{{ page.title }}</a></h3>
    {% if page.meta.teaser %}<img src="{{ base_url }}/{{ page.meta.teaser }}" alt=""/>{% endif %}
    <p class="excerpt">{{ page.description }}</p>
{% endfor %}
PulsarFX commented 6 years ago

hmm, this would make images static. At the moment I just need to drop them into the content folder next to the md file, and the plugin will pick it up (I added some modification so the plugin looks for images with the file name pattern, like filename.*\.jpg, which will find i.e. filename.001.jpg filename.002.jpg ...

Is there a way to call a plugin manually from inside a plugin? Or would it be easier to rewrite the plugin so that it would go with the onPagesLoaded event?

PhrozenByte commented 6 years ago

It would be easier to rewrite the plugin. However, I definitly don't recommend this because it has a significant negative performance impact.

PulsarFX commented 6 years ago

ok, thanks for your advice. I'll give it a go, the system is small (60 pages atm) and runs from a ssd, because why not ;-)