Skip to content

Instantly share code, notes, and snippets.

@jeremyworboys
Created September 23, 2012 02:42
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jeremyworboys/3768630 to your computer and use it in GitHub Desktop.
Save jeremyworboys/3768630 to your computer and use it in GitHub Desktop.
{exp:query sql="
SELECT md.entry_id, cd.field_id_56, md.col_id_48
FROM exp_matrix_data AS md
LEFT JOIN exp_playa_relationships AS pr
ON md.entry_id = pr.parent_entry_id
LEFT JOIN exp_channel_data AS cd
ON pr.child_entry_id = cd.entry_id
WHERE md.field_id = 123
AND md.row_order = 1
GROUP BY md.entry_id
ORDER BY md.entry_id ASC"}
{exp:stash:set name="phone_{entry_id}" cache="no"}{if col_id_48}{col_id_48}{if:else}{field_id_56}{/if}{/exp:stash:set}
{/exp:query}
<ul>
{exp:channel:entries channel="channel_name" sort="asc" limit="250" disable="categories|category_fields|member_data|pagination"}
<li>
<div class="info">
<p class="contactInfo">
{exp:stash:get name="phone_{entry_id}" cache="no"}<br/>
<a href="mailto:{emp_email}">{emp_email}</a>
</p>
</div>
</li>
{/exp:channel:entries}
</ul>
<ul>
{exp:channel:entries channel="channel_name" sort="asc" limit="250" disable="categories|category_fields|member_data|pagination"}
<li>
<div class="info">
<p class="contactInfo">
{contact limit="1"}
{if direct_phone}
{direct_phone}
{if:else}
{office}
{office_phone}
{/office}
{/if}
{/contact}<br/>
<a href="mailto:{emp_email}">{emp_email}</a>
</p>
</div>
</li>
{/exp:channel:entries}
</ul>

Channel Fields

contact is a matrix with 3 columns: office, direct_phone, direct_fax
direct_phone & direct_fax are text fields
office is a single select playa field
office_phone is a text input on the offices channel

SQL Explanation

SELECT     md.entry_id,                               # Get the {entry_id} from matrix_data,
           cd.field_id_56,                            # {office_phone} from channel_data and
           md.col_id_48                               # {direct_phone} from matrix_data
FROM       exp_matrix_data AS md                      # 
LEFT JOIN  exp_playa_relationships AS pr              # 
ON         md.entry_id = pr.parent_entry_id           # 
LEFT JOIN  exp_channel_data AS cd                     # 
ON         pr.child_entry_id = cd.entry_id            # 
WHERE      md.field_id = 123                          # where the matrix field is {office}
AND        md.row_order = 1                           # and only grab the first row.
GROUP BY   md.entry_id                                # This prevents extra columns from playa_relationships.
ORDER BY   md.entry_id ASC                            # Order by {entry_id}

Stash

I check if the person has a direct_phone and, if so, store it in Stash. If not, store the office_phone from the office they are in.

I am using cache="no" so the Stash vars aren't written to and read from the DB.

Conclusion

This method reduced the number of queries on this page from ~800 down to ~40 per (uncached) page load.

@eheiser
Copy link

eheiser commented Sep 24, 2012

Just one question, in after.html : is this all in the same template?
Is the exp:query parsed before the channel:entries loop then?

@jeromecoupe
Copy link

If I remember Low's Parse Order presentation well, modules {exp:tags} are parsed in the order they are in the template. If nested the parser deals with them from the root of the document inwards

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment