Go to main content

Textpattern CMS support forum

You are not logged in. Register | Login | Help

#1 2009-08-14 05:20:50

johnstephens
Plugin Author
From: Woodbridge, VA
Registered: 2008-06-01
Posts: 999
Website

What are your use-cases for the txp:yield tag?

Textpattern 4.2.0 allows you to build forms that include a new tag: txp:yield.

So if you build a form like this:

<h4>Lorem Ipsum</h4>
<ul>
<txp:yield/>
</ul>

You can call it from your page like this:

<txp:output_form form="my-form">
<li>dolor</li>
<li>sit</li>
<li>amet</li>
</txp:output_form>

And Textpattern will process it into this:

<h4>Lorem Ipsum</h4>
<ul>
<li>dolor</li>
<li>sit</li>
<li>amet</li>
</ul>

The Textbook examples are pretty clear, but I can’t think of any real-life cases where this tag would be helpful. I use txp:variables a lot. I’m wondering what uses others might have for txp:yield.

Sam likened this tag to Radiant’s <r:yield /> tag. From what I can gather, this seems like an apt comparison — but I can’t find any creative or useful examples of that tag in action either.

Last edited by johnstephens (2009-08-14 05:21:50)

Offline

#2 2009-08-14 06:03:50

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

Re: What are your use-cases for the txp:yield tag?

Off the top of my head (well, based on other ideas) you could do something like this:

On a form: header

<head>
...
<link rel="stylesheet" type="text/css" href="/css/common.css" />
<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript" src="/js/common.js"></script>
...
<txp:yield />
...
</head>

Then, on a page template:

<txp:output_form form="header">
<link rel="stylesheet" type="text/css" href="/css/special-section.css" />
<script type="text/javascript" src="/js/special-section.js"></script>
</txp:output_form>

And TXP will process it into:

<head>
...
<link rel="stylesheet" type="text/css" href="/css/common.css" />
<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript" src="/js/common.js"></script>
...
<link rel="stylesheet" type="text/css" href="/css/special-section.css" />
<script type="text/javascript" src="/js/special-section.js"></script>
...
</head>

And this is just the beginning… Let’s wait and see what could be possible when some of the great minds on this forum begin to play with this.
Of course, there are also some concerns: can <txp:output_form> (as a single or as a container) be nested inside another <txp:output_form></txp:output_form>? If so, will the whole Internet be put at risk?

Finally, you may say: “hey, but what you did above can be done using conditionals, like txp:if_section directly on header form”. Sure, but then, your header form will be cluttered of conditionals.
If the above example works, then it will let you keep some extra code directly on your page template, and not just to keep things tidy but also to do more TXP magic (yet to be discovered) inside txp:output_form as a container tag.

Last edited by maniqui (2009-08-14 06:05:28)


La música ideas portará y siempre continuará

TXP Builders – finely-crafted code, design and txp

Offline

#3 2009-08-14 06:17:59

artagesw
Member
From: Seattle, WA
Registered: 2007-04-29
Posts: 227
Website

Re: What are your use-cases for the txp:yield tag?

maniqui wrote:

Of course, there are also some concerns: can <txp:output_form> (as a single or as a container) be nested inside another <txp:output_form></txp:output_form>? If so, will the whole Internet be put at risk?

Yes, forms may be nested to arbitrary depth, and you can even pass the output of <txp:yield /> from an outer form to an inner form and it will work as expected. No, the Internet should be just fine. ;)

Offline

#4 2009-08-18 20:41:44

merz1
Member
From: Hamburg
Registered: 2006-05-04
Posts: 994
Website

Re: What are your use-cases for the txp:yield tag?

Automatic cooking with Textpattern made easy.
Define your standard recipe in a form.
Wherever special ingredients are needed define them where & when needed in an txp:output_form container.

Object oriented without all the if/else spaghetti code.

Only hard for people used to knotting spaghetti :)


Get all online mentions of Textpattern via OPML subscription: TXP Info Sources: Textpattern RSS feeds as dynamic OPML

Offline

#5 2009-08-31 04:08:06

mericson
Member
Registered: 2004-05-24
Posts: 137
Website

Re: What are your use-cases for the txp:yield tag?

I submitted the feature request for this, so here is my use case…

I have a portal like site containing many different islands of content with a consistent frame/style around the content. Rather then repeating the same stylization for each time that island appears, using a common form with <txp:yield/> allows wrapping content items consistently. Also allows different skinning by simply changing the name of the wrapping form name.

