I have a simple plugin that runs a query and returns a single value.

{exp:company_id id='{segment_3}'}

This outputs a number such as 5081

If I do this:

{preload_replace:cid="{exp:company_id id='{segment_3}'}"}


It works as well.

If I drop either {cid} or {exp:company_id id='{segment_3}'} into a query

    {exp:query sql="select field_id_10 as facebook, field_id_11 as twitter, field_id_13 as linkedin, field_id_15 as youtube from exp_channel_data where field_id_4 = '{exp:company_id id='{segment_3}'}'" parse="inward"}

Either using parse inward or not ... or using the preload or plugin the value in debugging shows : M00o93H7pQ09L8X1t49cHY01Z5j4TT91fGfr

I am a bit stumped at this point. Any pointers would be much appreciated.


Taking Advice Below I got this to work both ways: {exp:company_id id="123456"}{/exp:company_id} and {exp:company_id}{segment_3}{/exp:company_id}

var $return_data;

function company_id()
    $this->EE =& get_instance();
    $tagdata = $this->EE->TMPL->tagdata; 
    $id = ($this->EE->TMPL->fetch_param('id')) ? $this->EE->TMPL->fetch_param('id') : $this->EE->TMPL->tagdata ;

    $id = $this->_get_id($id);
    $this->return_data = $id;

function _get_id($id)
    // Query
    $this->results = $this->EE->db->query('SELECT company_id FROM '.$this->EE->db->dbprefix('jobs').' WHERE job_id = '.$id.' LIMIT 1');

    if($this->results->num_rows() == 0) :
        if($this->errors == 'false') :
            return null;
        else :
            return null;
    else :
        return $this->results->row('company_id');

There are a few possible solutions available here:

1. Global variable approach

Amend your plugin so that it sets a global variable instead of/as well as returning the value directly. This ensures that it is parsed very early so you can use it as {cid} in tag parameters. You can set a global EE variable like this in your plugin:

$this->EE->config->_global_vars['cid'] = 123;

You'd still need to call the plugin once in a template for the variable to be set. If you'd rather keep it clean and not do that you'd simply need to make it into an extension instead, probably using the sessions_end or template_fetch_template hooks.

2. Tag pair approach

You could amend your plugin to work as a tag pair so that you can wrap it around any other EE tags and therefore get the parse order right.


public function __construct() {      
  $this->EE =& get_instance();
  $tagdata = $this->EE->TMPL->tagdata;
  $id = $this->EE->TMPL->fetch_param('id');

  $vars[0] = array('cid' => 123);

  $tagdata = $this->EE->TMPL->parse_variables($tagdata, $vars);
  return $tagdata;

You would then use the plugin as a tag pair and {cid} would be available on the inside.

3. Create a new plugin method

If you're comfortable making a plugin to do the job of fetching the company id, it seems odd to use the query module for this when you could just combine your methods together into a single plugin, so you'd have {exp:your_site:company_id} and {exp:your_site:company_social_links}

4. Use the channel:entries search parameter combined with one of the above

If you take the first or second approaches numbered above, could you not use a simple channel:entries tag with the search parameter instead of a query tag? Eg:

{exp:channel:entries search:cf_company_id="={cid}" ...}
   {cf_twitter}|{cf_facebook} etc

This wouldn't perform as well as the query module but is a bit cleaner and less fiddly.

5. Stash

Stash is an answer for everything these days, and there's probably a way you could do some template gymnastics to make it work in pretty much the same way you're attempting to with the preload_replace. The complexity would probably outweigh the benefit however.


I should also point out that (whilst I don't know exactly what you're aiming for), you need to be quite careful from a security point of view that you don't allow users to hack your urls, since you're directly passing segment_3 into your plugin. Without the proper precautions this could allow people to view other companies' data by changing numbers in the urls.

  • I went down Path 2 as you suggested. I posted an update above. I couldn't get it to work exactly like you had for syntax. I will look at approach 3 as you recommended as that seems like a better solution. I don't have a ton of experience with plugins so trying to learn it as I go. Thank you for your very detailed response. I truly appreciate it. Apr 22 '13 at 0:33
  • Let us know how you get on. I would most recommend approach no.1 above, since it's so simple and you can always be certain that the variable will be fully parsed and available anywhere in your template (just like any standard global variable). Apr 22 '13 at 22:44

Use Active Record instead and it will likely work, as well as being somewhat safer.

  • I tried with that one as well. Same result. Apr 21 '13 at 23:25

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.