gantry / gantry5

:rocket: Next Generation Template / Theme Framework
http://gantry.org
1.03k stars 205 forks source link

display curent post content using twig (timber) in custom html particle #2741

Open jbonlinea opened 3 years ago

jbonlinea commented 3 years ago

Hi there,

The question might seems naive, but I've search on the documentation and on web and still couldn't find a working solution ?! So, on wordpress, how to display the current post content using twig (timber) in custom html particle

The most natural way I could think of was to :

-> On the front end, I do find my layout as I expect but {{ post.title }} is not returned, while Test: is indeed displayed.

In gantry5 setttings compile twig and compile yalm are checked

So now I wonder if one need to add a wp query in every single custom html particle, to get the curent post, and thus then be able to use timber/twig templating ? this seems super inefficient ! I gues it's not as I have checked how the content and the content array particle are built, and I clearly appears that the content particle do not do a custom query, this is actually the whole point !

Woud you kindly provide any guidance on how to best use twig code into custom html Thank's in advance

mahagr commented 3 years ago

Particles are insulated from the main content, but you can still access Timber by using the methods from Timber (see their docs).

jbonlinea commented 3 years ago

Hi there

Thank's for your reply :)

Yes I do have a basic understanding of twig template from a light experience of symphony, and do have studied the timber documentation.

Particles are insulated from the main content, but you can still access Timber by using the methods from Timber (see their docs).

Hum, what does particles are insulated exactly means ?

It suggest that particle do not kwow about, or can't get the current page querry ? and that if one want to display some current page field in a particle, the particle itself has to contain a query ?

If yes that's a bit surprising, but ok there may be good reasons, just wonder which, and if it is really optimal as it adds many db query for *nothing". Then I also wonder how do the "content" particle works, as I can't see any querry in the twig.

Thank's

mahagr commented 3 years ago

I mean that most particles are not and should not be aware of their surroundings. This is because usually, they do not need to, which is also optimization as it allows for better caching.

However, you can still get that information, though I am not really an expert in WP. I know there are particles that display page titles for example.

jbonlinea commented 3 years ago

Hi

Thank's for your reply.

Ok, performence wise, I do get why most particle do not, and should not be aware of the context.

however there are also very good reasons why some particles should be aware of the context.

Why : let gantry be a true dynamic page template builder

Gantry, in the wp universe,as far as I understand , is quite unique because

But I see a huge lack in gantry as it is now. While it can be used as a static page builder, it can't answer to the need of building dynamic page template !!!

So I can create outlines and assigned them, but all the content of the outline will be static, except the particle "Page content". But, event if using custom fields and post_meta limitlessly may be debatable, it is largely, extensively, I mean hugely use on WP.

If we can't get these post data with gantry, we need to do it anyway, thus end up using something else to do the job. For instance I'll use a "custom html" particle to place a shortcode inside. Example could be through the use of ACF shortcode, Pods shortcode, Custom Content shortcode, and many more...

Alternatively I could write twig in my html paricle, but as the particle is not aware of the context, I'll have to write the query. And I'll soon end up with a page where the main query is used by the content particles, and 3, 5 or 7 particle each doing the same query, but still 3, 5, or 7 times, to display one field ?!

Eu... do you see the absurdity ?

If I consider gantry as a theme builder, it's great, but if I regard gantry as a page template builder, for wp, it fails hard. It's like everything is there, but no.

Context aware particles.

Everything is here so let's use it !

I mean current page/post If I could, I would place a particle for title here, content there, custom field here... super easy, but no. build a page template, and use it, but no.

The solution (theoretically)

It apears that at least two particles, "Page content" and "system message", are aware of the context...

So why not have one more context aware particle, with an html field, in which we could type twig to get post_meta. With the context known, displaying the post title is as simple as {{ post.title }}, post ID would be {{ post.ID }}, post date {{ post.date }}... any custom field, for instance named myField, would be {{ post.myField }}... and as Timber is very well integrated with ACF and Gutemberg, so even advanced relationship or repeated field could be displayed form there.

A similar approach could be to have a particle with a select dropdown field, it would list all post and post_meta field available, you select one, it displays its content. We understand that it would be limited to text, number, date, and other text based field, but it's already a great advancement !

My research for the technical solution

Well I've seen that "Page content" and "system message" are not defined as "particle" but as "system" in their yalm file. ok why not.

Following that, I identified some difference between what I will name "particle-particle" and "system-particle", you may correct me where I'm wrong ;)

OK, ok,

from my testing it apears that wp-content/plugins/gantry5/engines/nucleus/templates/system.html.twig is context aware, while wp-content/plugins/gantry5/engines/nucleus/templates/particle.html.twig is not.

Ok ok

So what I need to do is to create a system-particle, let's say "context", but as the system.html.twig do only kwow about "content" and "message" I need to add one subtype. Here it is undefined as I don't know how to define the subtype

        {% else %}
            {% set class = 'g-system-context' %}
            {% include ['particles/' ~ segment.subtype ~ '.html.twig',
                       '@particles/' ~ segment.subtype ~ '.html.twig',
            '@nucleus/content/missing.html.twig'] %}

O let's build my context particle : here is the yalm

name: Context
description: Particle awere of the context to display dynamic content using twig.
type: system
icon: fa-file-text-o
hidden: false

