<?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>kristarella.com &#187; Tutorials</title> <atom:link href="http://www.kristarella.com/category/tutorials/feed/" rel="self" type="application/rss+xml" /><link>http://www.kristarella.com</link> <description>Website of photography loving, mac-using, Christian molecular biology graduate working in web design.</description> <lastBuildDate>Fri, 20 Jan 2012 21:42:24 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <item><title>WordPress Child Themes and Thesis</title><link>http://www.kristarella.com/2010/10/wordpress-child-themes-and-thesis/</link> <comments>http://www.kristarella.com/2010/10/wordpress-child-themes-and-thesis/#comments</comments> <pubDate>Mon, 04 Oct 2010 08:13:26 +0000</pubDate> <dc:creator>kristarella</dc:creator> <category><![CDATA[Tutorials]]></category> <category><![CDATA[Thesis]]></category> <category><![CDATA[tutorial]]></category> <category><![CDATA[WordPress]]></category><guid
isPermaLink="false">http://www.kristarella.com/?p=4013</guid> <description><![CDATA[Years ago, two branches of WordPress theme customisation began: there was the custom CSS approach, where you used a custom CSS file to override styles in style.css and localise your changes, and there were child themes. As far as I can tell these were both in development around the same time: people realised there needed [...]]]></description> <content:encoded><![CDATA[<p></p><p>Years ago, two branches of WordPress theme customisation began: there was the custom CSS approach, where you used a custom CSS file to override styles in style.css and localise your changes, and there were child themes. As far as I can tell these were both in development around the same time: people realised there needed to be a better way to customise themes, and as that progressed we got theme frameworks and so on.</p><p>Now theme frameworks are abundant and we&#8217;re all trying to find the most efficient way to customise them. I&#8217;ve been using the custom CSS and functions file method for a while; first with the Copyblogger theme and then with <a
href="http://www.shareasale.com/r.cfm?B=198392&#038;U=403481&#038;M=24570">Thesis</a>. I like it; I find it to be a quick and simple way of doing things. However, recently I&#8217;ve been seeing the advantages of child themes over custom files, particularly when using WordPress Networks (previously known as <abbr
title="WordPress Multi User">WPMU</abbr>, sometimes now referred to as <abbr
title="WordPress Multi Site">WPMS</abbr>).<br
/> <span
id="more-4013"></span><br
/> I&#8217;ve used child themes briefly with the Hybrid theme and others. Recently I started working on a <a
onclick="window.open(this.href); return false;" href="http://diythemes.com/forums/showthread.php?39175-New-attempt-at-BuddyPress-child-theme">BuddyPress child theme for Thesis</a> <small>(needs a DIYthemes login to access the forum thread)</small>. The BuddyPress theme compatibility plugin is pretty great, but for really smooth integration and to avoid pain when upgrading Thesis, a child theme is really the only way to go. That got me thinking that <strong>child themes would be a much simpler way of using Thesis across multiple networked sites</strong> with different customisations, without having to <a
href="http://www.kristarella.com/2009/09/using-thesis-with-wpmu/">edit Thesis as I&#8217;ve done before</a>. Instead of creating a new custom folder for each site, you create a new child theme and activate the child theme instead of Thesis.</p><p>You can check out the <a
href="http://codex.wordpress.org/Child_Themes">WordPress Codex</a> for the basics of child theme development, but there are a couple of things to note when making child themes for Thesis:</p><ol><li>If you <strong>leave the <tt>custom-sample</tt> folder in tact</strong> when installing Thesis (instead of changing its name to &#8220;custom&#8221;) it will act as a fallback custom folder. If <tt>custom.css</tt> and <tt>layout.css</tt> are not found in a <tt>custom</tt> folder in your child theme there will be errors because the files won&#8217;t be found, but with <tt>custom-sample</tt> as a fallback, there won&#8217;t be. You can duplicate <tt>custom-sample</tt> and have both a <tt>custom</tt> and <tt>custom-sample</tt> folders in your main Thesis folder if needed.</li><li>Copy a duplicate of the <tt>custom-sample</tt> folder to your child theme folder and name it &#8220;custom&#8221;. I don&#8217;t think it&#8217;s essential to keep using the custom folder structure in your child theme, but I highly recommend it, because you&#8217;ll have a unique copy of <tt>layout.css</tt> for each site for the Design Options to be written to, and a <tt>cache</tt> folder for that site&#8217;s thumbnails.</li><li>You need to specify a template for your child theme (in <tt>style.css</tt>, e.g., <code>Template: thesis</code> and the template name is the folder name of the parent theme. So to avoid having to change the template name every time you upgrade Thesis you may want to <strong>name your thesis folder something generic</strong> rather than keeping the version number in the folder name.</li><li>You need to <strong>import Thesis&#8217; <tt>style.css</tt></strong> to use in the child theme you can do that in one of two ways<ul><li>add this to the top of <tt>style.css</tt> (note that the Thesis folder name is important here as well)</p><pre>@import url(../thesis/style.css);</pre></li><li>or by add the following to the child theme&#8217;s <tt>functions.php</tt><pre>if(!is_admin())
	wp_enqueue_style( 'thesis-css', get_bloginfo('template_url') . '/style.css', '', false, 'screen,projection' );</pre></li></ul></li><li>It&#8217;s important to notice that the <strong>child theme&#8217;s functions.php is loaded before the parent</strong> theme&#8217;s. This impacts interaction with Thesis in a few ways. The first I noticed was that constants such as <code>THESIS_CUSTOM_FOLDER</code> are not defined yet, so if you&#8217;re in the habit of locating images in the custom folder using that constant (as I am) it won&#8217;t work. Also Thesis classes (i.e., PHP classes, such as those that control the loop API) are not loaded yet, so if you are writing custom loops with the loop API you need to address this. There are multiple ways to go about it:<ul><li>The simplest way I found was to add this line to the top of <tt>functions.php</tt></p><pre>include_once(TEMPLATEPATH.'/functions.php');</pre><p>I don&#8217;t know if there are any caveats to doing it this way, but I haven&#8217;t come across any problems with it so far.</li><li>Use <tt>custom/custom_functions.php</tt> instead of <tt>functions.php</tt>: if it exists, <tt>custom/custom_functions.php</tt> should be included by the Thesis <tt>functions.php</tt> file when it is run.</li><li>Wrap all of the code you want to use that interacts with Thesis into a function that hooks into <code>after_setup_theme</code>, which is run by WordPress right after the child and parent theme functions.php files have been loaded.</li></ul></ol><p>Beyond that my use of child themes with Thesis has been pretty smooth sailing.</p><p>Let me know if you use them and what some of your tips are!</p> ]]></content:encoded> <wfw:commentRss>http://www.kristarella.com/2010/10/wordpress-child-themes-and-thesis/feed/</wfw:commentRss> <slash:comments>42</slash:comments> </item> <item><title>Thesis Squeeze and Landing Pages</title><link>http://www.kristarella.com/2010/09/thesis-squeeze-and-landing-pages/</link> <comments>http://www.kristarella.com/2010/09/thesis-squeeze-and-landing-pages/#comments</comments> <pubDate>Tue, 14 Sep 2010 19:05:52 +0000</pubDate> <dc:creator>kristarella</dc:creator> <category><![CDATA[Tutorials]]></category> <category><![CDATA[featured]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Thesis]]></category><guid
isPermaLink="false">http://www.kristarella.com/?p=4001</guid> <description><![CDATA[Thesis 1.8 has lots of great new features, but one of the less publicised ones is the range of filters that has been extended. These filters make it possible to customise even more of Thesis&#8217; output without modifying core files. Previously, squeeze pages or landing pages that varied significantly from the rest of your site&#8217;s [...]]]></description> <content:encoded><![CDATA[<p></p><p>Thesis 1.8 has lots of great new features, but one of the less publicised ones is the range of filters that has been extended. These filters make it possible to customise even more of Thesis&#8217; output without modifying core files.</p><p>Previously, squeeze pages or landing pages that varied significantly from the rest of your site&#8217;s layout might have needed a custom template, a whole new page template, or a bit of a fudge by hiding parts of the page with CSS. Now, it&#8217;s really easy to selectively remove the header, sidebars and footer.<br
/> <span
id="more-4001"></span></p><h3 id="blank-squeeze-page">Squeeze Page</h3><p>To get the simplest squeeze page possible: no header, sidebars or footer. Paste the following PHP in <tt>custom_functions.php</tt>. <small>This code is a modification of code found in the DIYthemes forum.</small></p><pre>function custom_remove_defaults($content) {
        return false;
}

function apply_custom_filters() {
    if (is_page('Squeeze Page')) {
		add_filter('thesis_show_header', 'custom_remove_defaults');
		add_filter('thesis_show_sidebars', 'custom_remove_defaults');
		add_filter('thesis_show_footer', 'custom_remove_defaults');
	}
}
add_action('template_redirect','apply_custom_filters');</pre><p>The first function is the filter that returns &#8220;false&#8221; instead of returning the content that would normal be there (in the header, or footer, or sidebar). Read more about <a
href="http://diythemes.com/thesis/rtfm/customizing-with-filters/">filters in the Thesis user manual</a>.</p><p>The second function selects the page on which to apply the filter and then applies the filter to the header, sidebars and footer, just before Thesis loads on that page. Change &#8220;Squeeze Page&#8221; in <code>if (is_page('Squeeze Page'))</code> to the title of your squeeze page. If you want to filter multiple pages you can add their names as an array. E.g., <code>if (is_page(array('Squeeze Page','Second Squeeze Page','Magical Landing Page')))</code>.</p><h4 id="automatic-squeeze-pages">Easily assign many squeeze pages</h4><p>To more easily assign pages as squeeze pages, when you&#8217;re creating the page you can add a custom field to the page and have your custom function detect it. Change the code in <tt>custom_functions.php</tt> to the following.</p><pre>function custom_remove_defaults($content) {
        return false;
}

function apply_custom_filters() {
	global $wp_query;
	$squeeze = get_post_meta($wp_query->post->ID, 'squeeze-page', true);
	if ($squeeze) {
		add_filter('thesis_show_header', 'custom_remove_defaults');
		add_filter('thesis_show_sidebars', 'custom_remove_defaults');
		add_filter('thesis_show_footer', 'custom_remove_defaults');
	}
}
add_action('template_redirect','apply_custom_filters');</pre><p>Then when creating or editing your squeeze page add a custom field with the name &#8220;squeeze-page&#8221; and any value (it doesn&#8217;t matter what the value is because we only use the name).</p><p><a
href="http://www.kristarella.com/wp-content/uploads/squeeze-page-custom-field.png"><img
src="http://www.kristarella.com/wp-content/uploads/squeeze-page-custom-field-500x201.png" alt="" title="Squeeze Page Custom Field" width="500" height="201" class="aligncenter size-large wp-image-4002" /></a></p><p>Using this set up, every page with this custom field will have the header, footer and sidebars removed.</p><p>These pages can be styled individually by using the page name body class, or styled together using a body class filter. See <a
href="http://diythemes.com/thesis/rtfm/custom-css-classes-posts-pages/">Using Custom CSS Classes for Posts and Pages</a> and the body class filter in the landing page code below.</p><h3 id="different-sidebar">Landing pages with different sidebars</h3><p>To present a different sidebar on squeeze or landing pages you could use the <a
href="http://wordpress.org/extend/plugins/widget-logic/">Widget Logic</a> or <a
href="http://wordpress.org/extend/plugins/dynamic-widgets/">Dynamic Widgets</a> plugins to designate which pages widgets should be displayed on, but if you have many landing pages, or many widgets, that could be labour intensive. So, you can create a whole new sidebar that gets displayed according to the page name or custom field assignment, like the squeeze page filters above. Widgets in these sidebars will only be displayed on your landing pages.</p><p>The following code for a landing page &#8212; without header, original sidebars and footer and with new sidebars added &#8212; goes in <tt>custom_functions.php</tt>. <small>Note: I&#8217;m using different variables and custom field names than in the code above, so pay attention if trying to mix and match the code.</small></p><p
class="note"><strong>Update 25<sup>th</sup> October 2010:</strong> Added <code>id</code> parameter to <code>register_sidebars()</code> and changed IDs in <code>thesis_default_widget()</code> to avoid confusion with other registered widget areas with sequentially numbered IDs.<br
/> <strong>Update 3<sup>rd</sup> November 2011:</strong> Edited the &#8216;name&#8217; parameter in <code>register_sidebars</code> to fix disappearing widgets problem.</p><pre>function custom_body_classes($classes) {
	$classes[] = &quot;landing-page&quot;;

	return $classes;
}