Offline

#6 2009-08-31 13:56:17

johnstephens
Plugin Author
From: Woodbridge, VA
Registered: 2008-06-01
Posts: 999
Website

Re: What are your use-cases for the txp:yield tag?

One limitation of txp:yield is that it can’t be used with a txp:article tag, but I found this workaround today:

<txp:article>
	<txp:output_form form="my_list">
		<txp:permlink>
			<txp:article_image thumbnail="1"/>
		</txp:permlink>
	</txp:output_form>
</txp:article>

Where form my_list is something like this:

<txp:if_first_article><ul></txp:if_first_article>
<li>
	<txp:yield/>
	<h4><txp:permlink><txp:title/></txp:permlink></h4>
</li>
<txp:if_last_article></ul></txp:if_last_article>

In other word, I think I get it now. This allows me to use my generic list form for many article lists on the site, but use article thumbnails in the place needed, without trying to devise some crazy conditional statements in the form itself. Love it.

And hey, thanks for suggesting this feature!

Offline

#7 2009-08-31 14:34:20

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

Re: What are your use-cases for the txp:yield tag?

johnstephens wrote:

One limitation of txp:yield is that it can’t be used with a txp:article tag, but I found this workaround today:

Currently it only works in tandem with txp:output_form.
Would it make sense to add it to other wrapping tags? Probably, but there may be a few backward compatibility issues, as currently when using tags (txp:article, txp:article_custom, txp:section_list, etc) as container tags, the form attribute is ignored (which, btw, if someone specified it, it’s an “innocuous error”).

Now, I was going to post the following on the dev list or the Google issues tracker (maybe I will, after discussing it here) but this may be the place to share the idea.

I’ve been testing txp:yield and it’s a great addition to make a few new tricks. At the same time, it’s very limited, but that’s OK, as this is the first release of this feature, and I would bet it could be improved on future TXP versions.
So, here are some feature ideas:

Named yields

On a form: header

<head>
...
<link rel="stylesheet" type="text/css" href="/css/common.css" />
<txp:yield name="extra_css" />

<script type="text/javascript" src="/js/jquery.js"></script>
<script type="text/javascript" src="/js/common.js"></script>
<txp:yield name="extra_js" />
...
</head>
<body>
...
<div id="breadcrumb">Home | <txp:yield name="breadcrumb" /></div>
...

Then, on a page template:

<txp:output_form form="header">
<!-- below, txp:yield is used as a container, to create different yields that will be passed to the "header" form above -->
<txp:yield name="extra_css"> 
  <link rel="stylesheet" type="text/css" href="/css/special-section.css" />
  <link rel="stylesheet" type="text/css" href="/css/another.css" />
  <style>
  /* some inline css */
  </style>
</txp:yield>

<txp:yield name="extra_js"> 
  <script type="text/javascript" src="/js/special-section.js"></script>
  <script type="text/javascript" src="/js/super-jquery-plugin.js"></script>
  <script>
  // some inline JS
  </script>
</txp:yield> 

<txp:yield name="breadcrumb"> 
  <a href="..."><txp:section /></a><txp:if_individual_article><txp:title /></txp:if_individual_article>
</txp:yield> 

</txp:output_form>

You get the idea, right?

But then, I’ve heard that there is a <txp:scope /> tag in the pipeline. I wonder where/if it overlaps with this idea, as I understand that it’s aimed to limit the scope of a <txp:variable />. BTW,according to Textbook <txp:variable /> can be used as a container tag, did you know?

So, maybe, <txp:scope /> + <txp:variable /> = named <txp:yield />.
Currently, txp:variables aren’t being destroyed after being used (which may lead to undesirable results), but txp:yields are destroyed (they don’t exist outside the form after it is processed).

Well, I’ll stop now. This is just the beginning of a brainstorming of ideas for TXP 4.2.X or maybe TXP 5.0 :)


La música ideas portará y siempre continuará

TXP Builders – finely-crafted code, design and txp

Offline

#8 2009-09-01 03:22:22

artagesw
Member
From: Seattle, WA
Registered: 2007-04-29
Posts: 227
Website

Re: What are your use-cases for the txp:yield tag?

I think your example would be better accomplished via scoped variables (see below) than by extending the yield tag. Using scoped variables, I would implement it as follows:

<head>
	<link rel="stylesheet" type="text/css" href="/css/common.css" />
	<txp:variable name="extra_css" />
	<script type="text/javascript" src="/js/jquery.js"></script>
	<script type="text/javascript" src="/js/common.js"></script>
	<txp:variable name="extra_js" />
