textpattern / textpattern.github.io

Textpattern CMS user documentation.
https://docs.textpattern.com
GNU General Public License v2.0
15 stars 17 forks source link

variable and if_variable tag clarifications #112

Closed wion closed 4 years ago

wion commented 5 years ago

I can't remember if I ever really knew how to use variables, or I just forgot, but I find them a little confusing now and the docs don't help at all. Maybe I'll try to improve the variable and if_variable docs, but first I have to understand them. The usual game. So following is what I understand, or think I understand, and what I don't understand at all. Please someone put me right.

variable

Can be used as a container or single tag.

It has two attributes: name="" and attribute="".

The name attribute seems straightforward enough. In order to use a variable at all (let alone assign a value to it), it must have a name.

So let's say we want a variable named 'string', and we want to assign a value to that variable equaling 'This is my string'. To do this as a container tag, it would be:

<txp:varible name="string">
This is my string.
</txp:variable>

How would we use that variable now? I don't know.

Do assign the same value as a single tag:

<txp:varible name="string" value="This is my string." />

Again, how would we use that? I don't know.

But I do know that some version of the variable must be put above where the value needs to be output. Example one in the variable doc seems to try to explain that idea, but not very well. The example seems like a lot of needless code and doesn't elucidate why the sole instance of the variable tag is at the bottom of it. Beats me.

And apparently you can also do this?

But I have no clue what those mean exactly, or why you would use one over the other, and the aforementioned doc doesn't mention any of them in the attributes section, nor any examples given.

So, you can see where some deficiencies are for the those like me who need the detail.

if_variable

Jumping ahead to the if_variable tag. Presumably once you have a global variable set to one's liking, you can then call the assigned value in a conditional way, if needed:

<txp:if_variable name="string">
  <em><txp:variable name="string" />.</em> It's doing its thing.
</txp:if_varible>

Which could also be written using the new tag structure syntax, as:

<if::variable name="string">
  <em><txp:variable name="string" /></em> It's doing its thing.
</if::varible>

Either way, it would output as:

'This is my string. It's doing its thing.'

If someone will help me iron out the kinks in all this, I will commit to augmenting the docs with what I learn. Other pea brains like me should appreciate it.

bloatware commented 5 years ago

How would we use that variable now?

You kinda answer this question in if_variable part. Variables are like Forms, you can store any string (even 0 or 1 or empty) inside and output it where needed with <txp:variable /> tag. Unlike static forms, variables are dynamic, i.e. they can be created and assigned a value on the fly. Additionally, you can compare this value against a string with <txp:if_variable /> tag and act accordingly:

<txp:variable name="page" value='<txp:page_url type="pg" />' />
<txp:if_variable name="page" value="1">
    This is the first page.
<txp:else />
    This is the <txp:variable name="page" />th page.
</txp:if_variable>
philwareham commented 5 years ago

I've added Oleg's example to the variable tag doc, as it's a nice example I think.

bloatware commented 5 years ago

You should extend it then to avoid 2th and 3th pages.

philwareham commented 5 years ago

You should extend it then to avoid 2th and 3th pages.

Already done!

bloatware commented 5 years ago

Ah, great, sorry :-)

wion commented 5 years ago

So what does the value="1" mean/do in your opening tag? I still don't get what "", "0", and "1" value values are supposed to do.

I'm under the impression they have a universal function across a lot of tags... Is there somewhere else they're already defined?

Revisiting Example 1 from the variable doc for context... It talks about defining a variable higher up in the DOM, I get that. Then in the first block the only variable tag is <txp:variable name="homepage" value="1" />

So that's suggesting (not clearly saying) to me that value="1" is part of the defining function? But even if so, what is it defining? All I see is a name and a number 1.

Then down the DOM the variable is used as a conditional, but I don't understanding what's being passed.

I'm sure this is stupid easy for anyone half familiar with scripting, but it's completely over my head. Tags that simply output what it says on the jar, no problem. But tags that do mysterious magic... I don't get them unless explained to me like I'm 5 years old. I can't be the only one. If we make the docs Destry-proof, you'll make them everyone-proof. ;)

Bloke commented 5 years ago

So what does the value="1" mean/do in your opening tag?

