Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#1 2011-01-18 12:41:04

jsoo
Plugin Author
From: NC, USA
Registered: 2004-11-15
Posts: 1,793
Website

[howto] Textpattern: Context in depth

Such is the title of my latest article.

What started as an idea for a one-page article kept drawing me in further as I learned how much I didn’t know about the topic :) It now includes an opening section on theory, a multi-page demo section, and a brief reference section.

I learned a ton in the process, and have really refined my view on what context means in Txp. Agree or disagree, I’d love to hear your views.


Code is topiary

Offline

#2 2011-01-18 13:30:52

wet
Developer Emeritus
From: Schoerfling, Austria
Registered: 2005-06-06
Posts: 3,357
Website GitHub Mastodon

Re: [howto] Textpattern: Context in depth

To expand on the topic, we are not absolutely content with some bugs and the behaviour of certain edge cases relating to context.

So we’d probably have to revise our routing algorithm according to these rules for the next release:

  1. For all request parameters which indicate a route to a member of closed set, we throw a 404 status upon the occurrence of a request which cannot be served from our set. This is true for article ids, section names, fixed routes like /rss/ or /file_download/ et cetera.
  2. We serve content-less responses for non-satisfiable routes calling members of an open set (e.g. non-existent categories, ?q= search term not found).
  3. We silently ignore parameters we do not know how to handle (for instance, to let plugins handle things as http://example.com/?acb_plugin_var=foobar)
  4. We apply defaults. “default” is the default section, “article” is the default context, search is off, and so on.

I think that “context” falls into bin #1, and so we’d rather object from silently correcting requests for invalid contexts, but let either some plugin handle this, or fall through and throw a 404 otherwise.

If no context is specified in the request URL, we use the routing logic in publish.php to establish one and default to “article” if it is clear from the rest of the request (e.g. through the presence of
$id, $section or the components in the rest of the URL).

Offline

#3 2011-01-18 13:31:33

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

Re: [howto] Textpattern: Context in depth

Holy mackerel context, Batman. Awesome stuff.

I only now wish (as you note) that I’d read this article before I implemented the messy ?context= variable and used ?type= as you suggest. *sigh* hindsight/stupidity eh? Sorry.

One thing that caught my eye in terms of semantics was your use of front page. It makes a lot of sense to call it that because it is the front page of that particular section. From experience I tended to initially receive blank stares when I explained that to clients because ‘front page’ to them is what we might term the ‘index page’, i.e. the root, domain-level entry point (well, either that or they think I’m referring to software by Micro$oft for authoring bloated and impossible to maintain web sites).

Over time I’ve trained myself during sales/documentation pitches to use front page for just the domain’s (sectionless) index page, and landing page for the head of any section (i.e. a section without an article on it / a URL with just a section in it; usually the article list, unless overridden with something clever). It makes it easier for me to say that one can ‘land’ on any section, see what’s there in the list and then ‘jump’ off to pages within that section when using the article tag. Or some such allegorical nonsense.

[ btw, I’m not suggesting you change the article to accommodate my whimsical naming strategy or anything, just offering counterpoint ]

That’s a masterpiece of documentation and I implore — nay demand — you link to it from the wiki in the Orientation or Tutorials pages. Superb.


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

#4 2011-01-18 13:52:32

jsoo
Plugin Author
From: NC, USA
Registered: 2004-11-15
Posts: 1,793
Website

Re: [howto] Textpattern: Context in depth

Bloke wrote:

I only now wish (as you note) that I’d read this article before I implemented the messy ?context= variable and used ?type= as you suggest.

I’m not sure I would have had the idea to write the article in the first place, if not for the new contexty features in 4.3.0. So there.

Over time I’ve trained myself during sales/documentation pitches to use front page for just the domain’s (sectionless) index page, and landing page for the head of any section

I like it, will edit.

That’s a masterpiece of documentation and I implore — nay demand — you link to it from the wiki in the Orientation or Tutorials pages. Superb.

Very kind, sir. Will do somesuch thing.


Code is topiary

Offline

#5 2011-01-18 19:04:51

jsoo
Plugin Author
From: NC, USA
Registered: 2004-11-15
Posts: 1,793
Website

Re: [howto] Textpattern: Context in depth


Code is topiary

Offline

#6 2011-01-19 13:43:21

pieman
Member
From: Bristol, UK
Registered: 2005-09-22
Posts: 491
Website

Re: [howto] Textpattern: Context in depth

Wow. Destined to be a classic reference piece.

It enlightened me on lots of stuff I already knew how to use, but was never sure why things worked in a certain way. And like your image gallery demo, it’s brought some of the new tags to life for me.

(doffs cap)

Right, now I’ve buttered you up, can I slip in a couple of questions? They relate to the way you’ve built the tutorial itself, rather than the code examples you’ve offered.

These two URLs display different images, but the same text:
http://ipsedixit.net/context_demo/?p=23
http://ipsedixit.net/context_demo/?p=24

This URLs however, displays a different image, but also different text to the others:
http://ipsedixit.net/context_demo/?p=53

What is the context that determines the written content?

Likewise, in a non-article category context…

…where is the text pulled from, and how? Do you have conditionals in your page template than serve named article IDs according to named image category context? eg.

<txp:if_category type="image" name="stasis"><txp:article_custom id="xx" /></txp:if_category>

Offline

#7 2011-01-19 14:05:00

jsoo
Plugin Author
From: NC, USA
Registered: 2004-11-15
Posts: 1,793
Website

Re: [howto] Textpattern: Context in depth

Thanks Stuart :)

