1

I have this opening low search result tag

{exp:low_search:results
  {if segment_2}query="{segment_2}"{/if}
  group_id="7"
  limit="4"
  paginate="bottom"
}

I wanted to do more checks on segment_2 before deciding if I should set query param(checking if the segment is for pagination such as P1 or P4).

{exp:low_search:results
    {if segment_2 == '' OR {exp:segment_search keyword="/^P\d+$/" segments="2" regex="yes"}}{if:else}query="{segment_2}"{/if}
     group_id="7"
     limit="4"
     paginate="bottom"
}

However, I don't think this will work. I think it has something to do with the parse order where you can't set complex conditionals inside a tag.

If so, is there an alternative way to set the query param?

UPDATE: The reason I am asking is because the code below does not work

{if {segment_2} == '' OR {exp:segment_search keyword="/^P\d+$/" segments="2" regex="yes"}}
    {exp:low_search:results
        {if segment_1 == "foo"}group_id="6"{/if}
        {if segment_1 == "bar"}group_id="7"{/if}
        limit="4"
        paginate="bottom"}
{if:else}
    {exp:low_search:results
        query="{segment_2}"
        {if segment_1 == "foo"}group_id="6"{/if}
        {if segment_1 == "bar"}group_id="7"{/if}
        limit="4"
        paginate="bottom"}
{/if}

I always get a Parse error: syntax error, unexpected T_ELSE in the code where I don't set the query param.

  • I'd suggest you edit this question to take Low Search out of the equation. It's a question about parse order and conditionals rather than LS, as the same issue would occur using the native channel:entries tag. Or any other tag, for that matter. – Low Jul 10 '13 at 14:05
  • @Low Changed the tags and title – arvinsim Jul 11 '13 at 2:01
6

So yeah. Parse order. I take it you've seen this pdf. If not, take a look, study it well.

What you need is for the opening tag to be in order before you hit stage 5: the parsing of module/plugin tags. In order to do that, you can only use simple conditionals in combination with early parsed global variables and preload replace variables. Native early parsed vars are limited, so go and get the super useful (and free) Mo' Variables to get more useful early parsed stuff.

Once installed, you can use {if paginated}{/if} as a simple conditional. Just beware you don't use any AND or OR operators, nor use {if:else} in your conditionals, because that will turn it into an advanced one, and will be parsed too late for your use.

First of all, this: {if {segment_2} == ''} is an advanced conditional. The simple syntax is {if segment_2 == ''}. Using tags in conditionals, like you do with the {exp:segment_search} tag, means the conditional is advanced, too. So, avoid.

Here's my take, using preload replace vars and simple conditionals only.

{!-- Don't set the query param if there is no query --}
{if segment_2 == ''}
    {preload_replace:pre_query=''}
{/if}

{!-- Don't set the query param for non-query paginated pages --}
{if segment_3 == ''}
    {if paginated}
        {preload_replace:pre_query=''}
    {/if}
{/if}

{!-- Determine group ID based on segment 1 --}
{if segment_1 == 'foo'}
    {preload_replace:pre_group_id="6"}
{/if}

{if segment_1 == 'bar'}
    {preload_replace:pre_group_id="7"}
{/if}

{!-- Default Preload Replace vars --}
{preload_replace:pre_query='query="{segment_2}"'}
{preload_replace:pre_group_id="6|7"}

{!-- Here comes the Results tag --}
{exp:low_search:results {pre_query} group_id="{pre_group_id}" limit="4"}
  ...
{/exp:low_search:results}

So, note that I don't use any conditionals in the tag itself. Everything is done using simple conditionals and preload replace vars. Keeps things nice and clean. And I haven't even mentioned Switchee yet...

2

You problem is you're trying to do a complex conditional within the tag parameters, that's not possible.

Here's a good article regarding parsing conditionals within tags: http://johndwells.com/blog/expressionengine-parse-order-advanced-conditionals-as-tag-parameters

As you state, the problem is simple conditionals versus complex conditionals.

The problem with your second code:

{if {segment_2} == '' OR {exp:segment_search keyword="/^P\d+$/" segments="2" regex="yes"}}
    {exp:low_search:results
        {if segment_1 == "foo"}group_id="6"{/if}
        {if segment_1 == "bar"}group_id="7"{/if}
        limit="4"
        paginate="bottom"}
{if:else}
    {exp:low_search:results
        query="{segment_2}"
        {if segment_1 == "foo"}group_id="6"{/if}
        {if segment_1 == "bar"}group_id="7"{/if}
        limit="4"
        paginate="bottom"}
{/if}

...Is that you won't be able to have the opening tag in a separate conditional to the closing tag - EE parses conditionals at a separate stage to tags. It's not linear (working from top to bottom).

This may work:

{if {segment_2} == '' OR {exp:segment_search keyword="/^P\d+$/" segments="2" regex="yes"}}
    {exp:low_search:results
        {if segment_1 == "foo"}group_id="6"{/if}
        {if segment_1 == "bar"}group_id="7"{/if}
        limit="4"
        paginate="bottom"}

        {title}

    {/exp:low_search:results}
{if:else}
    {exp:low_search:results
        query="{segment_2}"
        {if segment_1 == "foo"}group_id="6"{/if}
        {if segment_1 == "bar"}group_id="7"{/if}
        limit="4"
        paginate="bottom"}

        {title}

    {/exp:low_search:results}
{/if}

...Where each tag pair is contained within the same conditional.

There's an additional problem in your revised conditional that is showing a parse error:

{if {segment_2} == '' OR {exp:segment_search keyword="/^P\d+$/" segments="2" regex="yes"}}

If there is no keyword, that tag will return an empty string, resulting in your conditional looking like this prior to EE parsing it: {if {segment_2} == '' OR }

...Which will result in the parse error. This is safer:

{if {segment_2} == '' OR '{exp:segment_search keyword="/^P\d+$/" segments="2" regex="yes"}'}

With the quotes, it can be parsed correctly as {if {segment_2} == '' OR ''}

Or how I'd approach it, by including in an embed and doing all the conditionals in the parent:

{if {segment_2} == '' OR {exp:segment_search keyword="/^P\d+$/" segments="2" regex="yes"}}
    {embed=template-group/search-results group_id="{if segment_1 == "foo"}6{/if}{if segment_1 == "bar"}7{/if}" query=""}
{if:else}
    {embed=template-group/search-results group_id="{if segment_1 == "foo"}6{/if}{if segment_1 == "bar"}7{/if}" query='query="{segment_2}"'}
{/if}

And in the embed template:

    {exp:low_search:results
        group_id="{embed:group_id}"
        {embed:query}
        limit="4"
        paginate="bottom"}

        {title}

    {/exp:low_search:results}

Note: for the first embed, query will be an empty string which is fine to pass as a parameter.

  • Setting the query to a blank string is wrong. It will output different results from not setting the query param at all. That is why you see in my code that I am checking if I should set query param or not. Otherwise, I could simply do query="{if segment_2}{segment_2}{/if}" – arvinsim Jul 11 '13 at 2:58
  • I've amended the embed example to accommodate this. – Peter Lewis Jul 11 '13 at 8:15

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.