</head>
<txp:scope local="true">
	<txp:variable name="extra_css"> 
	  <link rel="stylesheet" type="text/css" href="/css/special-section.css" />
	  <link rel="stylesheet" type="text/css" href="/css/another.css" />
	  <style>
	  /* some inline css */
	  </style>
	</txp:variable>

	<txp:variable name="extra_js"> 
	  <script type="text/javascript" src="/js/special-section.js"></script>
	  <script type="text/javascript" src="/js/super-jquery-plugin.js"></script>
	  <script>
	  // some inline JS
	  </script>
	</txp:variable> 

	<txp:output_form form="header" />
</txp:scope>

About the Scope Tag

Currently, <txp:variable> only allows for creation of global variables in a single global scope. Just as in general programming, overuse of global variables can result in code that is brittle and difficult to maintain.

The <txp:scope> tag establishes independent scopes for variable definitions, such that using the same name for a variable in different pages/forms/etc will not result in accidental variable stompage.

Example 1:

<txp:variable name="myvar" value="100">

Same as current behavior. “myvar” established in global scope, accessible everywhere.

Example 2:

<txp:variable name="myvar" value="100">
<txp:scope>
       <txp:variable name="myvar" value="200">
       <txp:variable name="myvar2" value="300">
</txp:scope>

Inside the scope, “myvar” assumes the value “200” and “myvar2” assumes the value “300”. Upon exiting this scope, “myvar” retains the value “200” and “myvar2” becomes undefined.

Example 3:

<txp:variable name="myvar" value="100">
<txp:scope>
       <txp:variable name="myvar2" value="200">
       <txp:variable name="myvar3" value="300">
       <txp:scope local="true">
               <txp:variable name="myvar2" value="400">
               <txp:variable name="myvar3" value="500">
       </txp:scope>
</txp:scope>

Demonstrates nested scopes and local scope. Scopes may be nested to any depth. By default, all variables declared at outer scopes are available to the inner scope and changes made to these variables are retained upon exiting the inner scope.

However, if the optional “local” attribute is set to “true,” a brand new scope is established with no access to outer scope variables (including globals). This enables creation of a pristine environment where there is no chance of clobbering existing globals due to unintended name collisions.

In example 3, inside the nested scope (declared with “local” attribute), “myvar” is undefined while “myvar2” and “myvar3” assume values of “400” and “500” respectively. Upon exiting the nested local scope, “myvar2” and “myvar3” revert to their previous values (“200” and “300” respectively) and myvar becomes accessible again, with the value “100”. Note that if myvar were redefined to some other value, say “600”, in the local scope, it would revert to its previous value of “100” upon exiting that scope.

Offline

#9 2009-09-01 04:12:11

mrdale
Member
From: Walla Walla
Registered: 2004-11-19
Posts: 2,215
Website

Re: What are your use-cases for the txp:yield tag?

wha? when the hell did scope happen?

Offline

#10 2009-09-01 06:12:58

artagesw
Member
From: Seattle, WA
Registered: 2007-04-29
Posts: 227
Website

Re: What are your use-cases for the txp:yield tag?

mrdale wrote:

wha? when the hell did scope happen?

The scope tag is a goodie I am cooking up for the next release.

Offline

#11 2009-09-02 15:52:51

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

Re: What are your use-cases for the txp:yield tag?

Hi Sam,
thanks for the follow up and the clear examples.

Let’s me start with a quote, I learn here at TXP forums.: “beauty is in the eye of the beholder” ;)
And a disclaimer: I’m doing lobby. Not only I’ve some “strong feelings” about the idea of named yields (you may already have seen this old thread), but also on an informal chat poll, the idea got a few “+1” from hardcore TXP users ;), which is just anecdotal as wishing a piece still needs someone to write it.

After seeing your examples, no doubt it can be achieved using txp:scope tag, which is a new nifty addition, a game opener on what can be achieved with a few strokes.

I think your example would be better accomplished via scoped variables (see below) than by extending the yield tag.

Let me sketch a quick comparison between the txp:scope example and the named txp:yields approach. I will use basic examples for both, as I think they will be the most real users cases. Nesting output_form, yields, scopes and variables maybe possible and useful, but let’s ignore this possibility by now.

txp:scope + txp:variable

First, a short example (based in yours):

<!DOCTYPE ... >
<head>
	<txp:variable name="A" />
	<txp:variable name="B" />