function custom_remove_defaults($content) {
        return false;
}

register_sidebars(2,
    array(
        'name' =&gt; sprintf(__('Landing Page %d'), $i ),
        'id' =&gt; 'landing-page-$i',
        'before_widget' =&gt; '&lt;li class=&quot;widget %2$s&quot; id=&quot;%1$s&quot;&gt;',
        'after_widget' =&gt; '&lt;/li&gt;',
        'before_title' =&gt; '&lt;h3&gt;',
        'after_title' =&gt; '&lt;/h3&gt;'
    )
);

function landing_page_sidebar() {
?&gt;
&lt;/div&gt; &lt;!-- custom end #content --&gt;
&lt;div id=&quot;sidebars&quot;&gt;
	&lt;div id=&quot;sidebar_1&quot; class=&quot;sidebar&quot;&gt;
		&lt;ul class=&quot;sidebar_list&quot;&gt;
			&lt;?php thesis_default_widget('landing-page-1'); ?&gt;
		&lt;/ul&gt;
	&lt;/div&gt;
	&lt;div id=&quot;sidebar_2&quot; class=&quot;sidebar&quot;&gt;
		&lt;ul class=&quot;sidebar_list&quot;&gt;
			&lt;?php thesis_default_widget('landing-page-2'); ?&gt;
		&lt;/ul&gt;
	&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt; &lt;!-- balance out #content divs --&gt;
&lt;?php
}

function apply_custom_filters() {
	global $wp_query;
	$landing = get_post_meta($wp_query-&gt;post-&gt;ID, 'landing-page', true);
	if ($landing) {
		// remove unwanted sections
		add_filter('thesis_show_header', 'custom_remove_defaults');
		add_filter('thesis_show_sidebars', 'custom_remove_defaults');
		add_filter('thesis_show_footer', 'custom_remove_defaults');
		//add custom body class
		add_filter('thesis_body_classes','custom_body_classes');
		// add new sidebars
		add_action('thesis_hook_after_content','landing_page_sidebar');
	}
}
add_action('template_redirect','apply_custom_filters');</pre><p>This code does the following to pages with a custom field named &#8220;landing-page&#8221;.</p><ul><li>adds a body class of &#8220;landing-page&#8221;</li><li>removes the header, sidebars, and footer</li><li>registers 2 new sidebars called Landing Page 1 and Lading Page 2</li><li>builds the code for the new sidebars (note that an extra <code>&lt;/div&gt;</code> and <code>&lt;div&gt;</code> are added because there&#8217;s no hook in between the end of <code>#content</code> and the end of <code>#content_box</code>)</li><li>then implements all of the above before Thesis loads</li></ul><h4 id="editing-sidebar-markup">Editing the sidebars</h4><p>If you only have one sidebar, you can remove the <abbr>HTML</abbr> for the second sidebar by deleting</p><pre>	&lt;div id=&quot;sidebar_2&quot; class=&quot;sidebar&quot;&gt;
		&lt;ul class=&quot;sidebar_list&quot;&gt;
			&lt;?php thesis_default_widget('landing-page-2'); ?&gt;
		&lt;/ul&gt;
	&lt;/div&gt;</pre><p>If you want a sidebar | content | sidebar arrangement, you&#8217;ll need different markup. Ask in the comments.</p><h4 id="landing-page-css">Landing page CSS</h4><p>When you implement the above you will find that the new sidebars are below the content. This is because removing the original sidebars activates the No Sidebar template and makes the content full-width. To fix this we need to find out what the width of <code>#content</code> in your Thesis layout was. Use <a
