EllisLab text mark
Advanced Search
     
assigned variable changes content in some context
Posted: 14 July 2008 05:23 PM
Avatar
Joined: 2008-03-05
62 posts

Hi,
I’ve got a weird problem where EE is changing the output of a variable during parsing. I’m trying to generate a Google Sitemap XML file.

I’ve assigned a variable at the top of my xml file.

{assign_variable:lastmodDate="{exp:stats}{last_entry_date format='{DATE_W3C}'}{/exp:stats}"

Which works fine with:

<url>
<
loc>http://www.example.com/examplegroup/template/C11/</loc>
<lastmod>{lastmodDate}</lastmod>
<
changefreq>weekly</changefreq>
<
priority>1.0</priority>
</
url

which outputs:

<url>
<
loc>http://www.example.com/examplegroup/template/C11/</loc>
<lastmod>2008-07-12T17:57:26+01:00</lastmod>
<
changefreq>weekly</changefreq>
<
priority>1.0</priority>
</
url

But with the following it gets weird:

{exp:weblog:categories weblog="eintraege" show_empty="yes" style="linear" category_group="4" disable="categories|member_data|pagination|trackbacks"}{if type != "level1Heading"}
<url>
<
loc>{site_url}examplegroup/template/C4/tag/<?php echo(rawurlencode("{category_name}"));?></loc>
<
lastmod>{lastmodDate}</lastmod>
<
changefreq>weekly</changefreq>
<
priority>0.5</priority>
</
url>
{/if}{/exp:weblog:categories} 

output is:

<url>

<loc>
http://www.example.com/examplegroup/template/C4/tag/Hotels & Motels
</loc>
<
lastmod>0</lastmod>
<
changefreq>weekly</changefreq>
<
priority>0.5</priority>
</
url

PHP parsing is set to output stage. Though I checked by removing the php-statement and the error still occurs. Why could the variable {lastmodDate} change it’s content to “0”?

 
Posted: 14 July 2008 05:27 PM   [ # 1 ]   [ Rating: 0 ]
Avatar
Joined: 2004-05-15
29075 posts

What version and build are you on? I’ve seen this error a few times, and quite often it simply boiled down to file corruption. Might want to re-upload your files, perhaps updating to the latest build in the process.

 
Posted: 14 July 2008 05:34 PM   [ # 2 ]   [ Rating: 0 ]
Avatar
Joined: 2008-03-05
62 posts

Hi Ingmar,
I’m using ExpressionEngine 1.6.4, Build: 20080710

The weird thing is, that this happens all in the same XML file.

 
Posted: 14 July 2008 05:47 PM   [ # 3 ]   [ Rating: 0 ]
Avatar
Joined: 2008-03-05
62 posts

I’ve reuploaded all files mentioned in the EE Documentation for updating to the latest version, just in case. The problem still persists.

 
Posted: 14 July 2008 06:18 PM   [ # 4 ]   [ Rating: 0 ]
Avatar
Joined: 2008-04-29
344 posts

Greetings,

It seems that assign_variable doesn’t like nested variables in the declaration. A workaround for right now is to just use the format instead of a variable for lastmodDate.

{assign_variable:lastmodDate="{exp:stats}{last_entry_date format='%Y-%m-%dT%H:%i:%s%Q'}{/exp:stats}"

I’ll be looking into why nested variable declarations are not functioning correctly.

 
Posted: 14 July 2008 06:29 PM   [ # 5 ]   [ Rating: 0 ]
Avatar
Joined: 2008-03-05
62 posts

I just tried your code, cleared all caches, still the same weird output.

It outputs <lastmod>2008-07-01T16:04:00+01:00</lastmod> if I just use {lastmodDate} but if I wrap it inside the {exp:weblog:categories} I get <lastmod>0</lastmod>

 
Posted: 14 July 2008 08:03 PM   [ # 6 ]   [ Rating: 0 ]
Avatar
Joined: 2008-04-29
344 posts

It seems I over-looked the parsing order. Your solution is embeds I believe.

 
Posted: 15 July 2008 05:21 AM   [ # 7 ]   [ Rating: 0 ]
Avatar
Joined: 2008-03-05
62 posts

Justin, I think we’re on the wrong track with this. I can even skip the assigned variable bit and just put the {exp:stats}{last_entry_date format=’%Y-%m-%dT%H:%i:%s%Q’}{/exp:stats} line everywhere I need it. The results are the same. Which is even more odd, since I thought that an assigned variable gets evaluated just once and then the content of it gets echoed wherever I put the variable name. But the output changes whenever I put the {exp:stats} call or the variable inside the {exp:weblog:categories}. I assigned the variable outside of this loop at the top of the XML file.

Even this code outputs the correct date as long as I stay outside of {exp:weblog:categories}, that’s why I assigned a variable for the {exp:stats} in the first place. Because I was assuming that {exp:stats} had something weird going on inside the {exp:weblog:categories}. So I tried assigning a variable, which I thought would just echo the string.

Why would “2008-07-01T16:04:00+01:00” change to “0” just because it’s output inside {exp:weblog:categories}?

 
Posted: 15 July 2008 03:21 PM   [ # 8 ]   [ Rating: 0 ]
Avatar
Joined: 2008-04-29
344 posts

Greetings,

Embeds would solve this, as each template is parsed on it’s own. The reason we need this is that each tag is identified in the order it occurs in the template. The tag is then stored in an array, and replaced with a temporary marker. The template is then parsed and the tags marker is replaced with the corresponding $return_data. If an identical tag occurs more than once in a template, the copy is replaced with the same marker. The second digit in the marker is the index in the array of tags (i.e.: M0…, M1…, M2… etc). After the tag is parsed, the markers are replaced.

Since 0 comes before 1, and there’s a marker for 0 (lastmodDate) inside of the maker for 1 (weblog:entries), the marker doesn’t get replaced when tag 0 is parsed. Tag 0’s code is never executed again, so the marker 0 (lastmodDate) that was inside of marker 1 (weblog:entries) never has an opportunity to be replaced by anything. So you end up with the temp marker output. Embeds allow each template to be parsed separately, and would solve this issue.

 
Posted: 15 July 2008 03:31 PM   [ # 9 ]   [ Rating: 0 ]
Avatar
Joined: 2008-03-05
62 posts

And why does even a direct {exp:stats}{last_entry_date format=’%Y-%m-%dT%H:%i:%s%Q’}{/exp:stats} result in the same output when it’s executed inside a {exp:weblog:categories}?

 
Posted: 15 July 2008 03:40 PM   [ # 10 ]   [ Rating: 0 ]
Avatar
Joined: 2002-06-03
6515 posts

The assign variable tag is immaterial here, as you have just surmised.

The template parser is an extremely complex gizmo, so let me try to explain it stripped of what techno mumbo jumbo I can. This will still be long, so bear with me.

The template parser intelligently saves on resources by only processing a given tag once, no matter how many times it occurs on the template.  This means that if your tag is exactly the same, including its tagdata, EE only execute’s that modules code once, and replaces all copies of that tag with the output.

So first, when the template parser goes through the template finding tags, it replaces them all with temporary markers (the gibberish), and adds each tag to a list of tags to be parsed, in the order they are encountered on the template, top down.  Each marker starts with the letter “M” followed by the number (starting at 0) that tag is sitting in on The List.

Second, the parser goes down its list of tags.  It parses tag #0, and then replaces all of #0’s marker with that tag’s output.

——————-

Ok that’s the setup.  Here’s why it affected you, and why this side effect is not a problem (and also extremely, extremely rare). Remember, top down, tags will be assigned 0, 1, 2, etc.  So I’m abstracting it out to show the nesting and the positioning only.  Just focus on the numbers.

{exp:tag0}foo{/exp:tag0}
{exp
:tag1}
    bar
    {exp
:tag0}foo{/exp:tag0}
{
/exp:tag1} 

Step 1, the tags are grabbed and replaced with markers.  The first tag encountered is replaced first.

M0
{exp
:tag1}
    bar
    M0
{
/exp:tag1} 

And then the next tag:

M0
M1 

All tags have been collected and put on The List, so step 2, the parser goes down The List, and parses tag #0:

foo
M1 

See the problem?  The second M0 is sitting protected inside the marker for tag #1, so it doesn’t get replaced.  Then tag #1 gets parsed.

foo
    bar
    M0 

And the marker is left in the output.  EE doesn’t go back and parse tag #0 again, it’s already done that once, and will not do it again.

So the circumstances required for this problem to exist each are uncommon, and combined, very very rare:

1) Multiple exact copies of a given tag
2) One or more copies nested inside another tag (tag nesting itself is also rare, and usually not recommended)
3) The tag of which there are copies must sit at a position in the template above any occurrences of it being nested in another tag.

 Signature 
 
Posted: 15 July 2008 06:04 PM   [ # 11 ]   [ Rating: 0 ]
Avatar
Joined: 2008-03-05
62 posts

Thanks a lot Justin and Derek for your explanation. It really makes a difference for me in understanding Expression Engine at its core. This is the stuff I want to know, so thanks for taking the time to show me what’s under the hood. You should do a few podcasts/videocasts on such things. I would really appreciate it, since it would help us to understand the way EE is meant to work.

The only thing I still don’t understand, why’s there such gibberish like “0” in the output. Shouldn’t there be just nothing instead? At least that’s what I’m used to from EE, when there’s a any parsing problem, EE stays silent in the output.

Thanks again for your detailed posts, it really helps.

 
Posted: 15 July 2008 06:34 PM   [ # 12 ]   [ Rating: 0 ]
Avatar
Joined: 2002-06-03
6515 posts

This particular scenario is just something that the template parser was not designed to anticipate.  It’s not intentional that it leaves the unparsed markers, I think for me at least, this is the first that I’ve ever seen it occur.  I think armed with this knowledge, we can take steps in future versions to find and remove these, and make a note in the Template Parsing log that so Super Admins can still have some feedback to know that something went wrong.  Confusing as it was to you, its existence in the output did prompt you to come here and post for help, which might not have occurred (or have been as easily diagnosable on our end) if it was silent.

 Signature 
 
Posted: 16 July 2008 08:01 AM   [ # 13 ]   [ Rating: 0 ]
Avatar
Joined: 2008-03-05
62 posts

You guys should definitely do a screencast series to explain best coding practices and how EE is designed to work internally. It’s only now that I realize that I’m seeing the marker definition. I really see the need for people who want to really grasp building complex sites in EE. There are so many things you can combine and nest and put conditionals in that you should explain how to make the most out of EE and not interfere with the logic that EE was built by. It doesn’t have to be a well laid out cleaned up tutorial series, just some quick sessions to enhance our knowledge about EE.

 
Posted: 16 July 2008 10:56 AM   [ # 14 ]   [ Rating: 0 ]
Avatar
Joined: 2008-03-05
62 posts

Just wanted to add that everything now works as expected. It feels so much better when you know about the mechanics and to know what results to expect instead of just working with trial and error. Thanks for your help!

 
Posted: 16 July 2008 11:10 AM   [ # 15 ]   [ Rating: 0 ]
Avatar
Joined: 2002-06-03
6515 posts

You’re quite welcome, eexperience.

 Signature