</head>
<txp:scope local="true">
	<txp:variable name="A"> 
       blah blah
       blah
	</txp:variable>
	<txp:variable name="B" value="blah" /> 

	<txp:output_form form="header" />
</txp:scope>

It works but then:

  • a) “major” code readability issue: how do I know that the variables are being used inside header form? Yes, I could intuit from the presence of txp:scope, but it is, imho, harder to “read it” and “deduce” what’s going on [1].
  • b) minor issue: it adds a lot of extra whitespace:. Not that is too relevant, but some TXP users are very OCD about white-space, and in this particular example, white-space above <doctype> may be triggering nasty modes in legacy browsers. Also, an edge case: if we want to server XML using Txp templates/forms, I understand the whitespace can be undesired too. But that’s another story…
  • c) issue: as “beauty is in…”, I find it harder to see and to follow the wrapping txp:scope + local="" + contained txp:variable + contained forms dance. The global/local variable scope concept itself is one very hard to grasp, and consider that many TXP users (me included) are non-programmers.

[1] Regarding the “major” issue above, see this txp:scope extended example:

<txp:scope local="true">
	<txp:variable name="A"> 
       blah blah
       blah
	</txp:variable>
	<txp:variable name="B" value="blah" /> 

	<txp:output_form form="basics" />
	<txp:output_form form="header" />
	<txp:output_form form="a_few_extra_things" />
</txp:scope>

Now, how will user knows if/where variable A and B are being used? Is it in “basics” form? Is it in “header”? Is it in “a_few_extra_things”? Is it in all of them? In none of them maybe (which, of course, code example doesn’t make too much sense)?
You may say: don’t wrap on txp:scope those that don’t use the variables, but that just replies one question or two.

Now, here is where I think the idea of named txp:yield shines, as it can make code easier to read and follow, and to maintain, and overcomes the three listed issues (a, b, c) above.

txp:output_form + named txp:yields

First, a short example (based in mine):

<txp:output_form name="header">
	<txp:yield name="A">
	Blah blah
	Blah
	</txp:yield>
	<txp:yield name="B">
	Blah
	</txp:yield>
</txp:output_form>
<!DOCTYPE ...>
<head>
	<txp:yield name="A" />
	<txp:yield name="B" />
</head>

Some benefits I see on this:

  • Looking at the name attribute on wrapping txp:output_form, you can see where the yields are going to be used.
  • yields are already scoped “by nature”. They don’t exist or are destroyed outside the form. So, no need of scoping things, which is stuff for clever programmers :)
  • it’s less, more readable, and easier to follow code (“beauty is…”). Imho, it is easier for non-programmers to use it and to follow.
  • it “grows” on the current concept, implementation and usage of txp:yield, which has been a nice addition, but currently rather limiting on what can be achieved with it.
  • no extra whitespace: less output site and happy OCD users.
  • also, what about this? If the way to go is txp:scope + txp:variables, then it almost makes obsolete the current implementation of txp:yield. Poor little tag!

La música ideas portará y siempre continuará

TXP Builders – finely-crafted code, design and txp

Offline

#12 2009-09-07 19:54:24

mericson
Member
Registered: 2004-05-24
Posts: 137
Website

Re: What are your use-cases for the txp:yield tag?

I just remembered my other use case…

I have several sections that I want to be mostly identical, they all have the same layout, header, footer and right-hand column. There are subtle differences in the navigation and layout of the articles within the sections. The way I handle it today is my page template is essentially one big case statement with an article tag or output_form for each section. This works, and maintains the common style for the page, but is cumbersome to manage as I have all these conditions in the page for each section…

<div class="header">...</div>
<div class="menu">...</div>
<div class="col1">
  <txp:if_section name="faq">
     ...
  </txp:if_section>
  <txp:if_section name="blog>
     ...
  </txp:if_section>
</div>
<div class="col2">...</div>
<div class="footer">...</div>

With yield I will return to a different page for each section without the conditions, but put the common page design in a form with a yield.

<!-- 'pageskin' form contains common page layout / design -->
<div class="header">...</div>
<div class="menu">...</div>
<div class="col1">
  <txp:yield/>
</div>
<div class="col2">...</div>
<div class="footer">...</div>
<!-- page for each section with section specific content inside the output_form element -->
<txp:output_form form="pageskin">
  <!-- section specific output here -->
  </txp:output_form>
</code></pre>

Offline

Board footer

Powered by FluxBB