href="http://www.kristarella.com/2009/02/how-to-use-firebug-for-css/">Firebug in Firefox</a> or Webkit Inspector in Safari or Chrome to find that width by right clicking in the content area and selecting &#8220;Inspect Element&#8221;.</p><p><a
href="http://www.kristarella.com/wp-content/uploads/content-width.png"><img
src="http://www.kristarella.com/wp-content/uploads/content-width-500x113.png" alt="" title="Webkit Inspector #content width" width="500" height="113" class="aligncenter size-large wp-image-4003" /></a></p><p>Then add the width back into <tt>custom.css</tt>.</p><pre>.landing-page .no_sidebars #content {width:51.3em;}</pre><p>Except for adding your content and styling the page, that&#8217;s about it. Content is added as per usual, by editing the page in the WordPress dashboard.</p> ]]></content:encoded> <wfw:commentRss>http://www.kristarella.com/2010/09/thesis-squeeze-and-landing-pages/feed/</wfw:commentRss> <slash:comments>143</slash:comments> </item> <item><title>How I made a post contents menu</title><link>http://www.kristarella.com/2010/06/post-contents-menu/</link> <comments>http://www.kristarella.com/2010/06/post-contents-menu/#comments</comments> <pubDate>Wed, 30 Jun 2010 01:31:38 +0000</pubDate> <dc:creator>kristarella</dc:creator> <category><![CDATA[Tutorials]]></category> <category><![CDATA[Geek]]></category> <category><![CDATA[Javascript]]></category> <category><![CDATA[Websites]]></category><guid
isPermaLink="false">http://www.kristarella.com/?p=3953</guid> <description><![CDATA[When I redesigned kristarella.com I implemented a contents menu that you can see in top right corner of some posts and pages; mainly tutorial posts. This was part of my effort to make the site more navigable. I&#8217;ve had a couple of questions about how I did that, so I&#8217;m going to answer them today. [...]]]></description> <content:encoded><![CDATA[<p></p><p>When I redesigned kristarella.com I implemented a contents menu that you can see in top right corner of some posts and pages; mainly tutorial posts. This was part of my effort to make the site more navigable.</p><p>I&#8217;ve had a couple of questions about how I did that, so I&#8217;m going to answer them today. The menu itself is generated via jQuery. I chose to use javascript to implement the menu because that way the menu would only be generated when it is suitable to do so, and the variety of selectors in jQuery makes it simple to select the content needed.<br
/> <span
id="more-3953"></span><br
/> I thought hard about using javascript in this way, since I generally agree that if it can be done in another language, a server-side language, then it should be. I considered that perhaps a PHP filter on the post contents might be more suitable, and then the menu would be available to those without javascript too. However, in the end I went with javascript because I couldn&#8217;t quite conceptualise how I would do it with PHP, and because I thought this feature is an optional extra, not crucial for the navigation of the site, so it is acceptable to do it in javascript.</p><p><a
href="http://www.kristarella.com/wp-content/uploads/jquery_contents_menu.png"><img
src="http://www.kristarella.com/wp-content/uploads/jquery_contents_menu-500x225.png" alt="" title="jQuery Content Menu" width="500" height="225" class="frame aligncenter size-large wp-image-3954" /></a></p><h3 id="menu-prerequisites">Pre-requisites for the menu to function</h3><h4>Headings with IDs</h4><p>The main pre-req for this menu is that the post or page contain headings with IDs assigned to them. I already had this for quite a few tutorials so that I could link to certain sections of tutorials when I wanted to.</p><p>You can cause a browser to jump to a certain ID by adding <code>#id-name</code> to the end of the URL. This applies to any element on the page, not just headings. For example, if I wanted to send you to the footer of my site I could use a link that looks like <code>&lt;a href="#footer"&gt;Link to footer&lt;/a&gt;</code>.</p><h4>Load jQuery library</h4><p>You also need to have the jQuery library loaded on the page. This can be done in the <code>&lt;head&gt;</code> of the webpage, or before the <code>&lt;/body&gt;</code> tag at the end of the webpage.</p><p>For instructions on how to do this in WordPress see <a
href="http://digwp.com/2009/06/including-jquery-in-wordpress-the-right-way/">Including jQuery in WordPress (the right way)</a> and <a
href="http://digwp.com/2009/06/use-google-hosted-javascript-libraries-still-the-right-way/">Use Google-hosted javascript libraries (&#8230; still the right way)</a>. If you&#8217;re using <a
href="http://www.shareasale.com/r.cfm?B=198392&#038;U=403481&#038;M=24570">Thesis</a>, there are options under the Page Options to include various javascript libraries, as well as options for each post or page (on their editing page) to include the libraries. Selecting a library to be included on the home page under Page Options will cause it to be included on all pages.</p><h3 id="jquery-menu-code">The code</h3><p>This code should be included on the webpage, after the jQuery library has been loaded (either in the <code>&lt;head&gt;</code> or at the end of the page, as long as the jQuery library is loaded first). It can be added directly to the page if wrapped in <code>&lt;script type="text/javascript"&gt;</code> and <code>&lt;/script&gt;</code> tags, or in an external javascript file with a reference such as <code>&lt;script type="text/javascript" src="menu.js"&gt;&lt;/script&gt;</code> (recommended).</p><pre>jQuery(function() {
	var headings = &quot;.format_text h3[id], .format_text h4[id], .format_text h5[id], .format_text h6[id]&quot;;
	if (jQuery(headings).length &gt; 0)
		jQuery(&quot;.single-post .post_box .format_text, .thesography .post_box .format_text&quot;).prepend('&lt;ul id=&quot;toc&quot;&gt;&lt;h3&gt;Contents&lt;/h3&gt;&lt;/ul&gt;');

	jQuery(headings).each(function() {
		var id = jQuery(this).attr(&quot;id&quot;);
		var title = jQuery(this).text();
		jQuery(&quot;.single-post ul#toc, .thesography ul#toc&quot;).append('&lt;li&gt;&lt;a href=&quot;#' + id + '&quot;&gt;' + title + '&lt;/a&gt;&lt;/li&gt;');
	});
});</pre><h4 id="menu-code-explained">The code explained</h4><p>The first line of code opens the function and will run the function when the whole page has loaded.</p><p><code>var headings</code> creates a variable with a comma separated list of the headings the menu might use &#8212; that is, any h3, h4, h5 or h6 headings inside the div with class <code>.format_text</code> (a div containing the main post content in Thesis), and that have IDs (using the <a
href="http://api.jquery.com/category/selectors/attribute-selectors/">jQuery attribute selector</a>).</p><p>The next step of the function is subject to a conditional clause, that it should only run <em>if</em> there are some headings with IDs, i.e., if the <code>headings</code> variable contains something. When there are headings with IDs in the post an unordered list with ID <code>toc</code> and a heading of &#8220;Contents&#8221; is created at the top of the post. In my case, only on pages with a body class of &#8220;single-post&#8221; or &#8220;thesography&#8221; (see the code for <a
href="http://www.kristarella.com/2009/08/page-specific-headers-in-thesis/#filter-body-class">adding body classes</a>).</p><p>For each heading the code collects the ID and the text within that heading, and appends &#8212; to the previously created contents list &#8212; a list item containing a link to that heading.</p><h3 id="further-info">Further info</h3><p>That&#8217;s really about it. I hope you&#8217;ll be able to bend the code to suit your site if you need to, since this is something I came up with that suits my own blog and posting habits.</p><p>I think the biggest things in understanding this chunk of code is getting your head around CSS selectors and jQuery syntax. So, for more info on those check out the <a
href="http://docs.jquery.com/Main_Page">jQuery official documentation</a> and <a
href="http://htmldog.com/guides/cssbeginner/">HTML Dog</a> or <a
href="http://www.tizag.com/cssT/">tizag.com</a> CSS tutorials.</p> ]]></content:encoded> <wfw:commentRss>http://www.kristarella.com/2010/06/post-contents-menu/feed/</wfw:commentRss> <slash:comments>20</slash:comments> </item> <item><title>WordPress 3.0 custom post types, taxonomies &amp; Thesis</title><link>http://www.kristarella.com/2010/06/wordpress-3-0-custom-post-types-taxonomies-thesis/</link> <comments>http://www.kristarella.com/2010/06/wordpress-3-0-custom-post-types-taxonomies-thesis/#comments</comments> <pubDate>Tue, 22 Jun 2010 03:02:56 +0000</pubDate> <dc:creator>kristarella</dc:creator> <category><![CDATA[Tutorials]]></category> <category><![CDATA[featured]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Thesis]]></category> <category><![CDATA[WordPress]]></category><guid
isPermaLink="false">http://www.kristarella.com/?p=3943</guid> <description><![CDATA[With the recent launch of WordPress 3.0 there are loads of sweet new features to dig into. Digging into WordPress has a nice summary of many of the new features. My favourite new features include the custom post types and custom taxonomies (which have been available for a while, but the dashboard management capability has [...]]]></description> <content:encoded><![CDATA[<p></p><p>With the recent launch of WordPress 3.0 there are loads of sweet new features to dig into. <a
href="http://digwp.com/2010/05/guide-new-features-wordpress-3/">Digging into WordPress</a> has a nice summary of many of the new features.</p><p>My favourite new features include the custom post types and custom taxonomies (which have been available for a while, but the dashboard management capability has been fully implemented now). I guess those are slightly more advanced features, I think most users may be more excited by backgrounds, header and menus. As such, Matt Hodder already has a great post about <a
href="http://www.matthodder.com/enable-wordpress-3-0-features-for-the-thesis-theme/">enabling WP 3.0 menus, backgrounds and headers in Thesis</a>.</p><p>Also, there is an issue with the Thesis Custom File Editor in the dashboard, so if you use that a lot definitely check out <a
href="http://thesislab.net/archives/working-around-use_codepress-error-in-wordpress-3-0/">the fix for the use_codepress() error</a>.</p><p>Today I&#8217;m going to cover my favourite new WP 3.0 features.<br
/> <span
id="more-3943"></span></p><h3 id="custom-taxonomies">Custom Taxonomies</h3><p>Taxonomies are ways to classify posts and custom post types. WordPress has had two taxonomies for a long time: categories and tags. You&#8217;ve been able to register custom taxonomies in WordPress for quite a long time and since version 2.7 registering a non-hierarchical taxonomy (similar to tags) has provided a new input box in the post editing screen to assign your custom tag type to posts, but there was no menu item to edit that taxonomy and there was no input support for hierarchical taxonomies (like categories).</p><p>Now, registering a new taxonomy provides the input box on post editing pages and a dashboard menu item to edit the whole taxonomy.</p><p><img
src="http://www.kristarella.com/wp-content/uploads/WP3-CustomTaxonomies.png" alt="" title="WP3 Custom Taxonomies" width="298" height="486" class="frame alignright size-full wp-image-3945" /></p><p>Say you were building a website to document the spread of an infectious zombie-creating disease and wanted to profile and categorise individual zombies&#8230; You could create a custom post type for zombies (covered below) and assign location and infection taxonomies to make it easy to categorise and query where the zombies were sighted, or originated from, and which strain of the infection they have.</p><p>The following code would be posted into <tt>functions.php</tt>, or <tt>custom_functions.php</tt> for <a
href="http://www.shareasale.com/r.cfm?B=198392&#038;U=403481&#038;M=24570">Thesis</a>.</p><pre>// === CUSTOM TAXONOMIES === //
function my_custom_taxonomies() {
	register_taxonomy(
		'location',		// internal name = machine-readable taxonomy name
		'zombie',		// object type = post, page, link, or custom post-type
		array(
			'hierarchical' => true,
			'label' => 'Location',	// the human-readable taxonomy name
			'query_var' => true,	// enable taxonomy-specific querying
			'rewrite' => array( 'slug' => 'location' ),	// pretty permalinks for your taxonomy?
		)
	);
	register_taxonomy(
		'infection',
		'post',
		array(
			'hierarchical' => false,
			'label' => 'Infection',
			'query_var' => true,
			'rewrite' => array( 'slug' => 'infection' ),
		)
	);

}
add_action('init', 'my_custom_taxonomies', 0);</pre><p>The lines in the first registration are commented to explain them a bit, and another post by Justin Tadlock has <a
href="http://justintadlock.com/archives/2009/05/06/custom-taxonomies-in-wordpress-28">some more details about custom taxonomies</a>.</p><p>Notice that I made the Location taxonomy hierarchical, since I figured I could hone down the location as much as I want, and organise it in a hierarchy of country, state, city, suburb, etc. Also I only enabled it on &#8220;zombie&#8221; objects, that is, my Zombie post type. However, for the Infections tag I enabled it on posts because I figured I may write posts about the different strains and their evolution. I can enable the Infections taxonomy on Zombie post types within the post type registration below.</p><h3 id="custom-post-types">Custom Post Types</h3><p>Custom post types are new in WP 3.0. They are like posts and pages, but are handled separately within the WordPress dashboard and by the regular post query &#8212; like pages, they don&#8217;t show up on the posts page or in the feed.</p><p>When creating custom post types you can call them whatever name you like and you can mix some of the features of posts and pages. For example, you can create a custom post type that is hierarchical (like pages, allowing child pages) and that uses categories, tags or custom taxonomies (like posts already do).</p><p>Justin Tadlock has an amazing post with <a
href="http://justintadlock.com/archives/2010/04/29/custom-post-types-in-wordpress">the details of custom post types and how to make them</a>. Refer to that post for all the parameters related to creating custom post types.</p><p>In Thesis, creating custom post types is not very different to any other theme. The main difference is that instead of adding the registration code to <tt>functions.php</tt> you add it to <tt>custom_functions.php</tt>.</p><pre>// === CUSTOM POST TYPES === //
function create_my_post_types() {
	register_post_type( 'zombie',
		array(
			'labels' => array(
				'name' => __( 'Zombies' ),
				'singular_name' => __( 'Zombie' ),
				'add_new_item' => 'Add New Zombie',
				'edit_item' => 'Edit Zombie',
				'new_item' => 'New Zombie',
				'search_items' => 'Search Zombies',
				'not_found' => 'No zombies found',
				'not_found_in_trash' => 'No zombies found in trash',
			),
			'_builtin' => false,
			'public' => true,
			'hierarchical' => false,
			'taxonomies' => array( 'location', 'infection'),
			'supports' => array(
				'title',
				'editor',
				'excerpt'
			),
			'rewrite' => array( 'slug' => 'zombie', 'with_front' => false )
		)
	);
}
add_action( 'init', 'create_my_post_types' );</pre><p>There are loads more parameters that you could use. I found that these were the ones I needed to create a pretty simple post type with a smooth experience (i.e., all the terms in the admin call the posts &#8220;zombie&#8221; or &#8220;zombies&#8221; appropriately, rather than &#8220;posts&#8221; or &#8220;pages&#8221;).</p><p><a
href="http://www.kristarella.com/wp-content/uploads/WP3-CustomPostType.png"><img
src="http://www.kristarella.com/wp-content/uploads/WP3-CustomPostType-500x396.png" alt="" title="WP3.0 Custom Post Type" width="500" height="396" class="frame aligncenter size-large wp-image-3946" /></a></p><p>Worth noting is that even though the default slug (bit of the URL) will be the label (in this case &#8220;zombie&#8221;), I had to specifically state it in the registration code, otherwise I got a 404 error on my post. Also, you need to visit the permalink settings page after registering the post type to flush the rewrite rules so the new slugs work (just visit the page, you don&#8217;t have to re-save the options).</p><h4 id="thesis-meta-box">Thesis SEO &#038; image metadata for custom post types</h4><p><del>You might have noticed that the last line of my custom post type registration, <code>//'register_meta_box_cb'=>'add_meta_boxes',</code>, is commented out. Don&#8217;t uncomment it because it won&#8217;t work! To add meta boxes to the custom post type editing page, you need to provide a callback function and state the function name in the registration code. Thesis doesn&#8217;t support this yet, which is why I have custom fields enabled on the editing page. You can still use the Thesis SEO and image fields, but it will be a bit more manual until the callback is supported. I&#8217;ve left the line in the code to remind myself to add the callback in when it&#8217;s ready and I&#8217;ll edit this post to include it when it is.</del></p><p><img
src="http://www.kristarella.com/wp-content/uploads/thesis-custom-fields.png" alt="" title="Thesis Custom Fields" width="240" height="313" class="frame alignright size-full wp-image-3947" /></p><p><del>If you&#8217;ve been using the Thesis fields then the keys will probably be available for you in a select box when adding a new custom field. Some of the values you will know what to do with, such as <code>thesis_post_image</code> and <code>thesis_thumb</code> just take an image URL, but if you&#8217;re not sure what values to use take a look at the custom fields on one of your older posts already using the Thesis meta to see what should be entered as the value for the field.</del></p><p><ins>To add the Thesis meta boxes to your custom post editing page add the following to custom functions. <small>Courtesy <a
href="http://farinspace.com/custom-post-types-with-thesis-theme/">farinspace.com</a>.</small></ins></p><pre>function custom_thesis_meta_boxes() {
	$post_options = new thesis_post_options;
	$post_options->meta_boxes();
	foreach ($post_options->meta_boxes as $meta_name => $meta_box) {
		add_meta_box($meta_box['id'], $meta_box['title'], array('thesis_post_options', 'output_' . $meta_name . '_box'), '<strong>zombie</strong>', 'normal', 'high');
	}
	add_action('save_post', array('thesis_post_options', 'save_meta'));
}
add_action('admin_menu','custom_thesis_meta_boxes');</pre><p>Be sure to change the &#8220;zombie&#8221; in bold to the name of your custom post type. To add to more than one custom post type, try the following function, adding your custom post types to the array <code>$post_types</code>.</p><pre>function custom_thesis_meta_boxes() {
	$post_options = new thesis_post_options;
	$post_options->meta_boxes();
	$post_types = array('<strong>zombie</strong>','<strong>other_post_type</strong>');
	foreach ($post_types as $post_type) {
		foreach ($post_options->meta_boxes as $meta_name => $meta_box) {
			add_meta_box($meta_box['id'], $meta_box['title'], array('thesis_post_options', 'output_' . $meta_name . '_box'), $post_type, 'normal', 'high');
		}
		add_action('save_post', array('thesis_post_options', 'save_meta'));
	}
}
add_action('admin_menu','custom_thesis_meta_boxes');</pre><p></ins></p><h3>More to come</h3><p>There&#8217;s a lot more to WordPress 3.0, but I think this post is long enough. I&#8217;m sure I and others will have more exciting things to come!</p> ]]></content:encoded> <wfw:commentRss>http://www.kristarella.com/2010/06/wordpress-3-0-custom-post-types-taxonomies-thesis/feed/</wfw:commentRss> <slash:comments>103</slash:comments> </item> <item><title>Position Your Thesis Nav</title><link>http://www.kristarella.com/2010/05/position-your-thesis-nav/</link> <comments>http://www.kristarella.com/2010/05/position-your-thesis-nav/#comments</comments> <pubDate>Mon, 17 May 2010 02:14:23 +0000</pubDate> <dc:creator>kristarella</dc:creator> <category><![CDATA[Tutorials]]></category> <category><![CDATA[CSS]]></category> <category><![CDATA[Design]]></category> <category><![CDATA[featured]]></category> <category><![CDATA[Thesis]]></category><guid
isPermaLink="false">http://www.kristarella.com/?p=3890</guid> <description><![CDATA[I&#8217;ve been asked this several times, so I figured it&#8217;s high time to write a tutorial on it: how to position your Thesis navigation next to your site title. Essentially this tutorial is about the CSS position property more than anything else. position:absolute; The cool thing about the position property is that browsers generally interpret [...]]]></description> <content:encoded><![CDATA[<p></p><p>I&#8217;ve been asked this several times, so I figured it&#8217;s high time to write a tutorial on it: how to position your <a
href="http://www.shareasale.com/r.cfm?B=198392&#038;U=403481&#038;M=24570" target="_blank">Thesis</a> navigation next to your site title.</p><p>Essentially this tutorial is about the CSS <code><a
href="http://www.w3schools.com/Css/pr_class_position.asp">position</a></code> property more than anything else.<br
/> <span
id="more-3890"></span></p><h3 id="about-position-absolute">position:absolute;</h3><p>The cool thing about the <code>position</code> property is that browsers generally interpret it the same way! There&#8217;s none of the screwiness that comes with trying to get floats, margins, padding and borders to be the same in IE as they are everywhere else.</p><p>The values for the <code>position</code> property are:</p><ul><li><strong>static</strong>: the default behaviour of an element; you&#8217;ll rarely need to set it</li><li><strong>fixed</strong>: causes the element to stay in a fixed position, relative to the browser window &#8212; this one is an exception to what I said about IE, at least in IE6 and 7, fixed position elements were fine on the left, but weird on the right, not sure about IE8 or 9</li><li><strong>relative</strong>: the element is positioned exactly as it would be in the normal flow of the webpage and can be offset from there using the <code>top</code> and <code>left</code> properties</li><li><strong>absolute</strong>: causes and element to be positioned exactly where you tell it with the <code>top</code>, <code>right</code>, <code>bottom</code> and <code>left</code> properties; the position is absolute to the body of the web page, unless it&#8217;s inside a positioned element, in which case it is absolute relative to the positioned parent element</li></ul><p>The values that we are concerned with for the navigation are <code>relative</code> and <code>absolute</code>.</p><h3 id="nav-in-header">Move the nav inside the header</h3><p>Before putting the nav next to the title, we should put it inside the same element as the title. Paste the following into <tt>custom_functions.php</tt>.</p><pre>remove_action('thesis_hook_before_header','thesis_nav_menu');
add_action('thesis_hook_after_title','thesis_nav_menu');</pre><p>This moves the nav from above <code>#header</code> to inside it, after the title and tagline. You may also use <code>thesis_hook_before_title</code> if you want to put the nav before the title in the header; it doesn&#8217;t matter for the purposes of positioning it.</p><h3 id="nav-position">Position the nav next to the title</h3><p>To position the nav next to the title add the following to <tt>custom.css</tt>.</p><pre>.custom #header {position:relative;}
	.custom ul.menu {position:absolute; top:2.2em; right:1.1em; width:auto;}
		.custom ul.menu li.rss {float:left;}</pre><p>The first line is necessary for the nav to be positioned relative to the header rather than the whole page. The second line positions the nav 2.2em from the top and 1.1em from the right of <code>#header</code>.</p><p><code>width:auto;</code> is added for the sake of IE6 and 7 so that the nav is only as wide as it needs to be to accomodate its contents (other browsers automatically do this when using <code>position:absolute;</code>, or <code>float</code>). The subscribe tab is floated to the left, along with the other tabs, also for the sake of IE because IE will stretch the nav to the full width of the header if there are both left and right floated elements.</p><p><a
href="http://www.kristarella.com/wp-content/uploads/thesis-nav-position.png"><img
src="http://www.kristarella.com/wp-content/uploads/thesis-nav-position-500x64.png" alt="" title="Positioned Thesis Nav" width="500" height="64" class="frame aligncenter size-large wp-image-3902" /></a></p><h4 id="title-nav-width">Title or nav too wide?</h4><p>If your title or tagline is very long or your nav has too many tabs they will overlap. To prevent this you can specify widths for these elements by replacing the above CSS with the following.</p><pre>.custom #header {position:relative;}
	.custom #header #logo, .custom #header #tagline {width:50%;}
	.custom ul.menu {position:absolute; top:2.2em; right:1.1em; width:50%;}
		.custom ul.menu li.rss {float:left;}</pre><p>This will make the title, tagline or nav wrap when it needs more than half the width of the header. You may adjust the <code>50%</code> values to suit your design. Note that if your nav is not wider than half the header and you use <code>50%</code> instead of <code>auto</code>, the nav will start in the middle of the header and leave extra space on the right. To overcome this you may use <code>width:auto; max-width:50%;</code> instead, keeping in mind that <code>max-width</code> is not supported by IE6.</p><h3 id="related-links">Related Content</h3><p>Please ask <strong>related</strong> questions in the comments!</p><p>You may also be interested in my <a
href="http://www.kristarella.com/2009/11/drop-up-menu-in-thesis-1-6/">drop-up navigation tutorial</a> or the <a
href="http://diythemes.com/answers/category/nav-menus/">DIYthemes Answers blog posts on nav menus</a>.</p> ]]></content:encoded> <wfw:commentRss>http://www.kristarella.com/2010/05/position-your-thesis-nav/feed/</wfw:commentRss> <slash:comments>231</slash:comments> </item> <item><title>Mod TimThumb for WPMU and Thesis</title><link>http://www.kristarella.com/2010/05/mod-timthumb-for-wpmu-and-thesis/</link> <comments>http://www.kristarella.com/2010/05/mod-timthumb-for-wpmu-and-thesis/#comments</comments> <pubDate>Wed, 05 May 2010 03:23:43 +0000</pubDate> <dc:creator>kristarella</dc:creator> <category><![CDATA[Tutorials]]></category> <category><![CDATA[Graphics]]></category> <category><![CDATA[Thesis]]></category> <category><![CDATA[WordPress]]></category><guid
isPermaLink="false">http://www.kristarella.com/?p=3889</guid> <description><![CDATA[WPMU media locations WPMU implements a URL rewrite for uploaded media so that the location of an uploaded file is given as http://www.example.com/files/2009/01/image.jpg, but the actual URL of the file is http://www.example.com/wp-content/blogs.dir/BLOG_ID/files/2009/01/image.jpg (where BLOG_ID is the ID of the blog in question). TimThumb problem The easiest way to specify the URL for a post image [...]]]></description> <content:encoded><![CDATA[<p></p><h3 id="wpmu-media">WPMU media locations</h3><p>WPMU implements a URL rewrite for uploaded media so that the location of an uploaded file is given as <code>http://www.example.com/files/2009/01/image.jpg</code>, but the actual URL of the file is <code>http://www.example.com/wp-content/blogs.dir/BLOG_ID/files/2009/01/image.jpg</code> (where BLOG_ID is the ID of the blog in question).</p><h3 id="timthumb-problem">TimThumb problem</h3><p>The easiest way to specify the URL for a post image (whether you&#8217;re using <a
href="http://www.shareasale.com/r.cfm?B=198392&#038;U=403481&#038;M=24570" target="_blank">Thesis</a> post images, or custom fields to add a post thumbnail, or something else) is to copy the URL that WordPress inserts into the post. However, this URL doesn&#8217;t work with the TimThumb script (which Thesis and other themes use to generate thumbnails from larger images). Essentially TimThumb looks for the image file at the URL you specify, but the image file doesn&#8217;t exist there and the redirect that allows you to see the image in the browser doesn&#8217;t work for the script.<br
/> <span
id="more-3889"></span></p><h3>Overcoming the TimThumb problem</h3><p>There&#8217;s two ways that I can see to get TimThumb working on your site: modify your behaviour, or modify the script&#8217;s behaviour.</p><h4 id="change-image-url">Modify your behaviour</h4><p>You could simply edit the URL that you copy from WordPress and add <code>wp-content/blogs.dir/BLOG_ID/</code> into the image URL you want to use.</p><p>I don&#8217;t like this because it won&#8217;t fix any posts that have already been written and it&#8217;s extra work for the user every time they write a post. It also might not be easy for some users to remember that they need to change the URL, or in what way they need to change it.</p><h4 id="change-timthumb">Modify TimThumb&#8217;s behaviour</h4><p>I came across a <a
href="http://thesishosting.com/topics/wordpress/wordpress-mu/setting-up-timthumb-in-wpmu-yes-its-possible">TimThumb hack</a> for Thesis, but it didn&#8217;t work for me at all. I suspect it had something to do with my image URLs not being relative, but I&#8217;m not sure.</p><p>I was able to use the first part of the information in that post to make the blog IDs available in the TimThumb script and then using PHP replace the <code>/files/</code> part of the URL with <code>/wp-content/blogs.dir/BLOG_ID/files/</code>.</p><p>In the Thesis theme (version 1.7 at the time of writing) the TimThumb script is located at <tt>thesis_17/lib/scripts/thumb.php</tt>.</p><p
class="note"><strong>Update 5<sup>th</sup> Nov 2010:</strong> Changed line 448 below to fix a problem with this on blogs within a site network. Also, these edits still work the same with Thesis 1.8.</p><ul><li>At <strong>line 23</strong> (after the end of the file comments section) I added<pre>require_once('../../../../../wp-blog-header.php');</pre><p>to make the blog IDs available.</li><li><strong>After line 447</strong>, which says <code>$src = preg_replace("/\.\.+\//", "", $src);</code><br
/> To <strong>line 448</strong> (initially an empty line) I added</p><pre>global $current_site; global $current_blog; $src = str_replace($current_blog->path.'files/', $current_site->path.'wp-content/blogs.dir/'.$current_blog->blog_id.'/files/', $src);</pre><p>to replace the section of the image URL we need to change.</li></ul><p>That&#8217;s all.</p><h3>Further comments</h3><p>Other themes may use their own version of the TimThumb script, or they might use the one included with WPMU. These modifications should work with them, but the line numbers might be slightly different.</p><p>In theory this modification could be present in regular WordPress installations and in WordPress 3.0 with networks turned on or off (assuming WP3.0 directory structure is the same) without affecting the existing behaviour of the script. If &#8220;/files/&#8221; is not found in the image URL, it won&#8217;t be replaced and the image URL will remain the same.</p><p>In the long run it might be better to use the <a
href="http://markjaquith.wordpress.com/2009/12/23/new-in-wordpress-2-9-post-thumbnail-images/">thumbnails built into WordPress</a>. However, the caveat there is you will need to regenerate the different image sizes after setting up theme support for thumbnails, whereas TimThumb generates thumbnails on the fly and then caches them: changing image sizes is not a big deal with TimThumb.</p> ]]></content:encoded> <wfw:commentRss>http://www.kristarella.com/2010/05/mod-timthumb-for-wpmu-and-thesis/feed/</wfw:commentRss> <slash:comments>53</slash:comments> </item> <item><title>WordPress: Exclude child categories from category archives</title><link>http://www.kristarella.com/2010/03/wordpress-exclude-child-categories-from-category-archives/</link> <comments>http://www.kristarella.com/2010/03/wordpress-exclude-child-categories-from-category-archives/#comments</comments> <pubDate>Tue, 23 Mar 2010 00:57:24 +0000</pubDate> <dc:creator>kristarella</dc:creator> <category><![CDATA[Tutorials]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Thesis]]></category> <category><![CDATA[WordPress]]></category><guid
isPermaLink="false">http://www.kristarella.com/?p=3777</guid> <description><![CDATA[A normal category page I don&#8217;t know if you&#8217;ve noticed: on a WordPress category archive page, posts from that category and all its child categories are displayed. I don&#8217;t know why. It&#8217;s not the behaviour I would have expected, and although it&#8217;s not necessarily a bad thing, I can understand that some people wouldn&#8217;t want [...]]]></description> <content:encoded><![CDATA[<p></p><h3>A normal category page</h3><p>I don&#8217;t know if you&#8217;ve noticed: on a WordPress category archive page, posts from that category and all its child categories are displayed. I don&#8217;t know why. It&#8217;s not the behaviour I would have expected, and although it&#8217;s not necessarily a bad thing, I can understand that some people wouldn&#8217;t want it that way.<br
/> <span
id="more-3777"></span></p><h3 id="old-methods">&#8220;Solutions&#8221;</h3><p>I used to have a nice little function that used the <code>pre_get_posts</code> filter to exclude all the child categories, but for some reason that function stopped working somewhere between WordPress 2.7 and 2.8 and I couldn&#8217;t for the life of me get it to work again, at least not the way I wanted.</p><p>Furthermore, a simple <a
href="http://www.kristarella.com/2010/02/wordpress-custom-loops/#custom-queries">custom query like the one in my loop tutorial</a> doesn&#8217;t work quite right; often it modifies the query so that it thinks it&#8217;s on a normal home/blog page (very noticeable if you use only titles, or excerpts on archive pages and not the home page).</p><h4 id="problems-with-category-in">category__in</h4><p>For those in-the-know, you might be thinking, just use <a
href="http://codex.wordpress.org/Template_Tags/query_posts#Category_Parameters"><code>category__in</code></a>: it gets the posts from that category ID and not the child categories. However, when I tried it, I didn&#8217;t like the results.</p><p>It turned out that the reason the results were a little funky is because setting <code>category__in</code> obliterates the <code>cat</code> query variable. Two specific impacts of that are that the <code>single_cat_title()</code> template tag doesn&#8217;t work (because it uses <code>get_query_var('cat')</code> to get the category title) and any plugin using <code>get_query_var('cat')</code> (including Yoast Breadcrumbs) won&#8217;t work.</p><p>I tried setting the <code>cat</code> variable along with <code>category__in</code>, but <code>cat</code> seemed to override such that the child categories were no longer excluded and adding <code>category__not_in</code> didn&#8217;t help either.</p><h3 id="real-solution">The real solution</h3><p>The only real solution I could come up with was to use <code>category__in</code> before the loop and then reset the <code>cat</code> variable after the loop to allow plugins and widgets to use it.</p><h4>Before your category archive loop</h4><pre>$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$current_cat = get_query_var('cat');
$args=array(
	'category__in' => array($current_cat),
	'paged' => $paged
);
query_posts($args);</pre><p>Note that the <code>$paged</code> bit is essential for maintaining pagination. I usually prefer to use <a
href="http://www.kristarella.com/2010/02/wordpress-custom-loops/#custom-queries"><code>$query_string</code> in custom queries</a> for that, but it doesn&#8217;t work in this case.</p><h4>After the category page loop</h4><p>Assuming the <code>$current_cat</code> variable is still in tact from before the loop:</p><pre>set_query_var("cat",$current_cat);</pre><p>Otherwise use <code>category__in</code> to figure out what category you&#8217;re in:</p><pre>$cat = get_query_var('category__in');
set_query_var("cat",$cat[0]);</pre><p>Note that <code>category__in</code> returns an array, so we need to use <code>$cat[0]</code> to get the first array value, which is the ID of the current category.</p><p>Now the <code>cat</code> query variable will be available for use before and after your loop. It won&#8217;t be available inside the loop, but after two days on the topic, I couldn&#8217;t find a way around that &#8212; if you do, let me know!</p><h3 id="thesis-solution">Modifying your Thesis category archive pages</h3><p>If you would like to use this method in <a
href="http://www.shareasale.com/r.cfm?B=198392&#038;U=403481&#038;M=24570" target="_blank">Thesis</a> you need to insert the code before and after the loop with PHP via <tt>custom_functions.php</tt>.</p><h4>Before Thesis content</h4><p>This method presents another issue, because Thesis uses <code>single_cat_title()</code> in the archive info. So, when we set <code>category__in</code> the category name in the archive info will be blank. The following code initiates the custom query, removes the default archive info and adds a working archive info back in.</p><pre>function remove_child_cats() {
if (is_category()) :
	$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
	$current_cat = get_query_var('cat');

	$args=array(
		'category__in' =&gt; array($current_cat),
		'paged' =&gt; $paged
	);

	query_posts($args);

	remove_action('thesis_hook_archive_info', 'thesis_default_archive_info');
		echo '			&lt;div id=&quot;archive_info&quot;&gt;' . &quot;\n&quot;;
?&gt;
				&lt;p&gt;&lt;?php _e('From the category archives:', 'thesis'); ?&gt;&lt;/p&gt;
				&lt;h1&gt;&lt;?php echo get_cat_name($current_cat); ?&gt;&lt;/h1&gt;
&lt;?php
		echo '			&lt;/div&gt;' . &quot;\n&quot;;
endif;
}
add_action('thesis_hook_before_content','remove_child_cats');</pre><h4>After Thesis loop</h4><pre>function reset_cat_var() {
	$cat = get_query_var('category__in');
	set_query_var("cat",$cat[0]);
}
add_action('thesis_hook_after_content','reset_cat_var',1);</pre><p>That&#8217;s it: a way to exclude child categories from category archive pages without breaking (too much) stuff.</p><p>Please feel free to ask (related) questions!</p> ]]></content:encoded> <wfw:commentRss>http://www.kristarella.com/2010/03/wordpress-exclude-child-categories-from-category-archives/feed/</wfw:commentRss> <slash:comments>45</slash:comments> </item> <item><title>Rockin&#8217; out WordPress custom loops</title><link>http://www.kristarella.com/2010/02/wordpress-custom-loops/</link> <comments>http://www.kristarella.com/2010/02/wordpress-custom-loops/#comments</comments> <pubDate>Thu, 25 Feb 2010 04:56:32 +0000</pubDate> <dc:creator>kristarella</dc:creator> <category><![CDATA[Tutorials]]></category> <category><![CDATA[Blogging]]></category> <category><![CDATA[featured]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Thesis]]></category> <category><![CDATA[WordPress]]></category><guid
isPermaLink="false">http://www.kristarella.com/?p=3757</guid> <description><![CDATA[What&#8217;s a loop? When using WordPress, &#8220;The Loop&#8221; refers to the code in your template files that displays posts. Usually there is only one main loop per page, but you can have secondary custom loops to show special content. These can include recent posts and related posts. The loop depends on queries A query is [...]]]></description> <content:encoded><![CDATA[<p></p><h3 id="loop-is">What&#8217;s a loop?</h3><p>When using WordPress, &#8220;<a
title="WordPress Codex article on The Loop" href="http://codex.wordpress.org/The_Loop">The Loop</a>&#8221; refers to the code in your template files that displays posts. Usually there is only <em>one main loop</em> per page, but you can have secondary custom loops to show special content. These can include recent posts and related posts.<br
/> <span
id="more-3757"></span></p><h3  id="query-is">The loop depends on queries</h3><p>A <strong>query</strong> is related to the loop in that it determines what should be shown in the loop. For example, the default home query will contain all posts, 10 per page (or whatever number is set in Settings > Reading), from all categories; a single post query contains only information for the post or page you are viewing; archive loops will have posts according to the kind of archive page you are on (category, tag, month etc).</p><h4 id="custom-queries">Default and custom queries</h4><p>The main query for a WordPress page is determined automatically by the type of page you are viewing (it&#8217;s all handled by WordPress). You can create a <em>custom query</em> out of the default query by using the following <abbr>PHP</abbr> code somewhere before the start of your main loop code.</p><pre>global $query_string;
query_posts($query_string . '&#038;cat=-5');</pre><p>The above code gathers the variable <code>$query_string</code>, which contains all the default query information and then uses <code><a
title="WordPress Codex article on query_posts()" href="http://codex.wordpress.org/Template_Tags/query_posts">query_posts()</a></code> to create a query with all of the features of the default query, except the attributes that you change. In the example I have excluded the category with an ID of 5 from the query.</p><p>The benefit of using <code>$query_string</code> in this way is that you don&#8217;t destroy page pagination on the home and archive pages, which will happen when using <code>query_posts()</code> by itself.</p><h3 id="main-loop-code">The Loop code</h3><p>The main loop code generally starts with something like <code>&lt;?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?&gt;</code>. Where <code>have_posts()</code> is a WordPress function that determines whether the current query has any posts in it. <code>while ( have_posts() )</code> says &#8220;as long as there are posts in the query, do the following things&#8221;, and this repeats for each post until there are no more. In this case &#8220;the following things&#8221; are to execute the function <code>the_post()</code>, which fetches the post data from the database and makes it accessible for use via <a
href="http://codex.wordpress.org/Template_Tags/">Template Tags</a>, some of which are only available inside the loop.</p><h3 id="custom-loop">Creating a custom loop</h3><p>If you which to access other posts (to create a recent, related, popular or featured post list, for example) while keeping the main loop in tact you need to create a secondary custom loop. The best way to do this is to create a new query, using the <code>WP_Query()</code> function, which will be completely separate from the main query. Then you may loop over the posts in your new query.</p><h4 id="new-custom-query">New query for the custom loop</h4><p><code>WP_Query()</code> accepts the same parameters as <code><a
title="WordPress Codex article on query_posts()" href="http://codex.wordpress.org/Template_Tags/query_posts">query_posts()</a></code>, so have a look at that Codex page to find out what parameters you need.</p><p>For this example, let&#8217;s query 5 random posts from a category called &#8220;Featured&#8221;.</p><pre>$custom_loop = new WP_Query('showposts=5&#038;category_name=Featured&#038;orderby=rand');</pre><h4 id="new-custom-loop">Custom loop code</h4><p>Now we have to loop over the posts in the new query. Since the original page query still exists and our new query is stored in the variable <code>$custom_loop</code> we can&#8217;t use the same code as the main loop, but it is similar. This loop is basically the same as the main loop code, but it checks our custom query variable <code>$custom_loop</code> for the posts.</p><pre>if ( $custom_loop-&gt;have_posts() ) :
	while ( $custom_loop-&gt;have_posts() ) : $custom_loop-&gt;the_post();

		// this is where we put the code to show what we want for each post

	endwhile;
endif;</pre><h5 id="custom-loop-content">Content for the custom loop</h5><p>Unless we replace <code>// this is where we put the code to show what we want for each post</code> with something, nothing will actually show up when we run this code.</p><p>One of the simplest (and useful) things we could do is create a list of linked post titles.</p><pre>if ( $custom_loop-&gt;have_posts() ) :
	echo '&lt;ul&gt;';
	while ( $custom_loop-&gt;have_posts() ) : $custom_loop-&gt;the_post();

		echo '&lt;li&gt;&lt;a href=&quot;' . get_permalink() . '&quot;&gt;' . get_the_title() . '&lt;/a&gt;&lt;/li&gt;';

	endwhile;
	echo '&lt;/ul&gt;';
endif;</pre><p>Note that because the code between <code>while</code> and <code>endwhile</code> gets repeated for every post, <code>&lt;ul&gt;</code> and <code>&lt;/ul&gt;</code> (which start and end the unordered list) need to go outside of that part, i.e. outside of the loop.</p><h3 id="code-summary">Putting it all together</h3><p>The complete code for a custom query and custom loop producing an unordered list of random featured post title link is:</p><pre>$custom_loop = new WP_Query('showposts=5&amp;category_name=Featured&#038;orderby=rand');
if ( $custom_loop-&gt;have_posts() ) :
	echo '&lt;ul&gt;';
	while ( $custom_loop-&gt;have_posts() ) : $custom_loop-&gt;the_post();

		echo '&lt;li&gt;&lt;a href=&quot;' . get_permalink() . '&quot;&gt;' . get_the_title() . '&lt;/a&gt;&lt;/li&gt;';

	endwhile;
	wp_reset_query();
	echo '&lt;/ul&gt;';
endif;</pre><p>This is all <abbr>PHP</abbr> code, so make sure that you are in a <abbr>PHP</abbr> environment, i.e., this code should be somewhere after <code>&lt;?php</code> and before <code>?&gt;</code>. If these bits aren&#8217;t in your file where you want the custom loop to go, you can wrap the code in them.</p><p>Towards the end I&#8217;ve added <code>wp_reset_query()</code>, which &#8212; as the name suggests &#8212; resets the query. For some reason, when using <code>new WP_Query()</code>, <code>endwhile</code> ends the loop, but not the custom query. There&#8217;s another method on <a
href="http://codex.wordpress.org/The_Loop#Multiple_Loops_Example_2">The Loop codex page</a>, but it hasn&#8217;t always worked for me.</p><p>Sometimes I find that <code>wp_reset_query()</code> doesn&#8217;t quite work the way I want it to, I don&#8217;t get back to the original query. If you have that problem try <code>if ( have_posts() ) { while ( have_posts() ) { the_post; } };</code>. That usually works for me to reinitiate the original loop, but I&#8217;ve seen it create a recursive post loop too, so be careful.</p><h3 id="thesis-custom-loop">Using the custom loop in Thesis</h3><p>Using the custom loop in Thesis is pretty simple (once you have a grasp on the less simple stuff above): all you have to do is wrap the above code in a function and hook it in. If you need more info on basic function syntax check out <a
href="http://www.techforluddites.com/2010/01/thesis-hooks.html">What are hooks and how do you use them?</a> and <a
href="http://www.techforluddites.com/2010/01/thesis-the-basic-anatomy-of-a-custom-function.html">The basic anatomy of a custom function</a> on the Tech for Luddites blog.</p><pre>function custom_featured_posts() {
	$custom_loop = new WP_Query('showposts=5&amp;category_name=Featured&#038;orderby=rand');
	if ( $custom_loop-&gt;have_posts() ) :
		echo '&lt;ul&gt;';
		while ( $custom_loop-&gt;have_posts() ) : $custom_loop-&gt;the_post();

			echo '&lt;li&gt;&lt;a href=&quot;' . get_permalink() . '&quot;&gt;' . get_the_title() . '&lt;/a&gt;&lt;/li&gt;';

		endwhile;
		wp_reset_query();
		echo '&lt;/ul&gt;';
	endif;
}
add_action('thesis_hook_after_post','custom_featured_posts');</pre><p>That code pasted into <tt>custom_functions.php</tt> will add a list of 5 random posts from a category called &#8220;Featured&#8221; to the bottom of every post.</p><p>If you only wanted to show it on single post pages you would use a <a
href="http://codex.wordpress.org/Conditional_Tags" title="WordPress Codex page on Conditional Tags">conditional tag</a> by adding <code>if ( is_single() ) :</code> after the first line that opens the function, and <code>endif;</code> before the last curly bracket that ends the function.</p><h4 id="thesis-sidebar-loop">Add it to the sidebar</h4><p>If you want to add it to the sidebar to look like your other sidebar widgets you can use the following function.</p><pre>function widget_featured_posts() {
	$custom_loop = new WP_Query('showposts=5&amp;category_name=Featured&#038;orderby=rand');
	if ( $custom_loop-&gt;have_posts() ) :
		echo '&lt;li class=&quot;widget widget_featured_posts&quot;&gt;';
		echo '&lt;h3&gt;Featured Posts&lt;/h3&gt;';
		echo '&lt;ul&gt;';
		while ( $custom_loop-&gt;have_posts() ) : $custom_loop-&gt;the_post();

			echo '&lt;li&gt;&lt;a href=&quot;' . get_permalink() . '&quot;&gt;' . get_the_title() . '&lt;/a&gt;&lt;/li&gt;';

		endwhile;
		wp_reset_query();
		echo '&lt;/ul&gt;';
		echo '&lt;/li&gt;';
	endif;
}
add_action('thesis_hook_before_sidebar_1','widget_featured_posts');</pre><p>The function has the widget code and a heading added to match the <abbr>HTML</abbr> format of widgets in Thesis.</p><h4 id="thesis-thumbs">How about using thumbnails instead of post titles?</h4><p>Using thumbnails is a bit more attractive and intriguing than a list of post titles (not that a good post title can&#8217;t pull people in). If you use Thesis you should know about Post Images and Thumbnails; if you don&#8217;t please watch the <a
href="http://diythemes.com/in-post-options/">in-post options video</a>!</p><p>There&#8217;s a nice little snippet of code that you can use (inside the loop) to fetch the thesis post image or thumbnail:</p><pre>$post_image = thesis_post_image_info('thumb');
echo $post_image['output'];</pre><p>Use this in your custom loop like so.</p><pre>function custom_featured_posts() {
	$custom_loop = new WP_Query('showposts=5&amp;category_name=Featured&#038;orderby=rand');
	if ( $custom_loop-&gt;have_posts() ) :
		echo '&lt;strong&gt;Featured Posts&lt;/strong&gt;';
		echo '&lt;ul class="featured_posts"&gt;';
		while ( $custom_loop-&gt;have_posts() ) : $custom_loop-&gt;the_post();

			$post_image = thesis_post_image_info('thumb');
			echo '&lt;li&gt;' . $post_image['output'] . '&lt;/li&gt;';

		endwhile;
		wp_reset_query();
		echo '&lt;/ul&gt;';
	endif;
}
add_action('thesis_hook_after_post','custom_featured_posts');</pre><p><code>$post_image['output']</code> has the whole linked image markup with classes etc. If you just want to fetch the thumbnail URL to add your own HTML around it, use <code>$post_image['url']</code>.</p><p>The following CSS (to be placed in custom.css) will cause the thumbnails to be displayed horizontally next to each other.</p><pre>ul.featured_posts {list-style:none;}
	ul.featured_posts li {float:left;}</pre><h3>A related posts query</h3><p>There are several ways to determine if a post is related to another post, without getting too crazy with it, the simplest and most obvious attributes to use are categories and tags. If you haven&#8217;t been using categories and tags on your blog I would say to find a plugin that uses other means to determine relatedness, and don&#8217;t try to write your own related posts query (if you&#8217;re able to write one not based on categories and tags you probably don&#8217;t need this tutorial anyway!).</p><pre>function custom_related_posts() {
global $post;
if ( is_single() ) :
	//stores the original post data
	$original_post = $post;

	//get the post category
	$category = get_the_category();
	$cat = $category[0]-&gt;cat_ID;

	//gather a list of tags
	$tags = wp_get_post_tags($post-&gt;ID);
		$taglist = '';
		if ($tags) {
			foreach ($tags as $tag) {
				$taglist .= $tag-&gt;term_id . ',';
			}
			//start loop and query stuff
			$args = array(
				'cat' =&gt; $cat,
				'tag__in' =&gt; array($taglist),
				'post__not_in' =&gt; array($post-&gt;ID),
				'showposts'=&gt; 5,
				'caller_get_posts'=&gt; 1
			);
			$related_posts = new WP_Query($args);
			if ( $related_posts-&gt;have_posts() ) :
				echo '&lt;ul class=&quot;related_posts&quot;&gt;';
				while ( $related_posts-&gt;have_posts() ) : $related_posts-&gt;the_post();

					$post_image = thesis_post_image_info('thumb');
					echo '&lt;li&gt;&lt;a class=&quot;post_image_link&quot; href=&quot;' . get_permalink() . '&quot; title=&quot;Permanent link to ' . get_the_title() . '&quot;&gt;' . $post_image['output'] . '&lt;/a&gt;&lt;/li&gt;';

				endwhile;
				wp_reset_query();
				echo '&lt;/ul&gt;';
			else :
				echo '&lt;p&gt;Sorry, no posts found&lt;/p&gt;';
			endif;
		}
endif;
}
add_action('thesis_hook_after_post','custom_related_posts');</pre><p>This adds a list of linked thumbnails of related posts to the bottom of a single post page. I&#8217;ve added a couple of comments in there to indicate what&#8217;s happening in the code.</p><p>The <code>$args = array(...</code> syntax is just another way of writing out the parameters to use in <code>WP_Query()</code>. It can be a bit easier for humans to read when using more than a few parameters to put them into an array like that.</p><p>The <code>tag__in</code> parameter indicates that the related post should be tagged with any (but not necessarily all) of the same tags as the current post. <code>post__not_in</code> is used here to exclude the current post from the query. <code>caller_get_posts</code>, when set to &#8220;1&#8243;, means that sticky posts are excluded.</p><p>You may notice that I&#8217;ve added a link around <code>$post_image['output']</code> because the whole function will only be shown on a single page, but <code>$post_image['output']</code> doesn&#8217;t output a link on single posts and pages.</p><h3>Questions?</h3><p>If you are not sure which WordPress tags to use in your loop or parameters in your query, please check the WordPress codex before asking here:</p><ul><li><a
href="http://codex.wordpress.org/Template_Tags/">Template Tags</a></li><li><a
href="http://codex.wordpress.org/Template_Tags/query_posts">query_posts()</a></li><li><a
href="http://codex.wordpress.org/Conditional_Tags">Conditional Tags</a></li></ul><p>If you need clarification on a particular bit of the code or it doesn&#8217;t work in a particular situation, please let me know and be specific. Thanks!</p> ]]></content:encoded> <wfw:commentRss>http://www.kristarella.com/2010/02/wordpress-custom-loops/feed/</wfw:commentRss> <slash:comments>131</slash:comments> </item> <item><title>Drop-up menu in Thesis 1.6</title><link>http://www.kristarella.com/2009/11/drop-up-menu-in-thesis-1-6/</link> <comments>http://www.kristarella.com/2009/11/drop-up-menu-in-thesis-1-6/#comments</comments> <pubDate>Wed, 11 Nov 2009 07:23:22 +0000</pubDate> <dc:creator>kristarella</dc:creator> <category><![CDATA[Tutorials]]></category> <category><![CDATA[CSS]]></category> <category><![CDATA[featured]]></category> <category><![CDATA[Geek]]></category> <category><![CDATA[jQuery]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Thesis]]></category><guid
isPermaLink="false">http://www.kristarella.com/?p=3733</guid> <description><![CDATA[Yes, drop-up is a bit of an oxymoron. Technically you pull something up and drop something down, but since we talk about drop-downs so much, and the effect of what I&#8217;m about to show you happens with the same amount of &#8220;gravity&#8221;, and I&#8217;m not an language pedant (all of the time)&#8230; it&#8217;s okay. I [...]]]></description> <content:encoded><![CDATA[<p></p><p>Yes, <i>drop-up</i> is a bit of an oxymoron. Technically you <em>pull</em> something <em>up</em> and <em>drop</em> something <em>down</em>, but since we talk about drop-downs so much, and the effect of what I&#8217;m about to show you happens with the same amount of &#8220;gravity&#8221;, and I&#8217;m not an language pedant (all of the time)&#8230; it&#8217;s okay.</p><p>I was asked how one might create a menu to go in the footer and I thought, hey why not show my blog a bit of love? So, what I&#8217;m going to do here is make a drop-up menu listing archives, categories and recent posts, using built in <a
href="http://codex.wordpress.org/Template_Tags/">WordPress template tags</a> and Thesis menu classes.</p><p><a
href="http://www.kristarella.com/wp-content/uploads/ThesisTutorial-DropUpNav.png"><img
src="http://www.kristarella.com/wp-content/uploads/ThesisTutorial-DropUpNav-499x175.png" alt="Drop-up Nav" title="Drop-up Nav" width="499" height="175" class="frame aligncenter size-large wp-image-3734" /></a><br
/> <span
id="more-3733"></span></p><p
class="alert">This has been tested in Safari and Firefox on Mac and IE6, IE7 and IE8 on Windows. There may be some z-index issues for sub-sub-menus in IE7 and IE8, sub-sub-menus don&#8217;t really work at all in IE6 because they&#8217;re not wrapped with tables, and position of the drop-up was not perfect in IE6. I wasn&#8217;t able to solve these issues. In many cases these bugs might not be visible at all (e.g., if you don&#8217;t have any sub-sub-menus), or acceptable sacrifices if you don&#8217;t care much about IE6, which I don&#8217;t.</p><p>The lovely thing about menus in <a
href="http://www.shareasale.com/r.cfm?B=198392&#038;U=403481&#038;M=24570">Thesis</a> 1.6 is that all the hard work of CSS dropdowns are done for you, and since the navigation has a class of &#8220;menu&#8221; (rather than an ID of &#8220;tabs&#8221;), it&#8217;s perfectly okay to reuse this class elsewhere.</p><h3 id="menu-code">The menu code</h3><p>This code needs to go in <tt>custom_functions.php</tt> (which is now conveniently accessible via the built in &#8216;Custom File Editor&#8217;).</p><pre>function custom_footer_nav() {
?&gt;
&lt;ul id=&quot;footer_nav&quot; class=&quot;menu&quot;&gt;
	&lt;li&gt;&lt;a href=&quot;&quot;&gt;Archives&lt;!--[if IE 7]&gt;&lt;!--&gt;&lt;/a&gt;&lt;!--&lt;![endif]--&gt;
	&lt;!--[if lte IE 6]&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;&lt;![endif]--&gt;
		&lt;ul class=&quot;submenu&quot;&gt;
			&lt;?php wp_get_archives(); ?&gt;
		&lt;/ul&gt;
	&lt;!--[if lte IE 6]&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/a&gt;&lt;![endif]--&gt;
	&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;&quot;&gt;Categories&lt;!--[if IE 7]&gt;&lt;!--&gt;&lt;/a&gt;&lt;!--&lt;![endif]--&gt;
	&lt;!--[if lte IE 6]&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;&lt;![endif]--&gt;
		&lt;ul class=&quot;submenu&quot;&gt;
			&lt;?php wp_list_categories('title_li='); ?&gt;
		&lt;/ul&gt;
	&lt;!--[if lte IE 6]&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/a&gt;&lt;![endif]--&gt;
	&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;&quot;&gt;Recent Posts&lt;!--[if IE 7]&gt;&lt;!--&gt;&lt;/a&gt;&lt;!--&lt;![endif]--&gt;
	&lt;!--[if lte IE 6]&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;&lt;![endif]--&gt;
		&lt;ul class=&quot;submenu&quot;&gt;
			&lt;?php wp_get_archives('type=postbypost&#038;limit=5'); ?&gt;
		&lt;/ul&gt;
	&lt;!--[if lte IE 6]&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/a&gt;&lt;![endif]--&gt;
	&lt;/li&gt;
&lt;/ul&gt;
&lt;?php
}
add_action('thesis_hook_after_footer','custom_footer_nav');</pre><h4 id="menu-code-description">What the code does</h4><p>The code is wrapped in a PHP function so that we may insert it below the footer using the <code>thesis_hook_after_footer</code> hook.<br
/> The HTML that builds the menu is an <a
href="http://www.w3schools.com/tags/tag_ul.asp" title="link to W3 Schools description of unordered lists">unordered list</a>, with each list item containing another unordered list. Each sub-list is populated with list items from the template tags <code><a
href="http://codex.wordpress.org/Template_Tags/wp_get_archives">wp_get_archives</a></code> and <code><a
href="http://codex.wordpress.org/Template_Tags/wp_list_categories">wp_list_categories</a></code>, which retrieve links to archives (monthly, daily, post by post, whatever you specify) and categories and present them as list items.</p><p>It&#8217;s essential that the first unordered list have <code>class="menu"</code> so that it inherits all the built-in dropdown function of the Thesis navigation menu.</p><p>Before and after each sub-list is</p><pre>&lt;!--[if IE 7]&gt;&lt;!--&gt;&lt;/a&gt;&lt;!--&lt;![endif]--&gt;
	&lt;!--[if lte IE 6]&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;&lt;![endif]--&gt;</pre><p>and</p><pre>&lt;!--[if lte IE 6]&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/a&gt;&lt;![endif]--&gt;</pre><p>Those are there to tell Internet Explorer not to finish the parent link before the sub-list (because IE6 only allows the <code>:hover</code> selector on links) and for IE6 to wrap the sub-list in a table (for positioning).</p><h3 id="javascript-code">A bit of javascript for positioning</h3><p>The above code will give a functional dropdown menu, but we were after a <em>drop-up</em> menu. To achieve that we need to position the submenus above the parent links by the same number of pixels as their height. This is not currently possible in CSS for dynamic elements (with automatically created height). You could give them a fixed height, but I&#8217;m going to use a bit of jQuery to detect the height and then position the submenu.</p><p>This should also go in <tt>custom_functions.php</tt></p><pre>if ( !is_admin() ) {
	wp_deregister_script('jquery');
	wp_register_script('jquery', (&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js&quot;), false, '1.3.2');
	wp_enqueue_script('jquery');
}