The demo section is of course intended to demonstrate standard Txp contexts and their uses. The code behind it, however, is anything but standard Txp. For the global image URLs you show, the text is in a sticky article, and that article has a conditional to check which image is showing. Same for the image-category and link-category contexts: sticky article containing a conditional.

There’s lots more fun stuff behind the demo section, and I may get around to posting a fuller explanation at some point.


Code is topiary

Offline

#8 2011-01-19 14:10:17

pieman
Member
From: Bristol, UK
Registered: 2005-09-22
Posts: 491
Website

Re: [howto] Textpattern: Context in depth

Ok, thanks. That makes perfect sense :-)

Offline

#9 2011-01-20 20:31:13

maniqui
Member
From: Buenos Aires, Argentina
Registered: 2004-10-10
Posts: 3,070
Website

Re: [howto] Textpattern: Context in depth

Great set of articles, tutorials and demos, Jeff. Far more better than one of the first tries at trying to grasp this concepts. ;)
Thanks.

There is one example that made some noise in my brain.

<ul>
    <li>
        Current section: <b><txp:section /></b><br />
        (from global section context)
    </li>
    <txp:section_list sections="info">
        <li>
            Current section: <b><txp:section /></b><br />
            (from <code>section_list</code> context)
        </li>
        <txp:article_custom section="txp" limit="1">
            <li>
                Current section: <b><txp:section /></b><br />
                (still from <code>section_list</code> context,
                despite local article context)
            </li>
        </txp:article_custom>
    </txp:section_list>
    <txp:article_custom section="txp" limit="1">
        <li>
            Current section: <b><txp:section /></b><br />
            (now from local article context)
        </li>
    </txp:article_custom>
</ul>

produces this output:

Current section: context_demo
(from global section context)
Current section: info
(from section_list context)
Current section: info
(still from section_list context, despite local article context)
Current section: txp
(now from local article context)

I’d have bet that the section tag inside the article_custom tag would have returned the name of current article’s section (txp), not the name of current iteration on outer section_list.
In fact, I find it quirky to not be so: it means that I can’t output which section the current article belongs to.
And thus, somehow breaks the concept of local context, that is, the context set by the more nested wrapping tag (article_custom in the example above).

Now, I get why I didn’t noticed before this quirky behavior. Because your example, although a good one, it’s a bit… unreal.
We will have to find a real use case for iterating over a section_list, while in the inner iteration you have some harcoded stuff (txp in article_custom)

This is, imho, a more real use case, which, in the end, hides the quirky behavior:

<txp:section_list sections="a, b, c">
  Section: <txp:section /><br />
  <txp:article_custom section='<txp:section />' limit="1">
  This article belongs to section: <txp:section /><br />
  </txp:article_custom>
</txp:section_list>

Which will output:

Section: a
  This article belongs to section: a 
Section: b
  This article belongs to section: b 
Section: c
  This article belongs to section: c 

The most inner section tag (inside article_custom) matches the currently iterated article section, making the output to look correct. But that’s correct just by coincidence, because, well, we now know that it’s rendering the value for current iteration of outer section_list, which is the value passed to section attribute of inner article_custom.

The consequence: you can’t access the real value of section when inside an article/article_custom (local) context.

You may say: “ok, but how do I access to the value of section for an outer context?”. Well, I’m not programmer, but I think this is doable by creating/assigning a variable just before entering into an inner scope/context.

URL says we are browsing section: <txp:section /><br /> 
<!-- ^^ let's suppose this section is named "events" --> 
  <txp:variable name="section_by_url"><txp:section /></txp:variable>

  <txp:section_list sections="a, b, c">
    The section for current iteration of section_list is: <txp:section /> <br />
    But don't forget we are currently browsing section: <txp:variable name="section_by_url" /><br />

    <txp:variable name="section_by_section_list"><txp:section /></txp:variable> 
    <!-- ^^ this will take values 'a','b' and 'c' on each iteration -->

    <txp:article_custom section='<txp:section />' limit="1"> 
    <!-- ^^ here, txp:section still takes the value of its outer context, 
    that is, txp:section_list, that's ok, totally expectable -->

      This article belongs to section: <txp:section /><br /> 
     <!-- ^^ correct output, but just by coincidence -->
      And outer section_list is currently iterating on: <txp:variable name="section_by_section_list" /><br />
      But don't forget we are currently browsing section: <txp:variable name="section_by_url" /><br /> 

    </txp:article_custom>
