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: 12,499
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.

Hire 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: 5,218
Website GitHub

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: 5,218
Website GitHub

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: 12,499
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.

Hire Txp Builders – finely-crafted code, design and Txp

Offline

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

etc
Developer
Registered: 2010-11-11
Posts: 5,689
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: 5,218
Website GitHub

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,689
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: 5,218
Website GitHub

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,689
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: 12,499
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.

Hire 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: 5,218
Website GitHub

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,689
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

#13 2019-01-09 14:47:07

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 12,499
Website GitHub

Re: Act on article status in any context

Haha, post_populate sounds like some kind of 80s music movement you’d see referred in the Grauniad.

I agree that process isn’t broadly grokkable so if there is anything better, let’s consider it, but I seem to recall we brainstormed when the idea was first floated and couldn’t come up with anything back then either. Thinking caps on.

While I like the txp-process concept for brevity – if it can be implemented in a useful and logical (no surprises) way – I think the notion of using <txp:hide> remains a good one because you are essentially hiding the content from the parser, just until a certain processing stage. Hey, I wonder if this syntax works:

<txp:hide until="2"> ...
   // content only "seen" in second pass
</txp:hide>

It does still rely on people knowing there are multiple passes, though. And is "until=1" essentially redundant because it’s the same as not having the hide tag there at all? Or does its use mean it will only be processed in stage 1, and skipped in 2 onwards (if indeed there’s anything left to parse)?

EDIT: Also, if we rename the process attribute, does that impact the txp-process too? txp-until doesn’t seem quite as attractive.

When we nail this, should we expose “Number of parser passes” in our new (well, recently re-introduced) Advanced Prefs area?

Last edited by Bloke (2019-01-09 14:52:47)


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

Hire Txp Builders – finely-crafted code, design and Txp

Offline

#14 2019-01-09 16:12:39

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

Re: Act on article status in any context

IIRC, until was considered at some stage, but process has another special meaning: <txp:hide process /> (without any value) will parse the content, but not output the result:

<txp:hide process>
    <!-- some comment for dev only eyes -->
    <txp:variable name="param1" value="1" />
    <!-- another comment for dev only eyes -->
    <txp:variable name="param2" value="2" />
</txp:hide>

No, there would not be txp-until :-) And yes, until="1" is useless as is, but makes sense in until='<txp:possibly_one />'.

Not sure about the number of parser passes pref. Currently it’s 2, but we could set it to, say, 15 without much risk, because parsing stops anyway as soon as there is no more <txp:tags /> left.

Offline

#15 2019-01-09 16:59:48

Bloke
Developer
From: Leeds, UK
Registered: 2006-01-29
Posts: 12,499
Website GitHub

Re: Act on article status in any context

Makes sense we’d considered (and rejected) until already. I’ve slept since then.

Presumably then, without any process attribute, the contents of hide tags are truly invisible. ISTR in previous versions scratching my head because the page issued an error or warning due to a malformed tag construct inside a <txp:hide> block. I’d have to check now but I also think I saw such hidden tags at least mentioned in the tag trace. Might be wrong.

I honestly can’t think of anything better than process. Stumped.

And if it makes sense to ditch the hidden pref and increase the default number of passes without ill effect to the parsing speed, then go for it. Convention over configuration, FTW.


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

Hire Txp Builders – finely-crafted code, design and Txp

Offline

Board footer

Powered by FluxBB