function add_to_head() {
?&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
	$(function() {
		$(&quot;#footer_nav ul.submenu&quot;).each(function() {
			var listHeight = $(this).height();
			$(this).css(&quot;top&quot;, &quot;-&quot; + listHeight + &quot;px&quot;);
		});
		$(&quot;#footer_nav &gt; li&quot;).click(function() {
			return false;
		});
	});
&lt;/script&gt;
&lt;?php
}
add_action('wp_head','add_to_head');</pre><h4 id="javascript-code-description">What the javascript does</h4><p>The first bit with deregister, register and enqueue script adds a Google hosted jQuery library to the pages on your blog (but not the admin pages in the dashboard).</p><p>The function <code>add_to_head()</code> adds some jQuery to the <code>head</code> of your site. It finds the submenu in our footer navigation (<code>#footer_nav ul.submenu)</code> and detects its height in pixels (<code>$(this).height()</code>) then applies CSS of <code>top:-height;</code> so that the submenu is positioned by its full height above the menu.</p><pre>$(&quot;#footer_nav &gt; li&quot;).click(function() {
	return false;
});</pre><p>That just makes sure that nothing happens when you click on the top-level links of the footer menu because in this example they don&#8217;t go anywhere. You can remove this if you intended to link the top links to real pages.</p><h3 id="extra-CSS">A bit of CSS to wrap up</h3><p>This goes in <tt>custom.css</tt>. All it does is rearrange some of the borders and margins that makes the dropdown navigation lists line up properly, so our drop-up lists line up better. If you have navigation borders set to <code>0</code> in the Design Options, you probably don&#8217;t need this CSS at all.</p><pre>.custom #footer_nav {border-bottom:0; border-top:1px solid #ddd;}
	.custom #footer_nav li {margin-bottom:0; margin-top:-0.1em;}
		.custom #footer_nav li ul {border-bottom:0; margin-top:0;}
			.custom #footer_nav ul.children {margin-top:0.1em;}</pre><p>If you need further info on the syntax of PHP, XHTML or CSS to understand the info above, please check out <a