form:
  fields:
    enabled:
      type: input.checkbox
      label: Enabled
      description: Globally enable page content.
      default: true

    html:
      type: textarea.textarea
      label: Custom HTML
      description: Enter custom HTML into here.
      overridable: false

    twig:
       type: input.checkbox
       label: Process Twig
       description: Enable Twig template processing in the content. Twig will be processed before shortcodes.
       default: '1'

    filter:
      type: input.checkbox
      label: Process shortcodes
      description: Enable shortcode processing / filtering in the content.
      default: '1'      

And the twig :

{% extends '@nucleus/partials/particle.html.twig' %} 
{% block particle %}
    What is my post title  : {{ post.title }}    <br>

    {% set html = segment.attributes.twig ? gantry.theme.compile(segment.attributes.html) : segment.attributes.html %}
    {{ (segment.attributes.filter ? gantry.platform.filter(html) : html)|html|raw }}

{% endblock %}

The twig of my context particle is now aware of the context ! Awesome, my particle displays my title !!! BUT The content of my html field of my particle is not !!! The twig inside the html field of my particle is processed, but it is not awere of the content ?!

What a boner !

Ok so I could create one context-particle for each "field" i want to display, but this is less flexible !

do you have any idea how to properly finish that ? Thank's

pplopx commented 3 years ago

I have the same need and am looking for a similar approach.

Why does the Page Content particle assume that I will want to display all the page content with it? I might want to disable it altogether to have the freedom to, for example, make a header within a full-width section with just the post title, its featured image and meta information. And in another section include only the content fitted to the box. And in another section with some highlighted colours to get the related posts thanks to the magic of Twig + Timber that would be aligned to the width of the container,...

It would be simple with a context-sensitive particle to get elements of the current post as proposed by @jbonlinea. Otherwise we would have to start coding in the template files, which means work for the experienced and newbies abandoning Gantry in search of other page builders that offer this implementation in a much simpler way.

As far as I know, there are NO particles that will fetch an element from the current post (e.g. title) and display it unless a new query is made. I've seen many and the more advanced ones like RT or Joomlead don't do it.

I expect the same answers...

jbonlinea commented 3 years ago

Writing this I think I of few things :

But hey, this is not ressource savy, so while preventing some particle to be context aware is savy, preventing all particles to be be aware of the context is sub-optimal by large.

And the only way I could do it as the prototype in my above post would require to edit one gantry core file, or override it in child theme, which not so nice to share widely especially for newbies...

and here we are again...

mahagr commented 3 years ago

Nothing prevents people from making more content-aware particles. In WP you can just use Timber to get whatever data you want from the site, there's nothing preventing people from making more particles that only render parts of the post.

The main issue (for someone who creates themes for multiple CMSes) is that you need to create and maintain custom particles for every platform as they all have very different ideas about what the content is supposed to look like. Also, Joomla does really not support content outside of its own context. That is likely why there aren't too many particles that are content-aware. They are really hard to get to work if you are developing a theme that is supposed to work on every platform.

CC @simmonsr

designzwang commented 2 years ago

@jbonlinea - I tried your example and created a particle from your yaml and twigfile, but without success. Using your example as it is ( "type: system" in the yaml file) , the particle is shown as a green system particle in the layout manager GUI, however the particle output is not rendered on the page. When I set "type: particle", the particle is shown as blue in the GUI, its output is rendered, but {{ post.title }} remains empty. @mahagr "there's nothing preventing people from making more particles that only render parts of the post." So - would you mind to help us out with an example how to achieve such a (seemingly) simple task like getting , for example, populating {{ post.WHATEVER }} in a particle's twig file? I can fetch a Post with Timber in PHP, but how would I do this inside a particle's twig file?

designzwang commented 2 years ago

@jbonlinea - oops, I edited a diffent copy of system.html.twig elsewhere in the file system, my bad. After editing the right one, your example works and I can use post.title and all the other post data. However, as you say, hacking the system.html.twig is not very sustainable - maybe @mahagr has a better idea how to get this done in the twig files....

designzwang commented 2 years ago

@jbonlinea - one final comment: according to https://docs.gantry.org/gantry5/advanced/file-overrides it is possible to override the plugin files by creating copies in the right place ... in my case (child theme of hydrogen) I copied wp-content/plugins/gantry5/engines/nucleus/templates/content/system.html.twig to wp-content/themes/g5_hydrogen_child/custom/engine/templates/content/system.html.twig and placed your additional code in the copied file. Gues what - it works. Since gantry supports a "custom" directory in the original theme folder, this could as well be done even without a child theme. So we seem to have a viable workaround ...

jbonlinea commented 2 years ago

hi

yes !

I've spend quite some time to make it work and I'm glad it may be usefull for you @designzwang

@mahagr : I understant that it wouldn't be doable for gantry team to develop a whole set of particle for every platforms. that actually why I took the road to create an only an simple "context" aware particle, and nothing more.

I don't know if I created it the right way, ganty wise, and if not I do not realise how much effort I would ask to includ such kind of particle in the wp distribution, but my very own opinion is that it would be a game changer for gantry.

If you want to get to me so we can tackle this the righ way, I'm more than willing to share and help with coding, testing, make a PR, etc.

Otherwise I may just publish my own context aware particle and offer it to download to gantry user from my own site, it may be more visible to user that are not into developement/github

Cheers

mahagr commented 2 years ago

@jbonlinea Please ping me after the holidays and we can take a look.