You can assign anything you like: 1 is just a convention to mean "something" as opposed to 0 meaning "nothing".

In the example on the variable page, it just sets the variable called homepage to that value to allow you to test later on if your site is in what you deem a "home" state, i.e. in this case not a category or search context.

Since it's been set, you can then use <txp:if_variable> later to check if the variable has the given value (in this case, "does homepage equal 1?") You could have made it like this:

...
conditional blah blah
...
        <title>My blog homepage</title>
        <meta name="description" content="The great homepage of my great blog.">
        <meta name="robots" content="index, follow, noodp, noydir">
        <txp:variable name="page_context" value="home" />
    </txp:if_category>
</txp:if_search>
...
<txp:if_variable name="page_context" value="home">
    … we've decided we're in 'home' context so do something a bit different here…
</txp:if_variable>

EDIT: You could also have set the same variable to any state, e.g. <txp:variable name="page_context" value="landing" /> if you detected you were not on the home page but on a section landing page. Again, later in your Page/Form templates you could test that variable to see if it matched "landing" and display something different if so. Just a convenience instead of always running the same <txp:if_...> conditionals all the time.

colak commented 5 years ago

Hi Destry, This is how I think about it in plain english.

  1. Establish a variable and what it should look for. For example to check if a category is populated by any articles.

<txp:variable name="any_name"><txp:article_custom category="my_category" limit="1" /></txp:variable>

  1. Check if the variable returns anything. If there are no articles in the category it will return nothing.

<txp:if_variable name="any_name" value="">

The value here is empty, hence, this is what you could do when there are no articles. ie you could have a text stating that there are no articles in this category.

<txp:else />

  1. There are articles in the category and you would like to render the content of article_custom

<txp:variable="any_name" />

  1. Finally close the if tag

</txp:if_variable>

This of course was the pre-4.7 way of doing it but it explains the logic.

Bloke commented 5 years ago

Yes, good example, colak.

As you state, from 4.7 we can use the power of <txp:evaluate> to short-circuit this particular use case. So, Destry, we now don't need to use variables like that unless we intend to reuse the same content a few times, then it becomes more efficient to do a tag call (article_custom here) once, store its output in a variable and then simply display the variable content multiple times further down the page.

wion commented 5 years ago

[Bloke] You can assign anything you like: 1 is just a convention to mean "something" as opposed to 0 meaning "nothing".

Okay, that kind of starts to make a little sense about the 1 itself. But if 0 means nothing, what would be a reason/example for using it?

I've also seen this in tags too: value="", such as Colak's step 2 above. What's the purposes of an empty value? [Doh, he explained it. Sorry again.]

The rest of the example is still not lucid.

Colak's example is more digestible, perhaps because it's more explicit/verbose. I like it. ;) That's the kind of alternative take that docs need wherever there is a gray zone. Better, frame in a way to be broadly useful and make it a higher-up pre-reading doc before jumping into individual tag pages, so not having to repeat the same bit over and over. Sounds like need for a variable. ;)

[Colak] This of course was the pre-4.7 way of doing it but it explains the logic.

Dang. So now that's not applicable anymore?

[Bloke] As you state, from 4.7 we can use the power of <txp:evaluate> to short-circuit this particular use case.

Unfortunately, evaluate is another one of those tags that I will probably never fully grok.

[Bloke] we now don't need to use variables like that unless we intend to reuse the same content a few times,

Do you mean Colak's example? [Okay, yes, I think you do. It makes sense.]

In any case, the idea of reusing the same content via variables reminded me of the section_descriptions form in the mag, which had a bunch of container variables defined like:

<txp:variable name="description-from-the-editor">
An address from the Editor-in-Chief each issue to introduce a current issue's article topics, and to discuss other magazine affairs—as they would concern the interests of readers—that may arise from one issue to another.
</txp:variable>

That concept I get. Similar, but not exactly the same as Colak's example. But if I wanted to output that description somewhere, I would just use this: <txp:variable name="description-from-the-editor" />? (I guess I should look in the mag.)