href="http://tizag.com">Tizag tutorials</a> and <a
href="http://www.w3schools.com/">W3 Schools</a>.</p> ]]></content:encoded> <wfw:commentRss>http://www.kristarella.com/2009/11/drop-up-menu-in-thesis-1-6/feed/</wfw:commentRss> <slash:comments>46</slash:comments> </item> <item><title>Popup EXIF display with Thesography and jQuery</title><link>http://www.kristarella.com/2009/10/exif-with-thesography-jquery/</link> <comments>http://www.kristarella.com/2009/10/exif-with-thesography-jquery/#comments</comments> <pubDate>Sat, 17 Oct 2009 23:30:22 +0000</pubDate> <dc:creator>kristarella</dc:creator> <category><![CDATA[Tutorials]]></category> <category><![CDATA[CSS]]></category> <category><![CDATA[Geek]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Thesis]]></category> <category><![CDATA[Thesography]]></category> <category><![CDATA[WordPress]]></category><guid
isPermaLink="false">http://www.kristarella.com/?p=3686</guid> <description><![CDATA[I received a request to make Thesography display EXIF upon hover over an image instead of just displaying as more text in the post. While I won&#8217;t include that kind of function in the plugin at this time (because I&#8217;m not sure how best to do it while maintaining a good amount of flexibility), I [...]]]></description> <content:encoded><![CDATA[<p></p><p>I received a request to make <a
href="http://www.kristarella.com/thesography/">Thesography</a> display EXIF upon hover over an image instead of just displaying as more text in the post. While I won&#8217;t include that kind of function in the plugin at this time (because I&#8217;m not sure how best to do it while maintaining a good amount of flexibility), I can show you how to implement it to suit your posting style.<br
/> <span
id="more-3686"></span></p><h3 id="exif-tooltip"><acronym>EXIF</acronym> via the title attribute</h3><p>A very simple (though arguably non-semantic) way of doing this could be to display a tooltip via the title attribute.</p><div
id="attachment_3690" class="wp-caption aligncenter" style="width: 581px"> <img
src="http://www.kristarella.com/wp-content/uploads/tute_thesography-tooltip.png" alt="EXIF displayed in a tooltip by Thesography" title="Thesography EXIF tooltip" width="581" height="310" class="size-full wp-image-3690" /><p
class="wp-caption-text">EXIF displayed in a tooltip by Thesography</p></div><p>When you insert your image into your WordPress post you can insert the Thesography shortcode into the title attribute via the HTML view.</p><pre>&lt;img src=&quot;http://www.example.com/wp-content/uploads/2009/10/lily.jpg&quot; alt=&quot;lily&quot; <strong>title=&quot;&#91;exif id=&quot;18&quot; show=&quot;all&quot;&#93;&quot;</strong> width=&quot;800&quot; height=&quot;529&quot; class=&quot;aligncenter size-full wp-image-18&quot; /&gt;</pre><p>For this to work you must not have any HTML in the Thesography HTML display options. You should change the HTML options from the default to something like the following screenshot.</p><div
id="attachment_3689" class="wp-caption aligncenter" style="width: 551px"> <img
src="http://www.kristarella.com/wp-content/uploads/tute_thesography-options.png" alt="Thesography HTML options for tooltip display" title="Thesography HTML options" width="551" height="283" class="size-full wp-image-3689" /><p
class="wp-caption-text">Thesography HTML options for tooltip display</p></div><h3 id="exif-javascript">Fancy <acronym>EXIF</acronym> display with javascript</h3><p>The first step to making a javascript <acronym>EXIF</acronym> display is to use CSS to style the <acronym>EXIF</acronym> block the way you want it.</p><div
id="attachment_3688" class="wp-caption aligncenter" style="width: 476px"> <img
src="http://www.kristarella.com/wp-content/uploads/tute_thesography-default-display.png" alt="Default Thesography style: list with a class of &quot;exif&quot;" title="Thesography default style" width="476" height="393" class="size-full wp-image-3688" /><p
class="wp-caption-text">Default Thesography style: list with a class of &quot;exif&quot;</p></div><h4 id="the-css">The CSS makes it look cool</h4><div
id="attachment_3692" class="wp-caption alignright" style="width: 161px"> <a
href="http://www.kristarella.com/wp-content/uploads/tute_thesography-custom-display.png"><img
src="http://www.kristarella.com/wp-content/uploads/tute_thesography-custom-display-161x200.png" alt="EXIF displayed by Thesography with custom CSS" title="Thesography custom display" width="161" height="200" class="size-thumbnail wp-image-3692" /></a><p
class="wp-caption-text">EXIF displayed by Thesography with custom CSS</p></div><p>Using the following <abbr>CSS</abbr> (in your theme&#8217;s <abbr>CSS</abbr> file or <tt>custom.css</tt> when using the <a
href="http://www.shareasale.com/r.cfm?B=198392&#038;U=403481&#038;M=24570">Thesis theme</a>), along with a <a
href="http://www.kristarella.com/wp-content/uploads/black-85.png" target="_blank">black 85% opacity background image</a>, you can get a slightly transparent black sidebar over the left of your page.</p><p>You don&#8217;t have to use this particular <abbr>CSS</abbr>; it&#8217;s an example of the sort of thing you can do without having to recode your <acronym>EXIF</acronym> <abbr>HTML</abbr>. The javascript will apply to a range of different styles.</p><p><small>N.B. IE6 does not support <code>position:fixed;</code>, the list will appear below the image (where it was before) instead of overlayed on the page.</small></p><pre>ul.exif {
	position:fixed;
	left:-2em;
	top:0;
	z-index:100;
	height:100%;
	width:16em;
	padding:10em 2em 2em;
	background:url(images/black-85.png) repeat;
	color:#fff;
	list-style-position:inside;
}</pre><h4 id="the-javascript">The javascript makes it act cool</h4><p>To start, we need to add <code>display:none;</code> to the <abbr>CSS</abbr> so that <code>ul.exif</code> is hidden when the page loads.</p><p>The following <abbr>PHP</abbr> code can go in <tt>functions.php</tt> in the main directory of your theme, or in <tt>custom_functions.php</tt> if you&#8217;re using <a
href="http://www.shareasale.com/r.cfm?B=198392&#038;U=403481&#038;M=24570">Thesis</a>. If your theme doesn&#8217;t have a <tt>functions.php</tt> you can make one by creating a new file with that name (in a plain text editor, not MS Word or a rich text editor); add <code>&lt;?php</code> at the start and paste this code after that.</p><pre>if ( !is_admin() ) {
	wp_deregister_script('jquery');
	wp_register_script('jquery', (&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js&quot;), false, '1.3.2');
	wp_enqueue_script('jquery');
}

