Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#1 2019-01-08 17:26:32

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,250
Website GitHub

Act on article status in any context

I’m probably missing something again. Here’s what I’m trying to achieve:

  • Most (not all) site Sections are a collection of Live articles, with a single Sticky that acts as an index page.
  • The sticky article is shown on /section URLs, with the exception of the front page and a few other sections that don’t require one.
  • The /section/title URLs show individual articles as usual.
  • At the top of the Page template – above <head> I’m pulling in a Form called variables that sets up a few things used later in the pages – including in the HTML <title> tag.
  • One such thing is the notion of a “Secondary title” (Custom field). If an article has one of these set, then it’ll use it in some places, otherwise it uses the regular <txp:title>.

I want to set this variable when BOTH live and sticky articles are encountered, so that I can display the secondary title on sticky article pages as well as regular articles. How do I test – before any <txp:article> tag has been reached – whether the page contains either a regular article or a sticky article?

I can’t use <txp:if_individual_article> or <txp:if_article_list> because they test the URL to determine if the page is one or the other. And the URL is misleading because /section URLs assume List Context (not Article Context), but in this case they sometimes display a sticky article, and sometimes they don’t.

I can’t omit any form of ‘article context check’ because otherwise I get tag errors when I land on a regular /section link that doesn’t contain a sticky article.

I can’t put an exploratory <txp:article(_custom) pgonly> tag at the top before calling the variables Form, as that affects pagination.

In pseudo code, I kinda want:

Is this page an individual article?
   Get secondary title if set, otherwise get title
Else
   Is this page a section landing page that has a sticky article in it?
      Get secondary title if set, otherwise get title
   Else
      Use nothing - not article context
End

Any ideas? Can I use <txp:hide process="..."> or <txp:evaluate>? Or do I have to resort to a custom query? If so, can I make it into a ‘conditional’ shortcode tag like <txp::if_article_context> check custom field/title...</txp::if_article_context>?

Last edited by Bloke (2019-01-08 17:32:11)


The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

#2 2019-01-08 17:59:57

jakob
Admin
From: Germany
Registered: 2005-01-20
Posts: 4,578
Website

Re: Act on article status in any context

Would not your pseudo-code example translate into regular txp code in your variables form? It just comes at the expense of another query, right?

Other ideas:

  • If your sticky article is always pretty simple, e.g. just the body text, which it might be for an intro text, then you could do your <txp:article status="sticky" limit="1">…</txp:article> in your variables form and store the respective output of the title, secondary title and body tags in variables for using later on down the page.
  • IIRC, one of the rah_meta/s plugins allows you to specify the meta_title tag based on content that you only output further on down in the page.

TXP Builders – finely-crafted code, design and txp

Offline

#3 2019-01-08 18:08:59

jakob
Admin
From: Germany
Registered: 2005-01-20
Posts: 4,578
Website

Re: Act on article status in any context

Maybe an alternative to your structure – but still at the expense of another query – might be to do:

<txp:variable name="sticky_found">0</txp:variable>

<txp:article status="sticky" limit="1">
   <txp:variable name="page_title"><txp:title no_widow="0" /><txp:variable>
   <txp:variable name="page_sub_title"><txp:custom_field name="secondary_title" /><txp:variable>
   <txp:variable name="sticky_found">1</txp:variable>
</txp:article>

<txp:if_variable name="sticky_found" value="0">
    <txp:article limit="1">
       <txp:variable name="page_title"><txp:title no_widow="0" /><txp:variable>
       <txp:variable name="page_sub_title"><txp:custom_field name="secondary_title" /><txp:variable>
   <txp:article>
</txp:if_variable>

<txp:variable name="meta_title"><txp:variable name="page_sub_title" /></txp:variable>
<txp:if_variable name="meta_title" value="">
   <txp:variable name="meta_title"><txp:variable name="page_title" /></txp:variable>
</txp:if_variable>

maybe enclosing the second txp:article in an if_individivual_article if you are worried about it getting the first article on a list page that has no intro article…


TXP Builders – finely-crafted code, design and txp

Offline

#4 2019-01-08 22:55:27

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,250
Website GitHub

Re: Act on article status in any context

Thanks for the thoughtful answers. Yes, my pseudo code would translate to PHP, I just wanted to try and avoid doing that unless I had to. Wondered if there was some clever way to handle this using native tags instead.

Using the article tag to set the thing would need to be done above the <head> so I can use the value in the <title> tag. I guess it probably can’t damage any pagination because it always hits that article sticky tag first anyway – even in my regular page flow. So I could just call that up top, do the assignment as you suggest: capture the various output of the sticky article itself in variables that I could display later, to save calling it twice.

Might try that as it seems the most sensible route, thank you.


The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

#5 2019-01-09 08:11:04

etc
Developer
Registered: 2010-11-11
Posts: 5,028
Website GitHub

Re: Act on article status in any context

You can go other way if you prefer, schematically like this:

<txp:hide process="2">
    <txp:variable name="postponed" />
</txp:hide>
...
<txp:variable name="postponed" value="whatever" />

