What would cause page.url to suddenly stop working?

Generating A-Z lists of links to child pages (of the current page) - Antimatter theme - worked as expected, AT FIRST. Now, suddenly, the p.title property works fine but p.url is garbled in a way that GRAV is unable to follow its own-generated route.
As in:

<li><a href = "{{ p.url }}">{{ p.title|e }}</a></li>

outputs e.g.: …href = “%7B%7B%20p.url%20%7D%7D”…

The same thing happens if I try using: p.route.

Thanks to anyone who can explain the issue and the remedy here.

hi, @boatful just a guess, try
{{ p.url|e }}
and check in the admin panel Configuration > Twig Templating > Autoescape variables

@b.da, I don’t think that can be it, because "%7B%7B%20p.url%20%7D%7D" is the escaped value of "{{ p.url }}" and not the escaped value of p.url.

@boatful, Curious about:

  • what has changed and
  • where the snippet ‘lives’. Inside markdown of page, or in Twig, or…

In a page (typically a page with many children), looping through the child page list in a specified order.

Interestingly I can assign (write) p.url to any other property of the <a> tag, for example a data-url property, and the twig reference to p.url is displayed correctly.

ok @pamtbaau, got it, yep that was a first guess, since one var contains an escape filter (and is processed), the other doesn’t

that would be my second step :wink:

This is my first brush with GRAV. Possibly this stopped working as usual after switching themes briefly from antimatter to quark and back to antimatter again.

The following js/jQuery hack gets the job done. Ain’t pretty but it fixes the problem:

    <!-- FAIL <li><a href = "{{ p.url }}">{{ p.title|e }}</a></li> FAIL -->
		<a onclick = "const gotoChild = $(this).data('p-route');window.location.assign(gotoChild);return false;" class = "gotoChild" data-p-route = "{{p.route}}" href = "#">

Detective work:

Locally (WAMP server) two installed plugins were fully updated during this time:

  1. the forms plugin
  2. the flex-objects plugin

The other modified SINGLE FILE in the shortcode-core plugin is:

Lastly, locally during this time I installed

  1. Trilby’s page-toc plugin and
  2. a plugin named snipcart

Given that my {{ p.url }} links are still intact on my remote/testing site, is it possible that one or the other of these plugin updates could produce this bug?

You are 100% correct. When I ask twig to loop over some page collection and generate <a> links to each child/descendent/post in HTML, twig will commit the {{ p.url }} value to ANY OTHER ATTRIBUTE of the <a> element, such as …data-url=“{{ p.url }}…” HOWEVER NOT THE HREF ATTRIBUTE:

<a data-url="/ical/2023/0128_pool-session"
href="%7B%7B%20p.url%7Craw%20%7D%7D">Pool Session #1</a>

Using a filter like |raw or |urlencode is ignored. I tried twig string interpolation to solve the problem but that too produces the output in HTML shown above.

Is there perhaps some other twig filter I could/should be using to commit a {{ … }} value to the <a href=“…”> attribute?

Again, I came up with the following site-wide workaround for this using js/jQuery, saved to a file I named: repair_urls.js

           provided all twig loops over any page collection
           assign the p.url value to BOTH the href attribute of <a>
           as well as an attribute deliberately named: data-url
            let goChild = $(this).data("url");
            return false;

To re-enable bastardized links generated by twig that SHOULD point to the URL or route of each page in a collection (BUT DON’T) we simply overwrite/correct the href attribute using the intact value in data-url (once the page is fully loaded).

Here’s how it looks to twig:

    {% for p in pages %}
                    <a data-url='{{ p.url }}' href="{{ p.url }}">{{ p.title }}</a>
                   {{ p.header.event.start|date('l F jS, Y', 'America/New_York') }}
                    From: {{ p.header.event.start|date('g:ia', 'America/New_York') }}
                    To: {{ p.header.event.end|date('g:ia', 'America/New_York') }}
                    {{ p.header.event.location }}
    {% endfor %}

@boatful, You haven’t provided much context, so I’ve been trying to figure out what’s happening. I can finally reproduce the issue when using the following:

  • Installed plugin page-toc
  • Inside page typography.md, I have the following
    title: Typography
        items: '@root.pages'
        twig: true
    {% for page in page.collection %}
        <a href="{{ page.url }}">{{ page.title }}</a>
    {% endfor %}
  • The HTML generated by the Twig snippet is as follows:
    <a href="%7B%7B%20page.url%20%7D%7D">Home</a>
    <a href="%7B%7B%20page.url%20%7D%7D">Typography</a>

It’s clearly an issue introduced by plugin page_toc and the issue has been reported before in June 2022 but hasn’t received much attention (yet).

You might consider a separation of concerns and generate the Toc and the url list outside Markdown in their own reusable partial templates. In my view, Markdown in default.md is content, and a list of pages and toc are meta data.

Perhaps using twig_first: true is the remedy. Twig WAS outputting <a href=“%7B%7B%20page.url%20%7D%7D”>…</a> on a page of mine that loops over a collection of pages using:

        taxonomy.type: event

Then, when I added to the frontmatter:

title: Events
twig_first: true

the values ascribed to the href properties in the output reverted to usable/expected/root-relative links:

<a href="/ical/2023/0128_pool-session">Pool Session #1</a>

Meanwhile, the plugin page_toc remains enabled. This may not be “best practice” for other reasons, but it worked in this instance.

@boatful, In that case, your use-case (which is still unclear to me) is different from the one I described above, because in my case twig_first: true resulted in anchors wrapped in a code block as follows:

<pre><code>&lt;a href="/"&gt;Home&lt;/a&gt;
&lt;a href="/typography"&gt;Typography&lt;/a&gt;</code></pre>

Anyway, the good news is that your use-case seems to be solved.