function exif_popout() {
	if (is_single()) {
?&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
	$(function() {

		var hovered = 0;

		var maybeFadeOut = function() {
			if (hovered == 0) {
				$(&quot;ul.exif&quot;).fadeOut();
			}
		};

		var hoverOn = function() {
			$(this).parent().next(&quot;ul.exif&quot;).fadeIn();
			hovered++;
		};
		var hoverOff = function() {
			hovered--;
			setTimeout(maybeFadeOut, 0);
		};

		$(&quot;.post img&quot;).hover(hoverOn, hoverOff);
		$(&quot;ul.exif&quot;).hover(hoverOn, hoverOff);
	});
&lt;/script&gt;
&lt;?php
	}
}
add_action('wp_head','exif_popout');</pre><p>The first chunk of code is from <a
href="http://digwp.com/2009/06/use-google-hosted-javascript-libraries-still-the-right-way/">Digging into WordPress</a> and it loads the latest (at time of writing) jQuery library, hosted by Google. Using externally hosted libraries can be good because you have easy access to the latest files and because they can load asynchronously (i.e., while something from your server is loading, this can load too because it&#8217;s on another server, things from your server only load one at a time).</p><p>The second chunk of code inserts javascript into the <code>head</code> of our <abbr>HTML</abbr> WordPress page.</p><h5>exif_popout() step by step</h5><p>If you need more info about basic <abbr>PHP</abbr> syntax try the <a
href="http://www.tizag.com/phpT/" target="_blank">Tizag PHP tutorial</a>. On Tizag.com you can also find <abbr>HTML</abbr> and <abbr>CSS</abbr> tutorials.</p><p>The function <code>exif_popout()</code> is designed to load only on single post pages (<code>if (is_single())</code> determines that). It is also designed to be useful when there are multiple images on the page, each with their own <acronym>EXIF</acronym> that comes right after the image in the post.</p><p><code>$(function() { ... });</code> instructs jQuery to run our function when the webpage has completed loading.</p><p><code>var hovered = 0;</code> is a variable that acts as a counter getting increased or decreased as we move our mouse over and off the image or the <acronym>EXIF</acronym> block. It helps determine how the movement of the mouse indicates whether the <acronym>EXIF</acronym> should be visible or not.</p><p><code>maybeFadeOut</code> is a function that when called says, if <code>hovered</code> is equal to zero all <acronym>EXIF</acronym> blocks should be hidden (with a fade out effect).</p><p><code>hoverOn</code> is a function that when called takes the element it acts upon (<code>$(this)</code>, in this case it&#8217;s the image), then it finds that element&#8217;s parent element (using <code>parent()</code>, which in WordPress posts will be a paragraph, because images on their own line get wrapped in a paragraph). It then finds the <code>ul.class</code> that is next to that paragraph (<code>next("ul.exif")</code>) and displays it with a fade in effect. The <code>hovered</code> counter is also increased.</p><p><code>hoverOff</code> is a function that when called decreases the <code>hovered</code> counter and activates the <code>maybeFadeOut</code> function. <code>maybeFadeOut</code> is wrapped with <code>setTimeout</code>, which adds a delay (of zero milliseconds) to the execution of <code>maybeFadeOut</code> and moves it to the end of the current action queue; allowing the rest of the javascript to execute before it. This allows us to move our mouse off the image and onto the <acronym>EXIF</acronym> block, or off the block onto the image, without the <acronym>EXIF</acronym> fading out and back in again (i.e., the fade out is delayed until we really want it to disappear &#8212; when we&#8217;re not hovering on the image or the <acronym>EXIF</acronym>).</p><p><code>$(&quot;.post img&quot;).hover(hoverOn, hoverOff);<br
/> $(&quot;ul.exif&quot;).hover(hoverOn, hoverOff);</code><br
/> Those two lines activate <code>hoverOn</code> and <code>hoverOff</code> when you hover your mouse on and off <code>.post img</code> and <code>ul.exif</code>.</p><p
class="note"><code>.post</code> is a class assigned to the element containing your image. If your theme uses a different class for your posts you need to change that in the javascript. Also, <code>ul.exif</code> is an unordered list with a class of &#8220;exif&#8221;, which is the default display for Thesography. If you have changed the way that Thesography displays, you will need to change <code>ul.exif</code> to whatever element your <acronym>EXIF</acronym> is presented with.</p><h5 id="auto-inserted-exif">What if I&#8217;m using auto-insertion in Thesis</h5><p>If you&#8217;re using Thesography auto-insertion with Thesis and you have some text in between the image and the <acronym>EXIF</acronym> the javascript won&#8217;t work as written because <code>ul.exif</code> won&#8217;t be the next thing after the image paragraph, there will be another paragraph (or more) in between. However, if you&#8217;re using auto-insertion it means you&#8217;ve only got one lot of <acronym>EXIF</acronym> on the page and you can change <code>$(this).parent().next("ul.exif").fadeIn();</code> to <code>$("ul.exif").fadeIn();</code>.</p><h5>What if this doesn&#8217;t work with my post layout?</h5><p>There are so many different ways that your images and <acronym>EXIF</acronym> could be laid out in a post; it&#8217;s impossible for me to predict them all.</p><p>If you want to wrap your image and EXIF in a div together, that might simplify things for you and you could look into using the <a
href="http://docs.jquery.com/Selectors/siblings#prevsiblings">siblings selector</a> instead of <code>parent().next("ul.exif")</code>, or perhaps <code>parent().<a
href="http://docs.jquery.com/Traversing/children#expr">children("ul.exif")</a></code>.</p><p>Alternatively, while writing your post you could wrap each image and its related <acronym>EXIF</acronym> in paragraphs or divs with a unique class for each pair, and then use the <a
href="http://docs.jquery.com/Attributes/attr#name">class attribute as a variable</a> to identify which <acronym>EXIF</acronym> should be displayed.</p><p>For more info on how to identify and navigate elements with jQuery, check the jQuery documentation; particularly <a
href="http://docs.jquery.com/Selectors">Selectors</a> and <a
href="http://docs.jquery.com/Traversing">Traversing</a>.</p><p
class="alert">If you have trouble making the javascript fit your posting style and ask for help, please be very specific with the way your posts are displayed. A link to a direct example or the source code of an example (perhaps copied into <a
href="http://pastebin.com/">Pastebin</a>) is preferable.</p> ]]></content:encoded> <wfw:commentRss>http://www.kristarella.com/2009/10/exif-with-thesography-jquery/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Object Caching 842/938 objects using disk: basic

Served from: www.kristarella.com @ 2012-02-10 16:09:02 -->
