0

I'm finding that if I use a module tag like stash or playa as a parameter in a plugin tag, that an extra query for the module name is run for each loop. Here's the query that's run:

SELECT `module_version`, `module_name`
FROM (`exp_modules`)

From what I can tell, it's EE looking up the module so that it can parse it's tags. Here's some example template code that's generating the extra queries. This example uses a channel entries loop and a playa tag as a parameter but using another module tag like stash with just a string of ids 1|2|3|4 will do the same thing. The sp_within plugin is a custom plugin I've written however I've tried this with other plugins and the same thing occurs.

{exp:channel:entries channel="professions" orderby="title" dynamic="no" sort="asc" disable="custom_fields|categories|member_data|pagination"}
    {exp:sp_within haystack='{exp:playa:child_ids field="member_profession" entry_id="{zoo_visitor_id}"}' needle='{entry_id}' parse="inward"}
        <label><input name="member_profession[selections][]" value="{entry_id}" type="checkbox"{if within} checked="checked"{/if}> {title}</label>
    {/exp:sp_within}
{/exp:channel:entries}

Edit Here's a clearer example that just uses a channel entry loop and a stash variable.

{exp:stash:set name="selected_ids"}94|2|45|87{/exp:stash:set}

{exp:channel:entries channel="professions" dynamic="no" disable="custom_fields|categories|member_data"}
    {exp:sp_within haystack='{exp:stash:selected_ids}' needle='{entry_id}' parse="inward"}
        <label><input name="member_profession[selections][]" value="{entry_id}" type="checkbox"{if within} checked="checked"{/if}> {title}</label>
    {/exp:sp_within}
{/exp:channel:entries}

Can I cache the query for the module name in my sp_within plugin? It's okay when there's only a few extra queries but it gets a bit ridiculous when there's 20 plus. Does anyone know how to remove the extra queries?

3 Answers 3

1

Instead of using your plugin as a parameter, you can wrap the entire channel:entries tag inside your own plugin, and then just search-replace {custom_value}, a single variable, with the data you want to insert in the inner tags parameter. (parse=inward so that the outer tag-pair is parsed first)

{exp:custom_plugin:method parse="inward"}
  {exp:channel:entries channel="products" 
    entry_id="{custom_value}" status="wide" 
  }
    <h3>{title}</h3>
  {/exp:channel:entries}
{/exp:custom_plugin:method}

e.g.: Entry ID Returned From Plug-In Not Working in Channel Entries Tag

0

That's because you're telling it to loop multiple times. The outer Channel Entries tag is a loop so it will loop through all results defined by the filtering criteria. Then You're calling in your plugin and passing in the Playa Child ID's tag which also produces a full loop to provide a single parameter to your plugin. Anything with tag pairs will loop. You're also passing in dynamic variables as attribute values so all in all that will produce quite a lot of queries to even return a small number of entries.

Using Stash will help to cut this down but obviously the loop(s) would still need to run at least once to have the value available to pass on to your plugin. So in that case you'll probably need to set some nested Stash results to run the Channel Entries tag and the Playa Child IDs tag. Then Stash those results and call your plugin later on (outside of that loop). The first time it's run it may well result in the same number of queries but after that you should see a noticeable reduction.

4
  • Thanks Ian but that's not the problem. I'm using stash and already have all my other queries optimised which is why I've noticed that I'm getting these extra queries for the module name. I'm trying to establish if I can avoid that particular query. Sorry if my question wasn't clear.
    – Dylan
    Commented Apr 22, 2013 at 8:05
  • OK, I think I understand. To be honest the first query where the module is being selected from the modules table sounds like normal behaviour and I'm not sure you can cut remove that at all. Certainly from what I see of the loop in the templates though that can be optimised quite a lot. I can't see how you're using Stash in combination with that nested loop as you haven't included it but a 'template partials' approach is mainly for the benefit of a more efficient way of templating more akin to the Ruby methodology or modern PHP template languages.
    – Ian Young
    Commented Apr 22, 2013 at 8:18
  • I probably posted a bad example. I didn't show my template using stash as I thought it would complicate things when stash isn't the cause of the problem. I'll post a stripped down example.
    – Dylan
    Commented Apr 22, 2013 at 8:58
  • Actually, it's probably because you're calling your plugin within the Channel Entries loop so for each iteration it will make the same queries. Can you not Stash your Channel Entries loop too and then call the results of that into your plugin call?
    – Ian Young
    Commented Apr 22, 2013 at 11:24
0

This appears to be a limitation of using module tags as a parameter of any tag that produces a loop. I found two ways to avoid using the module tag as a parameter and therefore the additional queries for the module name.

1. Set the stash type parameter to snippet

This my preferred approach.

{exp:stash:set name="sn_selected_ids" type="snippet"}94|2|45|87{/exp:stash:set}

{exp:stash:parse process="end"}
   {exp:channel:entries channel="professions" dynamic="no" disable="custom_fields|categories|member_data"}
       {exp:sp_within haystack='{sn_selected_ids}' needle='{entry_id}'}
           <label><input name="member_profession[selections][]" value="{entry_id}" type="checkbox"{if within} checked="checked"{/if}> {title}</label>
       {/exp:sp_within}
   {/exp:channel:entries}
{/exp:stash:parse}

2. Enable PHP in your template

{exp:stash:set name="selected_ids"}94|2|45|87{/exp:stash:set}
{exp:channel:entries channel="professions" dynamic="no" disable="custom_fields|categories|member_data"}
    <?php
        $haystack = '{exp:stash:selected_ids}';
        $haystack = explode('|', $haystack);
        $in_array = array_search('{entry_id}', $haystack);
    ?>
    <label><input name="member_profession[selections][]" value="{entry_id}" type="checkbox"<? if ($in_array !== false) echo ' checked="checked"' ?>>{title}</label>
{/exp:channel:entries}
1
  • So it's just the query where it selects the module name and version that you're trying to eliminate? That may very well just be part and parcel of calling in the plugin. If it's eliminated using regular PHP then that's half proved. Do other plugins/extensions generate the same query when called? If so then that would possibly suggest that it can't be eliminated as it's part and parcel of the template parser.
    – Ian Young
    Commented Apr 22, 2013 at 9:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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