<txp:detour> The evaluate short-circuiting stuff gets a little esoteric, however. I can appreciate the new power of it for those who know how to wield it, but I think it's prudent to point out there is probably a point where the tag voodoo can be taken too far, defeating their whole purpose of making it easy for non-coders to work with PHP. It's just a different kind of barrier to the masses. Still a great niche tool for the wizards, but then why bother with the themes for soccer mom website owners, if you see what I mean. It's swapping one convenience for another hurdle, or something. I'm not complaining, I'm just offering a word of caution to the future. If things continue as they do, then maybe it becomes increasingly necessary to pre-build various kinds of packaged tag complexes/modules that do different common (and slightly uncommon) things so people don't have to figure it out from scratch, or redo it again and again. Assuming Txp does want to get more reach into the market. </txp:detour>

[Bloke] then it becomes more efficient to do a tag call (article_custom here) once, store its output in a variable and then simply display the variable content multiple times further down the page.

Just to understand if I'm still following... You're talking about Colak's example? [Again, yeah, I think you are. Sorry.]

So my challenge then is to grasp the use of numbers and empty values on the fly.

wion commented 5 years ago

I think the mag issues situation will be a good exercise for me to think about it. But if the tags can be improved/simplified with the new functionality, that would probably be smart to learn and do in my own site. Perhaps after crawling through that a little more fog will clear.

bloatware commented 5 years ago

Actually, in 4.7 <txp:article(_custom) /> is else-aware:

<txp:article>
    <txp:title />
<txp:else />
    Nothing here.
</txp:article>

An important use case for <txp:variable /> are counters or lists of all kinds:

<txp:article_custom>
<txp:if_first_article>
    <txp:variable name="authors" value='<txp:author title="" />' />
<txp:else />
    <txp:if_article_author name='<txp:variable name="authors" />'><txp:else />
        <txp:variable name="authors" value='<txp:variable name="authors" />,<txp:author title="" />' />
    </txp:if_article_author>
</txp:if_first_article>
</txp:article_custom>

<txp:authors name='<txp:variable name="authors" />' break=", ">
    <txp:author />
</txp:authors >
wion commented 5 years ago

[Colak] <txp:if_variable name="any_name" value="">

The value here is empty, hence nothing.

A little confusing on that point. If you're testing for a hit, why tell it to be nothing? Or do you mean something else by 'value'? I'm talking about the value attribute's value (value=""), which is shown here as empty. Why?

wion commented 5 years ago

[bloatware] An important use case for <txp:variable /> are counters or lists of all kinds

Okay. I'm expecting both in the periodical issues situation I'm hoping to get established, so again, a good exercise for me, I think.

Bloke commented 5 years ago

Yes I was referring to colak's example, sorry for not being clear.

1/0 is just a convention. You could call them 'haz' and 'not-haz' if you prefer. You can still test a variable to see if it contains a zero, or test it to see if it's empty (has no content) via value="".

Variables can be set to any value and can be tested to see if they contain any value previously set.

wion commented 5 years ago

1/0 is just a convention. You could call them 'haz' and 'not-haz' if you prefer.

Ahhhh... So it's not even an actual fixed attribute value in this case. No wonder the ambiguity.

You can still test a variable to see if it contains a zero, or test it to see if it's empty (has no content) via value="".

So you're saying value="0" and value="" are equivalent? One is the same as the other? Both used to test if conditional is a no hit? Good. This is clearing up.

Another question. If I find this in a mag form, <txp:variable name="issue" />, then I should recognize that's being used as an output marker, and the initial definition of that tag will have value="1" and is still somewhere higher up the DOM?

Hmmm... Nope. Where used seems to say there is no <txp:variable name="issue" value="1" /> anywhere, which makes sense, I guess, because we've established 1 is just a conditional convenience test only.

Bloke commented 5 years ago

So you're saying value="0" and value="" are equivalent?

In Txp, no. You can test for '0' distinct from 'empty'. This helps if you want to distinguish a counter that hasn't been initialised vs one that had started to be used but hasn't yet been incremented.

With regards a variable tag with no value, yes. That will output the current value assigned to the variable, whatever it may be. Could be a 1, a string, an entire set of articles, anything.

In the case you cite, that tag will output the current issue number read from the current context (URL or article, depending on what you're reading).

wion commented 4 years ago

Closing, as Phil had added the example to docs... https://github.com/textpattern/textpattern.github.io/issues/112#issuecomment-436196222

The rest I'll suffer on my own. ;)