Offline

#6 2019-01-09 11:26:30

jakob
Admin
From: Germany
Registered: 2005-01-20
Posts: 4,578
Website

Re: Act on article status in any context

Hi Oleg, Your examples are always tantalising but I don’t always get them entirely. I’d like to understand this <txp:hide process="{x}"> construction better.

So, does your example mean you could do:

<head>
    ...
    <txp:hide process="2">
        <title><txp:variable name="browser_title" /></title>
    </txp:hide>
    ...
</head>
<body>
    ...
    <txp:article status="sticky" limit="1">
        ...
        <txp:if_custom_field name="page_sub_title">
            <txp:variable name="browser_title"><txp:custom_field name="page_sub_title" /></txp:variable>
        <txp:else />
            <txp:variable name="browser_title"><txp:title no_widow="0" /><txp:variable>
        </txp:if_custom_field>
        ...
    </txp:article>
    ...
    <!-- ditto for for live txp:article etc. -->
    ...
</body>

i.e. putting a variable in place where you need it but only populating it further down the page?

What do the values for process mean?


TXP Builders – finely-crafted code, design and txp

Offline

#7 2019-01-09 11:33:48

etc
Developer
Registered: 2010-11-11
Posts: 5,028
Website GitHub

Re: Act on article status in any context

Hi Julian,

yes, we could do this. Recall that txp parses pages twice (by default). <txp:hide process="2" /> means “leave this block untouched until the *2*nd pass”. So your variables would be set on the first pass and output on the second one.

Offline

#8 2019-01-09 11:38:28

jakob
Admin
From: Germany
Registered: 2005-01-20
Posts: 4,578
Website

Re: Act on article status in any context

Excellent: that’s potentially really useful, but I wouldn’t have guessed it without you pointing that out.

Can you remind us what happens on parse loop 1 and loop 2?
Also in which situations there are not two passes (you wrote “by default”).

Maybe I can then make a tip out of that?

(edit: this is a bit like how rah_meta(s) worked too, although if I recall correctly it buffered the output to do that)


TXP Builders – finely-crafted code, design and txp

Offline

#9 2019-01-09 11:53:37

etc
Developer
Registered: 2010-11-11
Posts: 5,028
Website GitHub

Re: Act on article status in any context

That was @makss idea that I have implemented in core about 2 years ago. The workflow is the following. Suppose your page is just that. After the first parser pass we get

<head>
    ...
    <txp:hide process="2">
        <title><txp:variable name="browser_title" /></title>
    </txp:hide>
    ...
</head>
<body>
    ...
    Processed article (just some text now), with variables populated and stored in global variable array.
    ...
    <!-- ditto for for live txp:article etc. -->
    ...
</body>

Global variable is still set between two passes. On the second pass <txp:hide process="2" /> parses and outputs its content, so we get

<head>
    ...
        <title>Value of "browser_title" variable</title>
    ...
</head>
<body>
    ...
    Processed article (unchanged) ...
    ...
    <!-- ditto for for live txp:article etc. -->
    ...
</body>

The number of parser passes can be changed via a hidden preference (secondpass) would you need to alter the processing order even more.

Edit: actually, this can also be done as <txp:variable name="browser_title" txp-process="2" /> without wrapping it in hide, but this attribute is not (yet) intended for public use.

Offline

#10 2019-01-09 12:18:47

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 11,250
Website GitHub

Re: Act on article status in any context

That’s superb, Oleg. I’ll tinker with that concept and see how I get on, thank you.


The smd plugin menagerie — for when you need one more gribble of power from Textpattern. Bleeding-edge code available on GitHub.

Txp Builders – finely-crafted code, design and Txp

Offline

#11 2019-01-09 13:30:17

jakob
Admin
From: Germany
Registered: 2005-01-20
Posts: 4,578
Website

Re: Act on article status in any context

Brilliant. Would love to see (something like) this too:

<txp:variable name="browser_title" txp-process="2" />

That’s much less confusing-looking than txp:hide (but not always), but might it be possible to use another attribute name?

Putting on my “regular-user” hat, most users will have little to no idea of the inner workings of the parser. Unless there’s a good reason for explicitly using process (maybe there are other use cases I haven’t thought of), perhaps the attribute could have a more generally understandable name, like post_populate="1", fill="postpone" or populate="deferred" … maybe someone else has a better suggestion…


TXP Builders – finely-crafted code, design and txp

Offline

#12 2019-01-09 14:07:59

etc
Developer
Registered: 2010-11-11
Posts: 5,028
Website GitHub

Re: Act on article status in any context

I hope we’ll find a better name, but I would also like to improve the postponed processing itself. For example, in

<txp:some_tag txp-process="2" attr='<txp:another_tag />' />

<txp:another_tag /> would currently be parsed on both first and second passes, though it’s used only on the second one. Hiding avoids this problem:

<txp:hide process="2">
    <txp:some_tag attr='<txp:another_tag />' />
</txp:hide>

Offline

Board footer

Powered by FluxBB