5

I have a couple Low Variables I'm using similar to the traditional embed template method. This variable has query module tag to find prev/next entry, but since it's within the channel tag I'm having issues getting the early parsed LV code to output the correct info - which I thought would take care of it.

So I then thought "why don't I take the query tag code and create a new LV that is parsed earlier than it's parent LV.

I'm pretty sure this is a parsing stage issue. So I was wondering if this is even possible since the LV is inside the channel tag? I also moved around the variables to different LV groups to change the parsing sequence, but that didn't work.

My coded simplified is like this:

{exp:channel:entries
    channel="case_studies"
    disable="categories|category_fields|member_data|pagination|trackbacks"
    require_entry="yes"
}
    ...
    {lv_tmpl_utility_belt}
    ...
{/exp:channel:entries}

{lv_tmpl_utility_belt}:

<div id="utility-belt"{if segment_1 != ""} class="nav-sticky"{/if}>
{exp:switchee variable="{segment_1}" parse="inward"}
    {case value=""} {!-- Show Home Utility Bar --}
        <ul id="nav-belt-tabs" class="wrapper clearfix">
            {exp:low_variables:pair var="lv_home_hero"}
                <li{if count == 1} class="active"{/if}><a href="#">{hero_tab}</a></li>
            {/exp:low_variables:pair}
        </ul>
    {/case}

    {case default="yes"} {!-- Show Interior Utility Bar --}
    <div class="wrapper">
        <a class="btn-flat btn-menu"href="#">Navigation Menu</a>

        {lv_ee_casestudy_prevnext_entries}

    </div>
    {/case}
{/exp:switchee} 
</div> {!-- /#utility-belt --}

{lv_ee_casestudy_prevnext_entries}:

{exp:query sql="
    SELECT 
        url_title, 
        title 
    FROM exp_channel_titles 
    WHERE url_title < '{segment_3}'
    AND channel_id = '3'
    AND status = 'open'
    ORDER BY url_title 
    DESC LIMIT 1
"}
<a class="btn-flat btn-prev" href="{url_title}" title="Previous: {title}">Previous Case Study</a>
{/exp:query}

{exp:query sql="
    SELECT 
        url_title, 
        title 
    FROM exp_channel_titles 
    WHERE url_title > '{segment_3}'
    AND channel_id = '3'
    AND status = 'open'
    ORDER BY url_title 
    ASC LIMIT 1
"}
<a class="btn-flat btn-next" href="{url_title}" title="Next: {title}">Next Case Study</a>
{/exp:query}
  • Just a quick note, unrelated to answering your question but important none the less:- the query module does not escape input, so by passing {segment_3}(or other dynamic content) into your query param you're opening a potential SQL injection vulnerability. Check out the Active Record plugin for a safer alternative. – Tom Davies Dec 21 '12 at 22:02
  • I'm not 100% positive, but I don't think that's an issue b/c you can't use semicolons, apostrophes, slashes, etc. in URL's w/o getting an error. Will that query work with the Active record plugin? I don't see support for AND? – Siebird Dec 21 '12 at 22:30
  • What version of EE are you using and what version of Low Variables? – CreateSean Dec 22 '12 at 15:30
3

If you're using early parsed vars only, try putting both of them in the same LV group and make sure {lv_tmpl_utility_belt} comes before {lv_ee_casestudy_prevnext_entries}. This ensures that the vars will be put into the template correctly. Having the second var above the first will fail.

To clarify, you've got 2 vars, A and B. A contains B, so A needs to be parsed before B. Hence the order in their group matters.

However, looking at the contents of your vars, I can see an issue coming up. You've got {title} and {url_title} vars inside the Query tags. These will actually get parsed by the channel:entries tag before the Query tag can get to it. So, you either need to rename those, or, to avoid such conflicts altogether, you could use the low_variables:single tag, along with the preparse: parameters, available in LV 2.3.0+.

Your code would then look something like this:

{exp:channel:entries
    channel="case_studies"
    disable="categories|category_fields|member_data|pagination|trackbacks"
    require_entry="yes"
}
    ...
    {exp:low_variables:single
        var="lv_tmpl_utility_belt"
        preparse:segment_1="{segment_1}"
        preparse:segment_3="{segment_3}"
    }
    ...
{/exp:channel:entries}

And just change the lv_tmpl_utility_belt var slightly, so it calls lv_ee_casestudy_prevnext_entries by also using the low_variables:single tag:

{exp:low_variables:single
    var="lv_ee_casestudy_prevnext_entries"
    preparse:segment_3="{segment_3}"
}

This approach is what some people call Killing the Embed Tag.

| improve this answer | |
  • I just converted an existing site from embeds to this method last week and it works perfectly. – CreateSean Dec 23 '12 at 14:26
  • Low thanks for the tips and thorough answer. I was confused on how the use the preparse parameters before, but now this makes sense. Thanks for the clarification! – Siebird Dec 24 '12 at 13:38
  • Question: Can you explain why I need preparse:segment_3="{segment_3}" in the parent template? Does this pass this through from lv_tmpl_utility_belt to lv_ee_casestudy_prevnext_entries variable? I noticed when I removed it from the parent template (ie. channels tag call) it stopped working properly. Just trying to understand and learn how this approach works – Siebird Dec 26 '12 at 18:23
  • 1
    Because of parse order. The {segment_x} variables are parsed before the LV tags/vars are put into the template and thus remain unparsed, unless you pass them through using the preparse parameter. – Low Dec 27 '12 at 9:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.