----
  </txp:section_list>

Which should output:

URL says we are browsing section: events

    The section for current iteration of section_list is: a
    But don't forget we are currently browsing section: events

      This article belongs to section: a 
      And outer section_list is currently iterating on: a
      But don't forget we are currently browsing section: events
----
    The section for current iteration of section_list is: b
    But don't forget we are currently browsing section: events

      This article belongs to section: b 
      And outer section_list is currently iterating on: b
      But don't forget we are currently browsing section: events
----
    The section for current iteration of section_list is: c
    But don't forget we are currently browsing section: events

      This article belongs to section: c 
      And outer section_list is currently iterating on: c
      But don't forget we are currently browsing section: events

As you see, the output is logically correct, but a chunk of it (“This article belongs to section: “) is correct just by coincidence.

Jeff, in the part of the demo related to section context/tag, you say:

Section context has three layers, in descending order of priority:

  • local section context from section_list
  • section from local article context
  • global section context

Although your statement is correct under the light of the quirky behavior, I think there should be no “descending order or priority” for setting the section context (well, maybe just for the global section context set by current URL).

The section context should be set by the most inner wrapping tag that can set a section context.
Next examples suggests how this should work, imho.

<txp:section_list><txp:article_custom><txp:section /></txp:article_custom></txp:section_list>

^^ the deeper section context is set by article_custom.

<txp:article_custom><txp:section_list><txp:section /></txp:section_list></txp:article_custom>

^^ the deeper section context is set by section_list.
(Is there any real use case for that markup?)

As you can see, in both examples, there are no ambiguities, no descending order or priority. The inner container tag is the one that sets the section context.

Would love to hear your thoughts on this.
Thanks for reading.


La música ideas portará y siempre continuará

TXP Builders – finely-crafted code, design and txp

Offline

#10 2011-01-20 20:48:23

maniqui
Member
From: Buenos Aires, Argentina
Registered: 2004-10-10
Posts: 3,070
Website

Re: [howto] Textpattern: Context in depth

Also, I spotted this note on the developer notes part of your article:

Depending on the condition you want to check, this may be preferable even for elements with built-in tags. For example, if_individual_article evaluates to true if the $id global has a value, except when inside an article_custom tag. That’s because it checks against the $is_article_list global, not $id. If, for some reason, you need to check for page-level article context from within a custom list, if_individual_article is no help and you need to check $id directly.

Jeff, now that you are the master of TXP contexts (and a TXP core dev, congrats!!!), it seems to me that you may be the Chosen One: the only dev that will be able to answer a long standing issue I’ve reported on Google code and that is directly with all this context mumbo-jumbo. :)

Please, go carefully thru this issue: txp:if_article_id on article list context.
I say “carefully” because I’m reporting two different issues on that thread.
Also, because you will have to use a lot of brain power to understand my thoughts and examples, but, hey, you are the Chosen One, the man who tamed all TXP contexts in one page template. ;)
Also, because English is not my native language, so I made a few mistakes at the time I wrote the issue.

After reading that issue, please, also refer at this thread: if_article_list inside article_custom always evaluates true, where I discuss with Els (our Queen of Tags) the issue I reported in comment #2.
I think you will enjoy the discussion, and that I’m probably right (but only The Chosen One can confirm it) on my analysis, that there are still some quirky behaviors (should I say ‘bugs’?).

Thanks again.


La música ideas portará y siempre continuará

TXP Builders – finely-crafted code, design and txp

Offline

#11 2011-01-20 21:45:56

jsoo
Plugin Author
From: NC, USA
Registered: 2004-11-15
Posts: 1,793
Website

Re: [howto] Textpattern: Context in depth

Julián: thanks for the thought provoking posts and links!

You’re right that my section context example is contrived. But I’m having trouble thinking of a realistic case for when this would really matter. Maybe that means I shouldn’t include it in the demo.

BTW, to find global section context within a section_list or local article context, <txp:page_url type="s" /> will always work.

I agree with you that context precedence should match tag nesting. There are a number of areas where context-related behavior is not consistent. Main one the springs to mind at the moment is image context — too many different mechanisms.

Now I’ll have a look at your links and see if I can sort it out :)


Code is topiary

Offline

#12 2011-01-20 22:13:40

jsoo
Plugin Author
From: NC, USA
Registered: 2004-11-15
Posts: 1,793
Website

Re: [howto] Textpattern: Context in depth

I agree that if_article_id’s behavior is odd. I don’t know that a conditional should ever return blank. However, in this case it is clearly intentional. You could work around it like this (untested):

<txp:variable name="global_id">
	<txp:if_individual_article>
		<txp:page_url type="id" />
	<txp:else />
		list
	</txp:if_individual_article>
</txp:variable>
<txp:if_article_id id='<txp:variable name="global_id" />'>...

Code is topiary

Offline

Board footer

Powered by FluxBB