<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Luke Carbis</title>
	<atom:link href="http://lukecarbis.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://lukecarbis.com/blog</link>
	<description>It's more complicated than 42.</description>
	<lastBuildDate>Mon, 07 Nov 2011 20:16:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>How to order by post meta item without setting meta_key in WordPress</title>
		<link>http://lukecarbis.com/blog/2011/11/how-to-order-by-custom-meta-item-without-setting-meta_key-in-wordpress/</link>
		<comments>http://lukecarbis.com/blog/2011/11/how-to-order-by-custom-meta-item-without-setting-meta_key-in-wordpress/#comments</comments>
		<pubDate>Mon, 07 Nov 2011 06:58:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://lukecarbis.com/blog/?p=727</guid>
		<description><![CDATA[Problem: I wanted wp_query to sort by a custom meta item, but I also wanted it to include results that don't have that meta item assigned to them! When I use the built in 'orderby =&#62; 'meta_value', it requires me to set 'meta_key' =&#62; 'something' - and that won't include results that don't have that [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Problem:</strong> I wanted wp_query to sort by a custom meta item, but I also wanted it to include results that don't have that meta item assigned to them! When I use the built in <em>'orderby =&gt; 'meta_value'</em>, it requires me to set <em>'meta_key' =&gt; 'something'</em> - and that won't include results that don't have that meta_key assigned.</p>
<p><strong>Solution:</strong> I found some query filters that let me edit the SQL of the query, after all my other arguments have been considered. This means I can use an <em>INNER JOIN</em> and a different <em>ORDER BY</em> value to achieve the result I'm after. Here's the poetry:</p>
<div id="wpshdo_1" class="wp-synhighlighter-outer"><div id="wpshdt_1" class="wp-synhighlighter-expanded"><table border="0" width="100%"><tr><td align="left" width="80%"><a name="#codesyntax_1"></a><a id="wpshat_1" class="wp-synhighlighter-title" href="#codesyntax_1"  onClick="javascript:wpsh_toggleBlock(1)" title="Click to show/hide code block">Source code</a></td><td align="right"><a href="#codesyntax_1" onClick="javascript:wpsh_code(1)" title="Show code only"><img border="0" style="border: 0 none" src="http://lukecarbis.com/blog/wp-content/plugins/wp-synhighlight/themes/default/images/code.png" /></a>&nbsp;<a href="#codesyntax_1" onClick="javascript:wpsh_print(1)" title="Print code"><img border="0" style="border: 0 none" src="http://lukecarbis.com/blog/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png" /></a>&nbsp;<a href="http://lukecarbis.com/blog/wp-content/plugins/wp-synhighlight/About.html" target="_blank" title="Show plugin information"><img border="0" style="border: 0 none" src="http://lukecarbis.com/blog/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif" /></a>&nbsp;</td></tr></table></div><div id="wpshdi_1" class="wp-synhighlighter-inner" style="display: block;"><pre class="php" style="font-family:monospace;"><ol><li class="li1"><div class="de1"><span class="kw2">&lt;?php</span></div></li><li class="li1"><div class="de1">add_filter<span class="br0">&#40;</span> <span class="st_h">'posts_clauses'</span><span class="sy0">,</span> <span class="st_h">'my_custom_order_function'</span><span class="sy0">,</span> 20<span class="sy0">,</span> 1 <span class="br0">&#41;</span><span class="sy0">;</span></div></li><li class="li1"><div class="de1"><span class="kw2">function</span> my_custom_order_function<span class="br0">&#40;</span> <span class="re0">$pieces</span> <span class="br0">&#41;</span> <span class="br0">&#123;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">    <span class="re0">$pieces</span><span class="br0">&#91;</span><span class="st_h">'join'</span><span class="br0">&#93;</span> <span class="sy0">.=</span> <span class="st0">&quot; INNER JOIN (SELECT meta_id, post_id, meta_key, meta_value FROM wp_postmeta ORDER BY CASE meta_key WHEN 'custom_meta' THEN 1 ELSE 2 END ASC, meta_value ASC) AS cm1 ON (wp_posts.ID = cm1.post_id)&quot;</span><span class="sy0">;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">    <span class="re0">$pieces</span><span class="br0">&#91;</span><span class="st_h">'orderby'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="st0">&quot;CASE cm1.meta_key WHEN 'custom_meta' THEN 1 ELSE 2 END, cm1.meta_value ASC, wp_posts.post_title ASC&quot;</span><span class="sy0">;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1">    <span class="kw1">return</span> <span class="re0">$pieces</span><span class="sy0">;</span></div></li><li class="li1"><div class="de1">&nbsp;</div></li><li class="li1"><div class="de1"><span class="br0">&#125;</span></div></li><li class="li1"><div class="de1"><span class="sy1">?&gt;</span></div></li></ol></pre></div></div>
<p>Okay, so basically what we're doing here as adding a second postmeta table (the first is already added so that wp_query can handle meta queries), but before it's joined, we order it using MySQL's CASE order. This puts the meta_key we're looking for at the top of the JOIN, so if it exists, it will be that meta_key that is linked to our results.</p>
<p>Once we have joined the table, we just need to order by the join - again we do this using CASE, to put the results in the right order - items with our meta_key go first, and everything else second. We also do a secondary ORDER so that the items with the right meta_key also get ordered by meta_value.</p>
<p>It's important that you only use this code in context - pasting it in as is will force it to apply to every single query that is run on each page - and you probably don't want that.</p>
<p>If anyone can suggest a better way of doing it, or if there's something I missed, please let me know in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://lukecarbis.com/blog/2011/11/how-to-order-by-custom-meta-item-without-setting-meta_key-in-wordpress/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

