I've created a plugin that gets the entry_id's of the most popular selling items in the exp:resso store. I'd like to extend it by letting a user loop through each of those entries and output them on the page (much like the standard {exp:channel:entries} loop.

I can't find any documentation about how to pull together the right information within my plugin as in the example below.

At the moment my template tag:

{exp:expresso_store_most_popular_items category="2" limit="3"}

Exports a list of entry_id's of the most popular products eg:


How do I export each entry_id in such a way that i can be used as a tag {entry_id} in a loop such as in the example below:

{exp:expresso_store_most_popular_items category="2" limit="3"}
    {exp:store:product entry_id="{entry_id}"}

Any pointers much appreciated, thanks in advance.


2 Answers 2


There are a couple of ways to create plugins which return entry IDs like that.

The first, and most obvious, is for your plugin to return a pipe-separated list of entries, which is then passed to a channel entries tag. In your plugin file:

$tag_vars = array(array('search_entry_ids' => '4|6|12|19'));
$this->return_data = $this->EE->TMPL->parse_variables($this->EE->TMPL->tagdata, $tag_vars);

This can then be used in a template with the help of parse="inward":

{exp:my_plugin parse="inward"}
    {exp:channel:entries fixed_order="{search_entry_ids}"}
        <!-- results -->

Note I used the fixed_order paramter here. It behaves exactly the same as the entry_id="" parameter, except it keeps entries in the order you specify.

The other, slightly more cunning alternative is to actually extend the channel entries plugin. For example, this is what we do with the Store Search tag.

In your plugin, generate the same pipe-separated list of entry IDs. Then, load the channel entries tag and pass over handling to it:

$search_entry_ids = '4|6|12|19';

if (empty($search_entry_ids))
    return $this->EE->TMPL->no_results;

// save our results into the fixed_order parameter
$this->EE->TMPL->tagparams['fixed_order'] = $search_entry_ids;

// load channel entries tag
if ( ! class_exists('Channel'))

// let channel entries tag do all the hard work
$channel = new Channel();
$this->return_data = $channel->entries();

Now people using your plugin don't have to worry about parsing or any messy variables:

    <!-- all variables which work inside exp:channel:entries work here -->

Credit: I originally got this idea from this helpful gist.

  • Great answer! Many thanks Adrian - the tagparams & no results methods are exactly what I was looking for. I've included the Channel tag and my loop is working well.
    – Tomtids
    Commented Feb 4, 2013 at 15:28

The entry ids should be pipe separated like 12|13|2 and simply use the code like:

{exp:store:product entry_id="{exp:expresso_store_most_popular_items category='2' limit='3'}" parse="inward"}

It would be fine if you can share your query here which you are using within the plugin expresso_store_most_popular_items.

  • Thanks BKY, that is a workable solution which I may well end up using. I was really hoping to learn a little more about how I can set up tags within my plugin for use in a template loop.
    – Tomtids
    Commented Feb 4, 2013 at 14:14

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.