<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>boosten.org</title>
	
	<link>http://www.boosten.org</link>
	<description>Description of my Adventures in Open Source Land and how I graduately became a wannabee specialist</description>
	<lastBuildDate>Wed, 09 Dec 2009 10:24:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Boostenorg" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="boostenorg" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Permalinks in WordPress</title>
		<link>http://www.boosten.org/permalinks-in-wordpress/</link>
		<comments>http://www.boosten.org/permalinks-in-wordpress/#comments</comments>
		<pubDate>Thu, 19 Nov 2009 20:36:59 +0000</pubDate>
		<dc:creator>Peter Boosten</dc:creator>
				<category><![CDATA[webpublishing]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[permalinks]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.boosten.org/?p=410</guid>
		<description><![CDATA[This article describes the Permalinks Settings in Wordpress and how to configure them.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m sure everyone new to WordPress looked through the administration panel, and stumbled upon the Permalinks Settings.</p>
<p>So what are they?</p>
<p>In short: to make the links to your posts/pages/categories/tags look nicer than they do by default.</p>
<p>The default for WordPress is to not use permalinks at all. This gives a quite ugly URL for a post like this:
<pre>http://www.yourdomain.tld/?p=20</pre>
<p>, which also isn&#8217;t very SEO-friendly (SEO = Search Engine Optimization). Categories are shown by default with an URL like this:
<pre>http://www.yourdomain.tld/?cat=5</pre>
<p>, which isn&#8217;t helpful either. Tags look a bit nicer, but not as nice as one would wish for:
<pre>http://www.yourdomain.tld/?tag=sometag</pre>
<p>. </p>
<p>Permalinks should never change once configured (perma is short for permanent), since other people and search engines will use these to link articles from their site to yours. So you might want to think a bit about how you would like to structure them.</p>
<p>Using permalinks require actually two things: the settings in WordPress and the rewrite engine of Apache, which has to translate the much prettier, SEO- and user-friendly URLs into the internal
<pre>'/?p=somenumber'</pre>
<p> structure. I only describe Apache here, since that&#8217;s the web server I use, how to configure this in other web servers like Microsoft IIS is out of the scope of this article.</p>
<p>The Permalink Settings in the administrator panel gives you five different options for permalinks:</p>
<p>The first option is to use the default, which is the easiest to configure, since you don&#8217;t need to configure (or even have) the rewrite module of Apache, but gives you the ugly URLs.</p>
<p>The second one is titled &#8216;Day and name&#8217;, which will order your posts in a /year/month/day/title-of-your-post/ structure. I suggest this one to use when you have more than one posts a day. </p>
<p><em>A small warning might be given here: although it looks like your posts are going to be scattered around your site, they aren&#8217;t: all of your content is still stored in the MySQL database and nothing is going to be created on your site, except a small file called .htaccess (I will come to that later). Also the posts/pages/tags/categories aren&#8217;t restructured in any way, internally they are still called p=20, cat=5, and so on. With permalinks you&#8217;re simply telling Apache to rename the URL your reader requests in something WordPress can understand.</em></p>
<p>The next option in the list is called &#8216;Month and name&#8217;, which is basically the same as the second, but without the date. This one could be used if you have more than one post a month, but not more than one per day.</p>
<p>&#8216;Numeric&#8217; displays your posts as a number, but without the question mark. I do not suggest using these, since they&#8217;re not SEO friendly (in fact, I think they&#8217;re as ugly as the default ones).</p>
<p>The last one is the one I like: &#8216;Custom Structure&#8217;. Since I don&#8217;t post that much, I chose this one to create URLs like on my site:
<pre>http://www.yourdomain.tld/the-title-of-my-article/</pre>
<p>.</p>
<p>WordPress asks you to create your own structure and a number of variables can be used for this:</p>
<ul>
<li><strong>%year%:</strong> the year of the post (2008, 2009)</li>
<li><strong>%monthnum%</strong>: the month of the post in digits (01, 02, 03, and so on)</li>
<li><strong>%day%</strong>: the day of the post (09, 10, 11, &#8230;)</li>
<li><strong>%hour%</strong>: hour of the post, 24-hours</li>
<li><strong>%minute%</strong>: the minute part of the time of the post</li>
<li><strong>%second%</strong>: for the real freaks <img src='http://www.boosten.org/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </li>
<li><strong>%postname%</strong>: the title of the post (actually called the slug). Slugs are always lowercase.</li>
<li><strong>%post_id%</strong>: the post ID, which is the unique idetifier of a post. This is the number you would see when using the default</li>
<li><strong>%category%</strong>: the category of the post. If a post is contained in more than one category, then the category with the lowest number is shown here</li>
<li><strong>%tag%</strong>: the tag with the lowest ID contained in a post</li>
<li><strong>%author%</strong>: the name of the author</li>
</ul>
<p>According to the <a href="http://codex.wordpress.org/Using_Permalinks">codex</a> you really shouldn&#8217;t start permalinks with either %category% or %tag% because of performance reasons.</p>
<p>I use only /%postname%/ on my site.</p>
<p>If you make a change to the Permalink Settings, WordPress responds with &#8216;<em>You should update your .htaccess now</em>&#8216; and shows a suggestion ow how your .htaccess should look like. If the user account your web server runs on has write access to the root directory of WordPress, then WordPress will automatically create a .htaccess file if it does not exist, or modify if it exists.</p>
<p>In my case, my .htaccess file looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;ifmodule mod_rewrite.c&gt;
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
&lt;/ifmodule&gt;</pre></div></div>

<p>This .htaccess file needs some attention.</p>
<p>First of all it will be in the root of your WordPress directory structure (where your index.php is). If WordPress wasn&#8217;t able to create or modify the file for you, you&#8217;ll need to create one yourself, or modify the existing one. Depending on your setup that would mean either downloading the file from your site to your desktop with FTP, modify and upload again, or, if you&#8217;re lucky like me and have shell access, cd to the correct directory and use your favorite editor (like vi) and edit the file on the server.</p>
<p>This however is no guarantee that the permalinks actually will work. In order to make them work, your Apache might need some modifications also.</p>
<p>First of all, the module mod_rewrite needs to be loaded in your Apache configuration. For this to happen the following line needs to exist in your httpd.conf:</p>
<pre>
LoadModule rewrite_module libexec/apache22/mod_rewrite.so
</pre>
<p>The directory of the actual module might vary. This tells Apache to know about rewrite requests it might get. Otherwise Apache doesn&#8217;t know how to handle these requests and will give an error. Loading more modules in Apache however means that it&#8217;ll perform slower and uses more memory (it isn&#8217;t that much slower after loading the rewrite module, but you need to be aware of it: the more modules, the slower and the more memory &#8211; this applies to almost every application).</p>
<p>The next thing to reconsider is security. Since a .htaccess file will try to override existing configuration parameters, you need to tell Apache in its central configuration file that it is allowed for .htaccess files to do so.</p>
<p>In my central configuration, for this particular web site this is in it to allow overriding parameters:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">    &lt;directory &quot;/usr/local/webroot/htdocs&quot;&gt;
        Options FollowSymLinks
        AddOutputFilterByType DEFLATE text/html text/plain text/xml
        AllowOverride All
        Order allow,deny
        Allow from all
    &lt;/directory&gt;</pre></div></div>

<p>The <strong>AllowOverride</strong> parameter is the one needed. I chose &#8216;<em>All</em>&#8216;, but for the mod_rewrite module to work, only &#8216;<em>FileInfo</em>&#8216; is needed (according to the Apache documentation). &#8216;<em>All</em>&#8216; of course includes &#8216;<em>FileInfo</em>&#8216;.</p>
<p>This is all there is to tell about permalinks: think about them, configure them, and never touch em again <img src='http://www.boosten.org/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<img src="http://feeds.feedburner.com/~r/Boostenorg/~4/yhQR0vudF1Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.boosten.org/permalinks-in-wordpress/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Page Templates in WordPress</title>
		<link>http://www.boosten.org/page-templates-in-wordpress/</link>
		<comments>http://www.boosten.org/page-templates-in-wordpress/#comments</comments>
		<pubDate>Fri, 06 Nov 2009 19:45:51 +0000</pubDate>
		<dc:creator>Peter Boosten</dc:creator>
				<category><![CDATA[webpublishing]]></category>
		<category><![CDATA[custom fields]]></category>
		<category><![CDATA[page template]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.boosten.org/?p=399</guid>
		<description><![CDATA[Ever wondered why one would need Page Templates in Wordpress? This article will show you how to create them, how to use them, and even build some fun web site with it.]]></description>
			<content:encoded><![CDATA[<p>If you used WordPress for a while, and dug a bit deeper in its &#8216;guts&#8217;, then you probably would have heard about the <a href="http://codex.wordpress.org/File:Template_Hierarchy.png">Template Hierarchy</a>: it&#8217;s the way WordPress searches for the existence of certain templates in a theme.</p>
<p>A basic theme only needs two files: index.php and style.css. With these two files you can build an entire WordPress site. But themes most of the times exists of more templates, one for displaying single posts (single.php), one for displaying archives (archive.php), and also one for displaying pages (page.php). If you&#8217;re confused about the term page and post: posts are the articles that make the traditional blog, while pages display the more static information, like about pages.</p>
<p>Page Templates can be used to style pages totally different from others. But if you examine the hierarchy, you notice that WordPress first looks for pagename.php, whenever it wants to display a page. This means, that if I had an about.php file, I could style that totally different than all my other pages. What would I need Page Templates for then?</p>
<p>Suppose I had 5 writers on my site (which I haven&#8217;t, so I have to make up all the articles myself &#8211; if you want to write something as well, drop me a line), and I wanted the about pages of those writers to be differently styled than other pages, I could create 5 pagename.php files (which were basically the same, the only difference being the filename), which have to be maintained separately, if I wanted to have a consistent look and feel of these pages. Five files can be done, but what if I had 100 writers?</p>
<p>Here&#8217;s a perfect job for Page Templates: create only one (for writers), and apply this Page Template to the pages you want it applied to.</p>
<p>Let us create a Page Template. According to the <a href="http://codex.wordpress.org/Pages#Creating_Your_Own_Page_Templates">WordPress Codex</a> a Page Template needs some comments at the top, so that WordPress can recognize the file as a Page Template.</p>
<p><strong>A &#8216;warning&#8217; up front</strong> (just to let you enjoy the power of WordPress): I&#8217;m going to create some pages, attach Page Templates to them, and going to use Custom Fields as well. You might want to read up on Custom Fields in my previous articles (&#8220;<a href="http://www.boosten.org/using-custom-fields-in-wordpress-posts/">Using custom fields in WordPress posts</a>&#8221; and &#8220;<a href="http://www.boosten.org/example-uses-of-custom-fields-in-wordpress/">Example uses of custom fields in WordPress</a>&#8220;).</p>
<p>Second &#8216;warning&#8217;: If you&#8217;re going to follow my example, then it might put some extra menu options in your navigation bar, and confusing your visitors, so you might want to test this on a test site, not on your life site.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span> ?php
<span style="color: #666666; font-style: italic;">/*
Template Name: Book Review
*/</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Save this file as page-book-review.php in your theme directory. Now you have a Page Template.</p>
<p>Create another one, called page-book-overview.php.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span> ?php
<span style="color: #666666; font-style: italic;">/*
Template Name: Book Overview
*/</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Let me explain what I&#8217;m going to do: I want to create a page per book, and have that page display a picture of its cover, some information on the book (like author, ISBN, publisher), and have a small description of the book. The picture, author name, ISBN and publisher will be in a Custom Field, the description will go into the page. The title of the page will be the title of the book.</p>
<p>The Book Overview will show (clickable) pictures of all books, along with its title and author.</p>
<p><em>Disclaimer: I will copy the needed information from <a href="http://www.amazon.com">Amazon</a>, not the be their competitor, but just for demonstration purposes. The pictures are downloaded from Amazon as well. I&#8217;ve not read any of these books</em></p>
<p>Now I&#8217;m going to create some pages in a hierarchy. The first page to create is &#8216;Books&#8217;, which will have no content, but will have a Page Template assigned to it (The Book Overview Template).</p>
<p><img src="http://www.boosten.org/wp-content/uploads/2009/11/books.jpg" alt="books.jpg" border="0" width="660" height="411" /></p>
<p>Now let us create some book reviews, which should be child pages of the Books page. I&#8217;ll demonstrate one, but you&#8217;ll get the picture. I will not focus too much on creating the Custom Fields.</p>
<p><img src="http://www.boosten.org/wp-content/uploads/2009/11/book1.jpg" alt="book1.jpg" border="0" width="660" height="595" /></p>
<p>You might notice a thing or two: I&#8217;ve changed the parent of this page to the Books page, created above (this kind of hierarchy keeps your pages organized), I&#8217;ve assigned the &#8216;Book Review&#8217; Page Template to the page (which I&#8217;m going to do for all book reviews), and I&#8217;ve created some Custom Fields for author, ISBN, picture (called thumbnail) and publisher.</p>
<p>The result should be something like this:</p>
<p><img src="http://www.boosten.org/wp-content/uploads/2009/11/book2.jpg" alt="book2.jpg" border="0" width="660" height="291" /></p>
<p>Now we&#8217;re going to do the exciting stuff: actually style the Page Templates the way we want. I&#8217;m going to start with the overview page. </p>
<p>I want my Page Template to fit into my existing website, so I&#8217;m going to follow my current page.php for the layout.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&lt; ?php
/*
Template Name: Book Overview
*/
?&gt;
&nbsp;
&lt; ?php get_header(); ?&gt;
&nbsp;
&lt;div id=&quot;inner-wrapper&quot;&gt;
&nbsp;
  &lt;div id=&quot;content-single&quot;&gt;
 	&lt; ?php if ( (is_page('Books')) ) {
&nbsp;
	  query_posts(array('showposts' =&gt; 100, 'post_parent' =&gt; 354, 'post_type' =&gt; 'page'));
&nbsp;
       while (have_posts()) {
&nbsp;
		the_post(); // vital
&nbsp;
		$thumbPath = get_post_meta($post-&gt;ID, 'thumbnail', true);
&nbsp;
		$thumbPath = &quot;/wp-content/media/books/&quot; . $thumbPath;
	?&gt;
&nbsp;
	&lt;a href=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> the_permalink<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot; class=&quot;grid-book&quot;&gt;
		&lt;img src=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$thumbPath</span> ?<span style="color: #339933;">/&gt;</span><span style="color: #0000ff;">&quot; alt=&quot;</span><span style="color: #0000ff;">&quot; /&gt;&lt;br /&gt;
		&lt;span class=&quot;</span>grid<span style="color: #339933;">-</span>title<span style="color: #0000ff;">&quot;&gt;&lt; ?php the_title(); ?&gt;&lt;/span&gt;&lt;br /&gt;
		&lt;span class=&quot;</span>grid<span style="color: #339933;">-</span>author<span style="color: #0000ff;">&quot;&gt;&lt; ?php echo get_post_meta(<span style="color: #006699; font-weight: bold;">$post-&gt;ID</span>, 'author', true); ?&gt;</span>&lt;/span&gt;
	&lt;/a&gt;
&nbsp;
	&lt; ?php }
&nbsp;
	  }
	?&gt;
&nbsp;
&nbsp;
	&lt;/div&gt;&lt;!-- end content-single --&gt;
&nbsp;
&nbsp;
&lt;/div&gt;&lt;!-- end inner-wrapper --&gt;
&nbsp;
&lt; ?php get_footer(); ?&gt;</pre></div></div>

<p>What happened? The is_page(&#8216;Books&#8217;) check is done to ensure that this page only displays when the Page Template actually is connected to the Books page. In fact I&#8217;ve done this because I wanted to use this particular Page Template for several categories (of which Books is one), but I will not elaborate on that topic (unless on special request).</p>
<p>I call the query_posts function with several options: &#8216;showposts&#8217; will only return the first 100 records (in my example there are only 6, I want only the pages (post_type) of which the parent has ID 354 (in my case that&#8217;s the &#8216;Books&#8217; page &#8211; you can easily find the ID of a page, or post, by hovering the mouse over the page in the admin panel and view the status line of your browser).</p>
<p>I do not want to display the page, therefore I do not call the the_content() function, but I want to query the Custom Fields thumbnail and author. That&#8217;s why I call the_post(), since this will give me access to everything I need.</p>
<p>The first Custom Field to query is thumbnail. Since I only filled that field with the filename, I have to tell WordPress (or your browser) where to find the actual image file, so I prepend it with its full path. </p>
<p>Next I embed the image, the title of the post, and the Custom Field &#8216;author&#8217; in an anchor link to the actual page (the_permalink()).</p>
<p>I do this while I find pages that match my criteria.</p>
<p>The actual styling is done through css (this is personal taste, style it anyway you like):</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">/* Book reviews */</span>
<span style="color: #6666ff;">.grid-book</span> <span style="color: #00AA00;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">display</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">block</span><span style="color: #00AA00;">;</span>
        <span style="color: #000000; font-weight: bold;">float</span><span style="color: #00AA00;">:</span> <span style="color: #000000; font-weight: bold;">left</span><span style="color: #00AA00;">;</span>
        <span style="color: #000000; font-weight: bold;">width</span><span style="color: #00AA00;">:</span> <span style="color: #933;">150px</span><span style="color: #00AA00;">;</span>
        <span style="color: #000000; font-weight: bold;">height</span><span style="color: #00AA00;">:</span> <span style="color: #933;">200px</span><span style="color: #00AA00;">;</span>
        <span style="color: #000000; font-weight: bold;">border</span><span style="color: #00AA00;">:</span> <span style="color: #933;">1px</span> <span style="color: #993333;">solid</span> <span style="color: #cc00cc;">#999</span><span style="color: #00AA00;">;</span>
        <span style="color: #000000; font-weight: bold;">margin</span><span style="color: #00AA00;">:</span> <span style="color: #933;">10px</span><span style="color: #00AA00;">;</span>
        <span style="color: #000000; font-weight: bold;">text-align</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">center</span><span style="color: #00AA00;">;</span>
        <span style="color: #000000; font-weight: bold;">text-decoration</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #6666ff;">.grid-book</span> img <span style="color: #00AA00;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">border</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">none</span><span style="color: #00AA00;">;</span>
        <span style="color: #000000; font-weight: bold;">height</span><span style="color: #00AA00;">:</span> <span style="color: #933;">100px</span><span style="color: #00AA00;">;</span>
        <span style="color: #000000; font-weight: bold;">margin</span><span style="color: #00AA00;">:</span> <span style="color: #993333;">auto</span><span style="color: #00AA00;">;</span>
        <span style="color: #000000; font-weight: bold;">padding</span><span style="color: #00AA00;">:</span> <span style="color: #933;">10px</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #6666ff;">.grid-title</span> <span style="color: #00AA00;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">font-size</span><span style="color: #00AA00;">:</span> <span style="color: #933;">1.2em</span><span style="color: #00AA00;">;</span>
        <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#ff3355</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #6666ff;">.grid-author</span> <span style="color: #00AA00;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">font-size</span><span style="color: #00AA00;">:</span> <span style="color: #933;">1.0em</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>The result of this can be viewed here: <a href="http://www.boosten.org/books/">http://www.boosten.org/books/</a></p>
<p>Now on to the Page Template for the book review:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span> ?php
<span style="color: #666666; font-style: italic;">/*
Template Name: Book Review
*/</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
<span style="color: #339933;">&lt;</span> ?php get_header<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
  <span style="color: #339933;">&lt;</span>div id<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;inner-wrapper&quot;</span><span style="color: #339933;">&gt;</span>
    <span style="color: #339933;">&lt;</span>div id<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;content-single&quot;</span><span style="color: #339933;">&gt;</span>
      <span style="color: #339933;">&lt;</span> ?php <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span>have_posts<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
        <span style="color: #339933;">&lt;</span> ?php <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span>have_posts<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> the_post<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
          <span style="color: #339933;">&lt;</span>div id<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;book-info-col&quot;</span><span style="color: #339933;">&gt;</span>
&nbsp;
            <span style="color: #339933;">&lt;</span>h3 <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;post-title&quot;</span><span style="color: #339933;">&gt;&lt;</span> ?php the_title<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">&lt;/</span>h3<span style="color: #339933;">&gt;</span>
            <span style="color: #339933;">&lt;</span>p <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;book-author&quot;</span><span style="color: #339933;">&gt;</span>Author<span style="color: #339933;">:</span> <span style="color: #339933;">&lt;</span> ?php <span style="color: #b1b100;">echo</span> get_post_meta<span style="color: #009900;">&#40;</span><span style="color: #000088;">$post</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">ID</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'author'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">&lt;/</span>p<span style="color: #339933;">&gt;</span>
            <span style="color: #339933;">&lt;</span>p <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;book-publisher&quot;</span><span style="color: #339933;">&gt;</span>Publisher<span style="color: #339933;">:</span> <span style="color: #339933;">&lt;</span> ?php <span style="color: #b1b100;">echo</span> get_post_meta<span style="color: #009900;">&#40;</span><span style="color: #000088;">$post</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">ID</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'publisher'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">&lt;/</span>p<span style="color: #339933;">&gt;</span>
            <span style="color: #339933;">&lt;</span>p <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;book-isbn&quot;</span><span style="color: #339933;">&gt;</span>ISBN<span style="color: #339933;">:</span> <span style="color: #339933;">&lt;</span> ?php <span style="color: #b1b100;">echo</span> get_post_meta<span style="color: #009900;">&#40;</span><span style="color: #000088;">$post</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">ID</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'ISBN'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">&lt;/</span>p<span style="color: #339933;">&gt;</span>
&nbsp;
            <span style="color: #339933;">&lt;</span> ?php the_content<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
            <span style="color: #339933;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;clear&quot;</span><span style="color: #339933;">&gt;&lt;/</span>div<span style="color: #339933;">&gt;</span>
&nbsp;
            <span style="color: #339933;">&lt;</span> ?php edit_post_link<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'[edit page]'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'&lt;p&gt;'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
            <span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;&lt;!--</span> <span style="color: #990000;">end</span> book<span style="color: #339933;">-</span>info<span style="color: #339933;">-</span>col <span style="color: #339933;">--&gt;</span>
&nbsp;
            <span style="color: #339933;">&lt;</span>div id<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;book-pic-col&quot;</span><span style="color: #339933;">&gt;</span>
&nbsp;
              <span style="color: #339933;">&lt;</span> ?php
&nbsp;
               <span style="color: #000088;">$thumbPath</span> <span style="color: #339933;">=</span> get_post_meta<span style="color: #009900;">&#40;</span><span style="color: #000088;">$post</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">ID</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'thumbnail'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
               <span style="color: #000088;">$thumbPath</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;/wp-content/media/books/&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$thumbPath</span><span style="color: #339933;">;</span>
&nbsp;
               <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&lt;img src='<span style="color: #006699; font-weight: bold;">$thumbPath</span>' alt='' class='book-thumb' /&gt;&quot;</span><span style="color: #339933;">;</span>
&nbsp;
              <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
            <span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span> <span style="color: #339933;">&lt;!--</span> <span style="color: #990000;">end</span> book<span style="color: #339933;">-</span>pic<span style="color: #339933;">-</span>col <span style="color: #339933;">--&gt;</span>
&nbsp;
          <span style="color: #339933;">&lt;</span> ?php <span style="color: #b1b100;">endwhile</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
       <span style="color: #339933;">&lt;</span> ?php <span style="color: #b1b100;">endif</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
&nbsp;
    <span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span> <span style="color: #339933;">&lt;!--</span> <span style="color: #990000;">end</span> single<span style="color: #339933;">-</span>content <span style="color: #339933;">--&gt;</span>
   <span style="color: #339933;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;clear&quot;</span><span style="color: #339933;">&gt;&lt;/</span>div<span style="color: #339933;">&gt;</span>
  <span style="color: #339933;">&lt;/</span>div<span style="color: #339933;">&gt;</span> <span style="color: #339933;">&lt;!--</span> <span style="color: #990000;">end</span> inner<span style="color: #339933;">-</span>wrapper <span style="color: #339933;">--&gt;</span>
<span style="color: #339933;">&lt;</span> ?php get_footer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>This looks actually like a normal page.php, except that I make some function calls to grab the Custom Fields. I will not go each and every call, since I think the example speaks for itself. Now some styling:</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #cc00cc;">#book-info-col</span> <span style="color: #00AA00;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">width</span><span style="color: #00AA00;">:</span> <span style="color: #933;">400px</span><span style="color: #00AA00;">;</span>
        <span style="color: #000000; font-weight: bold;">float</span><span style="color: #00AA00;">:</span> <span style="color: #000000; font-weight: bold;">right</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span>
&nbsp;
<span style="color: #cc00cc;">#book-pic-col</span> <span style="color: #00AA00;">&#123;</span>
        <span style="color: #000000; font-weight: bold;">float</span><span style="color: #00AA00;">:</span> <span style="color: #000000; font-weight: bold;">right</span><span style="color: #00AA00;">;</span>
        <span style="color: #000000; font-weight: bold;">width</span><span style="color: #00AA00;">:</span> <span style="color: #933;">400px</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>To view these book reviews, just click on one of the books in the <a href="http://www.boosten.org/books/">overview page</a>.</p>
<img src="http://feeds.feedburner.com/~r/Boostenorg/~4/FRTYsvl911U" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.boosten.org/page-templates-in-wordpress/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Using triggers in MySQL</title>
		<link>http://www.boosten.org/using-triggers-in-mysql/</link>
		<comments>http://www.boosten.org/using-triggers-in-mysql/#comments</comments>
		<pubDate>Sun, 01 Nov 2009 22:11:09 +0000</pubDate>
		<dc:creator>Peter Boosten</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[gnuplot]]></category>
		<category><![CDATA[triggers]]></category>

		<guid isPermaLink="false">http://www.boosten.org/?p=347</guid>
		<description><![CDATA[I have some machines performing different actions on the same piece of information, and I wanted them to know about the previous action taken. That's when I came up with a solution using MySQL]]></description>
			<content:encoded><![CDATA[<p>S call me a geek for having several different machines at home, but I like to split different functions on different machines.</p>
<p>So I have a web server whose solely purpose it is to serve web pages (for 4 different external domains, and some test sites as well), which is completely separated from my MySQL server. Yet another server is doing my email, but also is used for some special purposes, like generating graphs.</p>
<p>Up till now I had this last machine generating graphs, which were rsynced once every hour to the web server. There was no trigger for generating the graph, so I had scheduled a cronjob once a day to generate those graphs.</p>
<p>One of these graphs is created from data input via a web form, which usually happens around 7 AM, and the graph is created at 9 AM, and the rsyncing takes place at 9:05 AM (actually again at 10:05 AM, and so on).</p>
<p>The problem with this method is that whenever the web form gets filled after 9 AM, the correct graphs don&#8217;t show up until the day after, and generating the same graphs more times a day was not an option for me.</p>
<p>So I found a way to synchronize all these actions by using a trigger in MySQL. I will be referring to my servers by the following names: Graph, MySQL and Web.</p>
<p>What are triggers? A trigger in MySQL is able to perform a task whenever a row in a table is inserted, updated, or deleted, and it can do that just before the row is actually altered, or after this joyful event.</p>
<p>Let&#8217;s start with the syntax:</p>

<div class="wp_syntax"><div class="code"><pre class="mysql" style="font-family:monospace;"><span style="color: #990099; font-weight: bold;">CREATE</span>
    <span style="color: #FF00FF;">&#91;</span><span style="color: #990099; font-weight: bold;">DEFINER</span> <span style="color: #CC0099;">=</span> <span style="color: #FF00FF;">&#123;</span> <span style="color: #000099;">user</span> <span style="color: #CC0099;">|</span> <span style="color: #990099; font-weight: bold;">CURRENT_USER</span> <span style="color: #FF00FF;">&#125;</span><span style="color: #FF00FF;">&#93;</span>
    <span style="color: #990099; font-weight: bold;">TRIGGER</span> trigger_name trigger_time trigger_event
    <span style="color: #990099; font-weight: bold;">ON</span> tbl_name <span style="color: #990099; font-weight: bold;">FOR EACH ROW</span> trigger_stmt</pre></div></div>

<p>Normally, a trigger runs with the authorizations of the user inserting, deleting or updating the table the trigger runs on, but you&#8217;re able to modify this behavior with the DEFINER clause. I&#8217;m not going to use this one, but made sure the authorizations of the user are in order.</p>
<p>The trigger_time can have two possible values, either BEFORE or AFTER. I want my actions taking place after the data is inserted.</p>
<p>The trigger_event can hold the values INSERT, UPDATE or DELETE.</p>
<p>The trigger_stmt (statement) is the action that gets executed when this trigger is activated.</p>
<p>I found in my quests, that it&#8217;s not possible, using standard MySQL, to have this trigger perform a system call, thus executing an external command. There are ways to do so, but it requires complex programs, calling named pipes or other ways. Since my applications aren&#8217;t time critical, I can live with a minute delay (the minute delay comes from cron, I will describe that below).</p>
<p>For this purpose I created an extra table in my database, to hold the action that needs to be performed:</p>

<div class="wp_syntax"><div class="code"><pre class="mysql" style="font-family:monospace;"><span style="color: #990099; font-weight: bold;">CREATE</span> <span style="color: #990099; font-weight: bold;">TABLE</span> <span style="color: #008000;">`work`</span> <span style="color: #FF00FF;">&#40;</span>
  <span style="color: #008000;">`name`</span> <span style="color: #999900; font-weight: bold;">varchar</span><span style="color: #FF00FF;">&#40;</span><span style="color: #008080;">25</span><span style="color: #FF00FF;">&#41;</span> <span style="color: #990099; font-weight: bold;">DEFAULT</span> <span style="color: #9900FF; font-weight: bold;">NULL</span>
<span style="color: #FF00FF;">&#41;</span></pre></div></div>

<p>Nothing fancy, it&#8217;s just to hold the action, until it has been performed.</p>
<p>Now for the trigger:</p>

<div class="wp_syntax"><div class="code"><pre class="mysql" style="font-family:monospace;"><span style="color: #990099; font-weight: bold;">CREATE</span> <span style="color: #990099; font-weight: bold;">TRIGGER</span> nutstrigger <span style="color: #990099; font-weight: bold;">AFTER</span> <span style="color: #990099; font-weight: bold;">INSERT</span> <span style="color: #990099; font-weight: bold;">ON</span> nuts
<span style="color: #990099; font-weight: bold;">FOR EACH ROW</span>
<span style="color: #990099; font-weight: bold;">BEGIN</span>
  <span style="color: #990099; font-weight: bold;">insert</span> <span style="color: #990099; font-weight: bold;">into</span> <span style="color: #990099; font-weight: bold;">work</span> <span style="color: #990099; font-weight: bold;">values</span> <span style="color: #FF00FF;">&#40;</span><span style="color: #008000;">'nuts'</span><span style="color: #FF00FF;">&#41;</span><span style="color: #000033;">;</span>
<span style="color: #009900;">END</span></pre></div></div>

<p>Don&#8217;t pay attention to the word &#8216;nuts&#8217;. In the Netherlands we call the utility companies (the ones that deliver power, gas and water to our houses) nuts, and I keep statistics on those on a daily bases by noting down the actual meter readings (don&#8217;t ask me why, I just like numbers).</p>
<p>I don&#8217;t know why we call those companies nuts, but I know I&#8217;m going nuts whenever they send a bill <img src='http://www.boosten.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
<p>Back to the trigger: AFTER a new row is inserted into table nuts, insert the word &#8216;nuts&#8217; into table work. If I weren&#8217;t to do nothing with this table work, then the word &#8216;nuts&#8217; would be added every day to this table.</p>
<p>But that&#8217;s not my intention.</p>
<p>Therefore, on server Graph I wrote the following shell script, that is executed every minute (cron).</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
&nbsp;
<span style="color: #007800;">TASKS</span>=<span style="color: #000000; font-weight: bold;">`/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>mysql <span style="color: #660033;">-BNe</span> <span style="color: #ff0000;">'select distinct(name) from work'</span><span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #007800;">day</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">date</span> +<span style="color: #000000; font-weight: bold;">%</span>d<span style="color: #000000; font-weight: bold;">`</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">for</span> TASK <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #800000;">${TASKS}</span>; <span style="color: #000000; font-weight: bold;">do</span>
  <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #800000;">${TASK}</span> <span style="color: #000000; font-weight: bold;">in</span>
  nuts<span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>mysql <span style="color: #660033;">-BNe</span> <span style="color: #ff0000;">'delete from work where name=&quot;nuts&quot;'</span>
	   <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>peter<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>nuts2.sh
	   <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$day</span>&quot;</span> = <span style="color: #ff0000;">&quot;01&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span> 
	   <span style="color: #000000; font-weight: bold;">then</span>
		<span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>peter<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>nutsmonthly.sh
	   <span style="color: #000000; font-weight: bold;">fi</span>
        <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>mysql <span style="color: #660033;">-BNe</span> <span style="color: #ff0000;">'insert into work values (&quot;sync&quot;)'</span>
	   <span style="color: #000000; font-weight: bold;">;;</span>
  <span style="color: #000000; font-weight: bold;">esac</span>
<span style="color: #000000; font-weight: bold;">done</span></pre></div></div>

<p>It&#8217;s no rocket science, but let me explain:<br />
TASKS is filled with a list of unique (distinct) actions it finds in table work. Distinct, because there&#8217;s no point in running the action more than once within a minute. These actions are separated by blanks, so make sure you don&#8217;t define any actions with blanks in them.</p>
<p>The day variable I need to do some special actions on the first of the month, but that could have been solved another way.</p>
<p>With the for loop, I loop through these different actions. The case selector then checks whether an action has been defined for this server. In this case, it&#8217;s only programmed to react on &#8216;nuts&#8217;. If it actually finds this action, I remove it from the table, or otherwise it would find it minute after minute.</p>
<p>I then run the nuts2.sh script, which basically performs a query in MySQL, and creates a graph of it, using GnuPlot. Depending on the day of the month I run the nutsmonthly.sh script, which does the same, but generates monthly graphs.</p>
<p>The last MySQL inserts another action into the work table, for another server, Web. This server copies the generated graphs from Graph. Remember, I do this on separate servers to keep the web server as clean as possible.</p>
<p>The script on Web looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
&nbsp;
<span style="color: #007800;">TASKS</span>=<span style="color: #000000; font-weight: bold;">`/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>mysql <span style="color: #660033;">-BNe</span> <span style="color: #ff0000;">'select distinct(name) from work'</span> peter<span style="color: #000000; font-weight: bold;">`</span>
<span style="color: #007800;">day</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">date</span> +<span style="color: #000000; font-weight: bold;">%</span>d<span style="color: #000000; font-weight: bold;">`</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">for</span> TASK <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #800000;">${TASKS}</span>; <span style="color: #000000; font-weight: bold;">do</span>
  <span style="color: #000000; font-weight: bold;">case</span> <span style="color: #800000;">${TASK}</span> <span style="color: #000000; font-weight: bold;">in</span>
  <span style="color: #c20cb9; font-weight: bold;">sync</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>local<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>mysql <span style="color: #660033;">-BNe</span> <span style="color: #ff0000;">'delete from work where name=&quot;sync&quot;'</span>
	   <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>peter<span style="color: #000000; font-weight: bold;">/</span>bin<span style="color: #000000; font-weight: bold;">/</span>resync.sh
	   <span style="color: #000000; font-weight: bold;">;;</span>
  <span style="color: #000000; font-weight: bold;">esac</span>
<span style="color: #000000; font-weight: bold;">done</span></pre></div></div>

<p>Same story here, but it checks on another action (&#8216;sync&#8217;), and does something else. resync.sh holds two rsync commands.</p>
<p>The last script is actually no longer related to the trigger, but it shows how servers can be daisy changed if they have to perform some action on the same trigger.</p>
<img src="http://feeds.feedburner.com/~r/Boostenorg/~4/OCuSbS5EV_I" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.boosten.org/using-triggers-in-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Shortcodes in WordPress</title>
		<link>http://www.boosten.org/shortcodes-in-wordpress/</link>
		<comments>http://www.boosten.org/shortcodes-in-wordpress/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 17:09:28 +0000</pubDate>
		<dc:creator>Peter Boosten</dc:creator>
				<category><![CDATA[webpublishing]]></category>
		<category><![CDATA[shortcodes]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.boosten.org/?p=316</guid>
		<description><![CDATA[Wordpress has many secrets for normal users, custom fields is an example of these secrets. Shortcodes is another one, which can be used rather simple, if you know how.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.boosten.org/using-custom-fields-in-wordpress-posts/">Custom Fields</a> may come in handy if you wanted to add something to your post, but their content is always outside the actual content of a post (although inside the loop).</p>
<p>But what if you wanted to insert something in a post as content, for instance the result of a function?</p>
<p>Well, that&#8217;s where shortcodes can be used. Shortcodes are available to mortals since WordPress version 2.5, so be sure to be up to date (and not only for shortcodes!).</p>
<p>Take a look at my <a href="/about">about</a> page (you don&#8217;t have to, I will copy the relevant text here).</p>
<p>There&#8217;s this text:</p>
<p><quote>My name is Peter. I’m 43 years of age, &#8230;</quote></p>
<p>Next year when you read this, I&#8217;m not 43 anymore, but will be 44 of age. That means that I have to modify that about page for at least once a year, to update my age. Not that that&#8217;s such a problem, but I don&#8217;t want to confuse you with (or even worse: lie to you about) a false age. </p>
<p>If I edit that about page, the actual text looks like this:</p>
<pre>
My name is Peter. I'm [peter-age] years of age,
</pre>
<p>How does WordPress know how to translate this piece of text-between-brackets ([peter-age]) into my age?</p>
<p>It follows the same principle as filters and actions (used in <a href="http://www.boosten.org/a-primer-on-writing-wordpress-plugins/">plugins</a>), in fact you could even write a plugin, where you define shortcodes (and I know several plugin writers have).</p>
<p>For my examples I will be modifying functions.php in my theme directory. You probably have a functions.php in your theme directory, and if you don&#8217;t have one, I&#8217;ll show you how to create it. There&#8217;s one drawback in using this functions.php: if you switch themes, your shortcode will not be known in that other theme. If you want to prevent that, you can follow the instructions on <a href="http://www.boosten.org/a-primer-on-writing-wordpress-plugins/">plugins</a> on this site.</p>
<p>Your basic functions.php should look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span> ?php
&nbsp;
<span style="color: #666666; font-style: italic;">// lots of code here, or not if you created this one yourself</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>To use shortcodes, you need actually two things: you have to tell WordPress that the shortcode exists, and you have to tell WordPress what to do if it encounters that shortcode. this is done with the add_shortcode() function.</p>
<p>In my functions.php is this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span> ?php
&nbsp;
&nbsp;
add_shortcode<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'peter-age'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'calc_my_age'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>This snippet tells WordPress that if it stumbles over [peter-age], it should call function calc_my_age(); So the only thing to do is to define that function.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span> ?php
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> calc_my_age<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #0000ff;">&quot;43&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
add_shortcode<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'peter-age'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'calc_my_age'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>That&#8217;s it. We&#8217;re done. We&#8217;ve created a shortcode. Till next time.</p>
<p>No wait, that would be too easy, since I would have to modify that function annually, and that would be even more cumbersome than modifying the post itself. I&#8217;ll carry on.</p>
<p>One note though: although you could &#8216;echo&#8217; the value back to the post, changes are that your layout would get messed up (if I recall correctly the place where that &#8217;43&#8242; would show up isn&#8217;t even defined), so always use &#8216;return&#8217;. </p>
<p>Let&#8217;s create a useful function, that actually updates my age as it evolves (or as I evolve, or age).</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span> ?php
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> calc_my_age<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// define the dates</span>
 	<span style="color: #000088;">$now</span><span style="color: #339933;">=</span><span style="color: #990000;">strtotime</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;now&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 	<span style="color: #000088;">$birthdate</span><span style="color: #339933;">=</span><span style="color: #990000;">strtotime</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;24 August 1966&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  	<span style="color: #000088;">$lengths</span>         <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;60&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;60&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;24&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;7&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;4.35&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;12&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;10&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  	<span style="color: #000088;">$difference</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$now</span> <span style="color: #339933;">-</span> <span style="color: #000088;">$birthdate</span><span style="color: #339933;">;</span>
&nbsp;
  	<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$j</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$difference</span> <span style="color: #339933;">&gt;=</span> <span style="color: #000088;">$lengths</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$j</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$j</span> <span style="color: #339933;">&lt;</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$lengths</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> <span style="color: #000088;">$j</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    		<span style="color: #000088;">$difference</span> <span style="color: #339933;">/=</span> <span style="color: #000088;">$lengths</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$j</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  	<span style="color: #009900;">&#125;</span>
&nbsp;
  	<span style="color: #000088;">$difference</span> <span style="color: #339933;">=</span> <span style="color: #990000;">intval</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$difference</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
  	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$difference</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span>
&nbsp;
add_shortcode<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'peter-age'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'calc_my_age'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Although there are definitely easier ways to calculate ones birthday, I translate both dates (the current one on $now, and my birth date in $birthdate &#8211; now that you know: congratulations are welcome in August <img src='http://www.boosten.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  ) in unix timestamps (seconds since Epoch), calculate the difference, and divide the number by seconds, minutes, hours, days, etc. The outcome of these divisions is my age in real, and I take the part before the decimal separator. That&#8217;s my age (43).</p>
<p>I have to tell you a small secret: it&#8217;s not only the about page I don&#8217;t want to update, but also this article. So somewhere at the top, I included this text in the post:</p>
<pre>
Next year when you read this, I'm not [peter-age] anymore, but will be [peter-age modifier="1"] of age.
</pre>
<p>Notice the second call to shortcode, especially the &#8216;modifier&#8217; thingemy? It&#8217;s possible to call shortcodes with parameters, and here I tell this shortcode to pass the value &#8217;1&#8242; to the function. Also notice that the first call has no such parameter, so it&#8217;s possible to define a default value.</p>
<p>Here&#8217;s what my function looks like:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span> ?php
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> calc_my_age<span style="color: #009900;">&#40;</span><span style="color: #000088;">$atts</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
  	<span style="color: #666666; font-style: italic;">// give $atts a default value</span>
	<span style="color: #990000;">extract</span><span style="color: #009900;">&#40;</span>shortcode_atts<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    		<span style="color: #0000ff;">'modifier'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">&quot;0&quot;</span><span style="color: #339933;">,</span>
    	<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$atts</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
	<span style="color: #666666; font-style: italic;">// define the dates</span>
 	<span style="color: #000088;">$now</span><span style="color: #339933;">=</span><span style="color: #990000;">strtotime</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;now&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 	<span style="color: #000088;">$birthdate</span><span style="color: #339933;">=</span><span style="color: #990000;">strtotime</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;24 August 1966&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  	<span style="color: #000088;">$lengths</span>         <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;60&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;60&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;24&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;7&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;4.35&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;12&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;10&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  	<span style="color: #000088;">$difference</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$now</span> <span style="color: #339933;">-</span> <span style="color: #000088;">$birthdate</span><span style="color: #339933;">;</span>
&nbsp;
  	<span style="color: #b1b100;">for</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$j</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> <span style="color: #000088;">$difference</span> <span style="color: #339933;">&gt;=</span> <span style="color: #000088;">$lengths</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$j</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000088;">$j</span> <span style="color: #339933;">&lt;</span> <span style="color: #990000;">count</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$lengths</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-</span><span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span> <span style="color: #000088;">$j</span><span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    		<span style="color: #000088;">$difference</span> <span style="color: #339933;">/=</span> <span style="color: #000088;">$lengths</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$j</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
  	<span style="color: #009900;">&#125;</span>
&nbsp;
  	<span style="color: #000088;">$difference</span> <span style="color: #339933;">=</span> <span style="color: #990000;">intval</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$difference</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000088;">$difference</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$difference</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>int<span style="color: #009900;">&#41;</span><span style="color: #000088;">$modifier</span><span style="color: #339933;">;</span>
&nbsp;
  	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$difference</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span>
&nbsp;
add_shortcode<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'peter-age'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'calc_my_age'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>So what happened? First of all, the function is called with a parameter, and the function has to know you&#8217;re passing parameters to it.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> calc_my_age<span style="color: #009900;">&#40;</span><span style="color: #000088;">$atts</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span></pre></div></div>

<p>Next, I want to give the parameter &#8216;modifier&#8217; a default value.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&nbsp;
  	<span style="color: #666666; font-style: italic;">// give $atts a default value</span>
	<span style="color: #990000;">extract</span><span style="color: #009900;">&#40;</span>shortcode_atts<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    		<span style="color: #0000ff;">'modifier'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">&quot;0&quot;</span><span style="color: #339933;">,</span>
    	<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$atts</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>I want my age not to be modified when I pass no modifier, although it would be nice to get a few years off (who am I kidding?).</p>
<p>And a bit further I add the value of modifier to the difference:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">  <span style="color: #000088;">$difference</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$difference</span> <span style="color: #339933;">+</span> <span style="color: #009900;">&#40;</span>int<span style="color: #009900;">&#41;</span><span style="color: #000088;">$modifier</span><span style="color: #339933;">;</span></pre></div></div>

<p>That simple. You can even pass more parameters to shortcodes, if you wanted to ([peter-age modifier="-10" hair="yes"]) <img src='http://www.boosten.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
<p>But you can do more with shortcodes.</p>
<p>Suppose you wanted to embed some words in your post in strong, italics and red text, and you do that quite often, wouldn&#8217;t be nice to have some shortcode (!) for that?</p>
<p>I mean, suppose you wanted to type your text like this:</p>
<p>This is [special]very special[/special] text, looking like this: <quote>This is <span style="color: red;"><strong><i>very special</i></strong></span> text</quote></p>
<p>This is also possible with shortcodes.</p>
<p>Let&#8217;s see how the function would look like:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span> ?php
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> my_special_text<span style="color: #009900;">&#40;</span><span style="color: #000088;">$atts</span><span style="color: #339933;">,</span> <span style="color: #000088;">$content</span><span style="color: #339933;">=</span><span style="color: #009900; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
  <span style="color: #b1b100;">return</span> <span style="color: #0000ff;">'&lt;span style=&quot;color: red;&quot;&gt;&lt;strong&gt;&lt;i&gt;'</span> <span style="color: #339933;">.</span> do_shortcode<span style="color: #009900;">&#40;</span><span style="color: #000088;">$content</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;/i&gt;&lt;/strong&gt;'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span>
&nbsp;
add_shortcode<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'special'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'my_special_text'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>If we want to embed content in shortcodes, then we actually <span style="color: red;"><strong><i>must</i></strong></span> (yeah, I used the shortcode here) pass two parameters to the function we call, the second one being the $content parameter, although we do not have to use the first one.</p>
<p>In short we return the content, surrounded by some extra text, in this case some xhtml tags. The do_shortcode() function makes it possible to actually embed shortcodes, just like you would embed xhtml.</p>
<pre>
[a]
  [b]
    [c]
    [/c]
  [/b]
[/a]
</pre>
<p>You might recognize <a href="http://en.wikipedia.org/wiki/BBCode">BBCodes</a> here <img src='http://www.boosten.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>That&#8217;s all for now. You can do this, and much more with shortcodes. Enjoy your shortcodes.</p>
<img src="http://feeds.feedburner.com/~r/Boostenorg/~4/fXoBkn2R_O8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.boosten.org/shortcodes-in-wordpress/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Example uses of custom fields in WordPress</title>
		<link>http://www.boosten.org/example-uses-of-custom-fields-in-wordpress/</link>
		<comments>http://www.boosten.org/example-uses-of-custom-fields-in-wordpress/#comments</comments>
		<pubDate>Tue, 06 Oct 2009 20:17:40 +0000</pubDate>
		<dc:creator>Peter Boosten</dc:creator>
				<category><![CDATA[webpublishing]]></category>
		<category><![CDATA[custom fields]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.boosten.org/?p=310</guid>
		<description><![CDATA[In the previous article I gave some practical examples of custom fields in Wordpress, and now I give some more.]]></description>
			<content:encoded><![CDATA[<p>In the <a href="http://www.boosten.org/using-custom-fields-in-wordpress-posts/">previous article</a> I showed how to create Custom Fields, and how to use them. I won&#8217;t go into the creating part anymore, since you could read that in the last article.</p>
<p>Let&#8217;s focus on styling.</p>
<p>Suppose you wanted different colors on different posts in home page, how would you do that?</p>
<p>The answer is simple: Custom Fields. If we created a Custom Field called post_color (I&#8217;m always reluctant to use blanks in Custom Field names, but I suppose it&#8217;s alright), and assigned a color per post (like red, green, black), then we&#8217;re ready to rumble.</p>
<p>In modern themes, posts are given a default set of css classes by using the post_class() function. This function can be expanded by giving it our own classes as parameter.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&lt; ?php while (have_posts()) : the_post(); ?&gt;
&nbsp;
&lt; ?php
  $postcolor=get_post_meta($post-&gt;ID, 'post_color', true);
?&gt;
&nbsp;
&lt;div <span style="color: #000000; font-weight: bold;">&lt;?php</span> post_class<span style="color: #009900;">&#40;</span><span style="color: #000088;">$postcolor</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span> id=&quot;post-&lt; ?php the_ID(); ?&gt;&quot;&gt;
&nbsp;
&lt;/div&gt;</pre></div></div>

<p>In this example we extract the Custom Field post_color from the post (just one) and pass the value to post_class().</p>
<p>I you now reload your site, another class has been assigned to each and every post where you added the Custom Field to.</p>
<p>This class can then be used in your stylesheet (style.css) to add extra properties to the particular post, like</p>

<div class="wp_syntax"><div class="code"><pre class="css" style="font-family:monospace;"><span style="color: #6666ff;">.red</span> <span style="color: #00AA00;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">background-color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#f00</span><span style="color: #00AA00;">;</span>
  <span style="color: #000000; font-weight: bold;">color</span><span style="color: #00AA00;">:</span> <span style="color: #cc00cc;">#fff</span><span style="color: #00AA00;">;</span>
<span style="color: #00AA00;">&#125;</span></pre></div></div>

<p>This example will give a red background, and white foreground colors.<br />
(I know, it&#8217;s an ugly example, but it fits the purposes).</p>
<p>Now create every possible color combination you can imagine, and add them to your posts <img src='http://www.boosten.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Suppose you wanted to decide per post if you wanted a sidebar or not (and also: which sidebar if you have more than one), this is also possible with Custom Fields.</p>
<p>Lets start at the beginning, by defining two additional sidebars for widgets (I&#8217;m still working on the default theme).</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span> ?php
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">function_exists</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'register_sidebar'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        register_sidebar<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
                <span style="color: #0000ff;">'before_widget'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'&lt;li id=&quot;%1$s&quot; class=&quot;widget %2$s&quot;&gt;'</span><span style="color: #339933;">,</span>
                <span style="color: #0000ff;">'after_widget'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'&lt;/li&gt;'</span><span style="color: #339933;">,</span>
                <span style="color: #0000ff;">'before_title'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'&lt;h2 class=&quot;widgettitle&quot;&gt;'</span><span style="color: #339933;">,</span>
                <span style="color: #0000ff;">'after_title'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'&lt;/h2&gt;'</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">function_exists</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'register_sidebar'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        register_sidebar<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
                <span style="color: #0000ff;">'before_widget'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'&lt;li id=&quot;%1$s&quot; class=&quot;widget %2$s&quot;&gt;'</span><span style="color: #339933;">,</span>
                <span style="color: #0000ff;">'after_widget'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'&lt;/li&gt;'</span><span style="color: #339933;">,</span>
                <span style="color: #0000ff;">'before_title'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'&lt;h2 class=&quot;widgettitle&quot;&gt;'</span><span style="color: #339933;">,</span>
                <span style="color: #0000ff;">'after_title'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'&lt;/h2&gt;'</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">function_exists</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'register_sidebar'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        register_sidebar<span style="color: #009900;">&#40;</span><span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
                <span style="color: #0000ff;">'before_widget'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'&lt;li id=&quot;%1$s&quot; class=&quot;widget %2$s&quot;&gt;'</span><span style="color: #339933;">,</span>
                <span style="color: #0000ff;">'after_widget'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'&lt;/li&gt;'</span><span style="color: #339933;">,</span>
                <span style="color: #0000ff;">'before_title'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'&lt;h2 class=&quot;widgettitle&quot;&gt;'</span><span style="color: #339933;">,</span>
                <span style="color: #0000ff;">'after_title'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'&lt;/h2&gt;'</span><span style="color: #339933;">,</span>
        <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>When this is in your functions.php (in your theme directory), and browse to your widget page in the appearance section of your administration backend, then you&#8217;ll see three sidebars, numbered 1 to 3. Just drag some widgets to all of them, preferably different ones, to make use of them in this example. The above snippet is just the part that is needed to create 3 widgetized sidebars, there might be more code already in your functions.php.</p>
<p>The way we are going to call these different sidebars from the theme is by using the dynamic_sidebar() function. This function takes one parameter: the number (or if you defined it, its name) of the sidebar, and defaults to 1. So we could call it with dynamic_sidebar(3), and it&#8217;ll show the third sidebar we just filled with some widgets.</p>
<p>Now modify three posts and add a Custom Field to each, called &#8216;sidebar&#8217;, their values should be 1, 2 and 3 (just to keep it simple). Make sure you have a fourth post without the sidebar Custom Field.</p>
<p>The next part to focus on is the single.php file. Do not alter your index.php to reflect the changes below, since it could have some strange effects. Remember that Custom Fields are part of a post, and when displaying 5 posts on your index.php file, it&#8217;s kinda strange if you try to change the sidebar 5 times. I&#8217;m actually not sure what would happen, probably the last post on the page is chosen as sidebar, but I&#8217;m not going to try. You&#8217;re welcome to try (and report back), but I&#8217;m certainly not promoting this: do at your own risk!</p>
<p>Let&#8217;s describe what&#8217;s going to happen in single.php: upon querying the database for the post (and its Custom Field), we have to decide whether the post gets a sidebar or not. Depending on this we have to style our page differently. In the Default theme, the difference between the both are two classes named narrowcolumn (page with sidebar) and widecolumn (page without sidebar). If the sidebar is in the page, also a div called sidebar is visible.</p>
<p>So lets have a look at the single.php (I&#8217;m going to strip it a bit, for readability):</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&lt; ?php
/**
 * @package WordPress
 * @subpackage Default_Theme
 */
&nbsp;
get_header();
?&gt;
  &lt;div id=&quot;content&quot; class=&quot;widecolumn&quot; role=&quot;main&quot;&gt;
  &lt; ?php if (have_posts()) : while (have_posts()) : the_post(); ?&gt;
&nbsp;
      &lt;div <span style="color: #000000; font-weight: bold;">&lt;?php</span> post_class<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span> id=&quot;post-&lt; ?php the_ID(); ?&gt;&quot;&gt;
           &lt;h2&gt;&lt; ?php the_title(); ?&gt;&lt;/h2&gt;
&nbsp;
           &lt;div class=&quot;entry&quot;&gt;
               &lt; ?php the_content('&lt;p class=&quot;serif&quot;&gt;Read the rest of this entry &amp;raquo;'); ?&gt;
           &lt;/div&gt;
      &lt;/div&gt;
&nbsp;
      &lt; ?php comments_template(); ?&gt;
&nbsp;
   &lt; ?php endwhile; else: ?&gt;
&nbsp;
       &lt;p&gt;Sorry, no posts matched your criteria.&lt;/p&gt;
&nbsp;
&lt; ?php endif; ?&gt;
&nbsp;
    &lt;/div&gt;
&nbsp;
&lt; ?php get_footer(); ?&gt;</pre></div></div>

<p>There&#8217;s already one minor problem here: the part where the layout is decided (&#8216;widecolumn&#8217; vs &#8216;narrowcolumn&#8217;) is outside the loop, so we have to move that part inside the loop. Also are we going to query the post for the Custom Field &#8216;sidebar&#8217; (just one, it wouldn&#8217;t make sense to have more than one sidebar Custom Field in our setup, but it could be if you have multiple sidebars in your posts).</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&lt; ?php
/**
 * @package WordPress
 * @subpackage Default_Theme
 */
&nbsp;
get_header();
?&gt;
&nbsp;
  &lt; ?php if (have_posts()) : while (have_posts()) : the_post(); ?&gt;
    &lt; ?php
      $sidebar=get_post_meta($post-&gt;ID, ‘sidebar’, true);
      if ($sidebar) 
        $columnclass='narrowcolumn';
      else
        $columnclass='widecolumn';
&nbsp;
    ?&gt;
    &lt;div id=&quot;content&quot; class=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$columnclass</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot; role=&quot;main&quot;&gt;
&nbsp;
      &lt;div <span style="color: #000000; font-weight: bold;">&lt;?php</span> post_class<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span> id=&quot;post-&lt; ?php the_ID(); ?&gt;&quot;&gt;
           &lt;h2&gt;&lt; ?php the_title(); ?&gt;&lt;/h2&gt;
&nbsp;
           &lt;div class=&quot;entry&quot;&gt;
               &lt; ?php the_content('&lt;p class=&quot;serif&quot;&gt;Read the rest of this entry &amp;raquo;'); ?&gt;
           &lt;/div&gt;
      &lt;/div&gt;
&nbsp;
      &lt; ?php comments_template(); ?&gt;
&nbsp;
   &lt; ?php endwhile; else: ?&gt;
&nbsp;
       &lt;p&gt;Sorry, no posts matched your criteria.&lt;/p&gt;
&nbsp;
&lt; ?php endif; ?&gt;
&nbsp;
    &lt;/div&gt;
&nbsp;
&lt; ?php get_footer(); ?&gt;</pre></div></div>

<p>Again this coding gives some styling problems: the post(s) (plural, because that&#8217;s how the loop works) need to be inside the content div, but it gets called more often than it should be. Therefore the background goes haywire, but for our purposes it suffices. What needs to be done to make it clean, but outside the scope of this article, is to differentiate between the content (posts and the sidebar), and the individual columns (left column and sidebar). Content (and sidebar) are then outside the loop, while the left column (including the narrowcolumn/widecolumn class) is inside the loop. Please ignore the vanishing background for now.</p>
<p>*EDIT*: it seems I&#8217;m the only one having this problem with one of my Firefoxes.</p>
<p>What here happens is that the post is queried for the Custom Field &#8216;sidebar&#8217; (nothing new here), and based on its existence $columnclass is set to either &#8216;narrowcolumn&#8217; (with sidebar) or &#8216;widecolumn&#8217; (no sidebar). You can already see the difference between posts with the &#8216;sidebar&#8217; Custom Fields, and those without.</p>
<p>Now we need to have the actual sidebar display:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&lt; ?php
/**
 * @package WordPress
 * @subpackage Default_Theme
 */
&nbsp;
get_header();
?&gt;
&nbsp;
  &lt; ?php if (have_posts()) : while (have_posts()) : the_post(); ?&gt;
    &lt; ?php
      $sidebar=get_post_meta($post-&gt;ID, ‘sidebar’, true);
      if ($sidebar) 
        $columnclass='narrowcolumn';
      else
        $columnclass='widecolumn';
&nbsp;
    ?&gt;
    &lt;div id=&quot;content&quot; class=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$columnclass</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot; role=&quot;main&quot;&gt;
&nbsp;
      &lt;div <span style="color: #000000; font-weight: bold;">&lt;?php</span> post_class<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span> id=&quot;post-&lt; ?php the_ID(); ?&gt;&quot;&gt;
           &lt;h2&gt;&lt; ?php the_title(); ?&gt;&lt;/h2&gt;
&nbsp;
           &lt;div class=&quot;entry&quot;&gt;
               &lt; ?php the_content('&lt;p class=&quot;serif&quot;&gt;Read the rest of this entry &amp;raquo;'); ?&gt;
           &lt;/div&gt;
      &lt;/div&gt;
&nbsp;
      &lt; ?php comments_template(); ?&gt;
&nbsp;
   &lt; ?php endwhile; else: ?&gt;
&nbsp;
       &lt;p&gt;Sorry, no posts matched your criteria.&lt;/p&gt;
&nbsp;
&lt; ?php endif; ?&gt;
&nbsp;
    &lt;/div&gt;
&nbsp;
  &lt; ?php
    if ($sidebar)
  ?&gt;
    &lt;div id=&quot;sidebar&quot; role=&quot;complementary&quot;&gt;
      &lt;ul&gt;
        &lt; ?php if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar((int)$sidebar) ) : ?&gt;
      &lt;/ul&gt;
    &lt;/div&gt;
  &lt; ?php
    endif;
  ?&gt;
&nbsp;
&lt; ?php get_footer(); ?&gt;</pre></div></div>

<p>What happens here: if the variable $sidebar exists (i.e. contains a value) when we collected it from the post, and when the function &#8216;dynamic_sidebar&#8217; exists, then call it and use the sidebar number as its parameter. Since all variables in PHP are treated as strings, dynamic_sidebar() doesn&#8217;t recognize our input without special treatment, since we decided to use numbers (which is implicit when not giving names to sidebars). Therefore the variable $sidebar is typecasted to an integer (int).</p>
<p>If you created the three sidebars, and gave the Custom Field &#8216;sidebar&#8217; a number between 1 and 3, then that sidebar will appear in your post. If you gave it a number higher than 3 (while only having 3 sidebars), then the layout will create the space for a sidebar, but no sidebar will show up.</p>
<p>Having the freedom to decide on <em>whether</em> a sidebar should appear, and even the freedom <em>which</em> sidebar should appear, gives a whole lot of powerful options to WordPress.</p>
<p>That&#8217;s it for now. I hope you enjoyed this article.</p>
<img src="http://feeds.feedburner.com/~r/Boostenorg/~4/DPiwD8LgCC0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.boosten.org/example-uses-of-custom-fields-in-wordpress/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using custom fields in WordPress posts</title>
		<link>http://www.boosten.org/using-custom-fields-in-wordpress-posts/</link>
		<comments>http://www.boosten.org/using-custom-fields-in-wordpress-posts/#comments</comments>
		<pubDate>Mon, 28 Sep 2009 18:11:41 +0000</pubDate>
		<dc:creator>Peter Boosten</dc:creator>
				<category><![CDATA[webpublishing]]></category>
		<category><![CDATA[custom fields]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.boosten.org/?p=290</guid>
		<description><![CDATA[A lot has been written about custom fields in Wordpress. This article describes some practical uses for them, and how to embed them into your posts.]]></description>
			<content:encoded><![CDATA[<p>Probably everyone has seen (and ignored) the Custom Fields (see screenshot) in WordPress when writing a post, just because the results are unknown when filling something in these fields, and one is afraid of breaking something, or, since they&#8217;re not needed anyway, why not ignore them forever.</p>
<p><img src="http://www.boosten.org/wp-content/uploads/2009/09/customfields1.png" alt="customfields1.png" border="0" width="660" height="398" /></p>
<p>Well, the potential uses are unlimited, so I&#8217;m going to describe some of them.</p>
<p>In most examples about the Custom Fields, &#8216;mood&#8217; is mentioned. One could fill the Custom Field with his or her mood, and this mood could then somehow be shown on ones post. So lets create a mood.</p>
<p>If you&#8217;ve never used Custom Fields in your blog (and you probably haven&#8217;t, or you would not be reading this article), then the input screen looks like the one above. After filling the input fields, the screen looks like this:</p>
<p><img src="http://www.boosten.org/wp-content/uploads/2009/09/customfields2.png" alt="customfields2.png" border="0" width="648" height="243" /></p>
<p>And after pressing &#8216;Add Custom Field&#8217; like this:</p>
<p><img src="http://www.boosten.org/wp-content/uploads/2009/09/customfields3.png" alt="customfields3.png" border="0" width="647" height="348" /></p>
<p>Now comes cool part number 1: if you press the publish button, the input screen changes somewhat:</p>
<p><img src="http://www.boosten.org/wp-content/uploads/2009/09/customfields4.png" alt="customfields4.png" border="0" width="641" height="343" /></p>
<p>The Custom Field we just created remained the same, however the &#8216;add new custom field&#8217; entry contains a pulldown. If you pull it down, then you will see all Custom Fields created in this WordPress installation, in this case only &#8216;mood&#8217;. WordPress now knows about this Custom Field and it will present the pulldown in all posts and pages you want to create (or modify, of course). If you want to add another Custom Field (other than &#8216;mood&#8217;, for instance &#8216;hair color&#8217; &#8211; my wife changes the color of her hair more often than other people change underwear), then you click the &#8216;enter new&#8217; link. Again after publishing this Custom Field will be available in the pulldown.</p>
<p>If you already published the post you just modified (or created) and preview it on your site, you&#8217;ll see no difference whatsoever. WordPress internally knows about your Custom Field, but doesn&#8217;t know what to do with it.</p>
<p>I will change the Default Theme of WordPress to show the usage, but of course you can embed this in any theme you like. The file I&#8217;ll be changing is single.php, and I&#8217;m going to put the mood just above the meta information.</p>
<p>The part in single.php looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #339933;">&lt;</span>p <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;postmetadata alt&quot;</span><span style="color: #339933;">&gt;...&lt;/</span>p<span style="color: #339933;">&gt;</span></pre></div></div>

<p>and the post I just modified looks like this:</p>
<p><img src="http://www.boosten.org/wp-content/uploads/2009/09/customfields5.png" alt="customfields5.png" border="0" width="468" height="391" /></p>
<p>The first thing to do is to pull the Custom Field from the post. The function for doing this is get_post_meta(). This function will need three parameters: the ID of the post, the name of the Custom Field (in our case &#8216;mood&#8217; &#8211; or &#8216;hair color&#8217; if you&#8217;re my wife) and a boolean value, being <strong>true</strong> of <strong>false</strong>. The last parameter depends on whether get_post_meta() has to read several Custom Fields with the same name (<strong>false</strong>) or should stop at the first it encounters (<strong>true</strong>). Since we have (or want) only one mood (or hair color) this parameter will be <strong>true</strong>.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #339933;">&lt;</span> ?php
  <span style="color: #000088;">$mood</span><span style="color: #339933;">=</span>get_post_meta<span style="color: #009900;">&#40;</span><span style="color: #000088;">$post</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">ID</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'mood'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
<span style="color: #339933;">&lt;</span>p <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;mood&quot;</span><span style="color: #339933;">&gt;&lt;</span> ?php <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Today, I'm feeling &quot;</span> <span style="color: #339933;">.</span><span style="color: #000088;">$mood</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">&lt;/</span>p<span style="color: #339933;">&gt;</span>
&nbsp;
<span style="color: #339933;">&lt;</span>p <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;postmetadata alt&quot;</span><span style="color: #339933;">&gt;...&lt;/</span>p<span style="color: #339933;">&gt;</span></pre></div></div>

<p>What happens here: I&#8217;ve created a variable $mood, which will hold the value for Custom Field &#8216;mood&#8217;, which it will get from the current post ID ($post->ID). It will stop searching for &#8216;mood&#8217;, once it finds the first (true).</p>
<p>Next I echo it to the screen, preceded by &#8220;Today, I&#8217;m feeling &#8220;. The class is for styling, which I will not be doing here.</p>
<p>The post looks now like this:</p>
<p><img src="http://www.boosten.org/wp-content/uploads/2009/09/customfield6.png" alt="customfield6.png" border="0" width="463" height="423" /></p>
<p>I could have used the following construction directly:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>p <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;mood&quot;</span><span style="color: #339933;">&gt;&lt;</span> ?php <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Today, I'm feeling &quot;</span> <span style="color: #339933;">.</span> get_post_meta<span style="color: #009900;">&#40;</span><span style="color: #000088;">$post</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">ID</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'mood'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">&lt;/</span>p<span style="color: #339933;">&gt;</span></pre></div></div>

<p>but then we have a problem with posts that don&#8217;t have a Custom Field &#8216;mood&#8217; configured (which is the case for all other posts I have). Take a look at another post:</p>
<p><img src="http://www.boosten.org/wp-content/uploads/2009/09/customfields7.png" alt="customfields7.png" border="0" width="462" height="410" /></p>
<p>That doesn&#8217;t look very pretty, does it? What we want to do is to create a default value, for the cases we didn&#8217;t define a mood we&#8217;re in.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span> ?php
  <span style="color: #000088;">$mood</span><span style="color: #339933;">=</span>get_post_meta<span style="color: #009900;">&#40;</span><span style="color: #000088;">$post</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">ID</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'mood'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$mood</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$mood</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;unwilling to tell&quot;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
<span style="color: #339933;">&lt;</span>p <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;mood&quot;</span><span style="color: #339933;">&gt;&lt;</span> ?php <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;Today, I'm feeling &quot;</span> <span style="color: #339933;">.</span><span style="color: #000088;">$mood</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">&lt;/</span>p<span style="color: #339933;">&gt;</span></pre></div></div>

<p><img src="http://www.boosten.org/wp-content/uploads/2009/09/customfields8.png" alt="customfields8.png" border="0" width="464" height="410" /></p>
<p>Looks better, doesn&#8217;t it. So now go ahead and give all your posts a &#8216;mood&#8217; Custom Field.</p>
<p>That wasn&#8217;t too hard, now was it?</p>
<h3>Some advanced uses</h3>
<p>Earlier I wrote about the three parameters get_post_meta() takes, the ID of the post, the name of the Custom Field, and either true (for one value) or false (for multiple values). In case of &#8216;false&#8217; the values will be put in an array. </p>
<p>Suppose we wanted a list with people we want to thank for their contribution below every post. This list can consist of zero, one or more people. First we add the Custom Fields to the post:</p>
<p><img src="http://www.boosten.org/wp-content/uploads/2009/09/customfields9.png" alt="customfields9.png" border="0" width="640" height="571" /></p>
<p>And then add the code to single.php, just below the &#8216;mood-code&#8217;.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span> ?php
<span style="color: #000088;">$thanks</span> <span style="color: #339933;">=</span> get_post_meta<span style="color: #009900;">&#40;</span><span style="color: #000088;">$post</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">ID</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'thanks'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$thanks</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&lt;h3&gt;Special thanks to:&lt;/h3&gt;<span style="color: #000099; font-weight: bold;">\n</span>&lt;ul&gt;&quot;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$thanks</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$person</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&lt;li&gt;&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$person</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;&lt;/li&gt;&quot;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&lt;/ul&gt;&quot;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>First we fill the array $thanks with all values (false) we find for &#8216;thanks&#8217; from the current post. If the array contains no data, it&#8217;ll ignore the following part completely, and will not display anything.</p>
<p>If however the array contains some data, then it&#8217;ll display a title called &#8216;Special thanks to:&#8217; and will query the array for every value and create an unordered list of it. This is how it looks in the default theme (of course you can add all kinds of formatting to it, you could present it in a table, or all names after another separated by commas, whatever you like):</p>
<p><img src="http://www.boosten.org/wp-content/uploads/2009/09/customfields10.png" alt="customfields10.png" border="0" width="472" height="209" /></p>
<p>These Custom Fields can really hold any value you like. You could have it hold urls to images, prices for your products, paths to local resources for your products.</p>
<p>Suppose you wanted to create a product page that holds a product you want to sell, and it could contain zero, one or more images.<br />
To display each image, you will need a path for the thumbnail, a path for the full size picture, and a title.</p>
<p>You could decide to create three Custom Fields for each image, but that would be a bit cumbersome, and probably overdone. So we don&#8217;t do that, but create just one Custom Field for each image, and put the values after another, with a separator we choose. In this case we will use the vertical bar (|).</p>
<p>Our &#8216;image&#8217; Custom Field will hold the following value:</p>
<p>product1-thumb.jpg|product1.jpg|Very nice product</p>
<p>The code for this would be:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span> ?php
  <span style="color: #000088;">$images</span> <span style="color: #339933;">=</span> get_post_meta<span style="color: #009900;">&#40;</span><span style="color: #000088;">$post</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">ID</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'image'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$images</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&lt;h3&gt;Pictures&lt;/h3&gt;&quot;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$images</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$image</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
      <span style="color: #000088;">$fullValue</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;|&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$image</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #000088;">$thumbPath</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$fullValue</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$fullsizePath</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$fullValue</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$description</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$fullValue</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #000088;">$fullsizePath</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;/wp-content/media/store/&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$fullsizePath</span><span style="color: #339933;">;</span>
      <span style="color: #000088;">$thumbPath</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;/wp-content/media/store/&quot;</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$thumbPath</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">&quot;&lt;a href='<span style="color: #006699; font-weight: bold;">$fullsizePath</span>' title='<span style="color: #006699; font-weight: bold;">$description</span>'&gt;&lt;img src='<span style="color: #006699; font-weight: bold;">$thumbPath</span>' alt='<span style="color: #006699; font-weight: bold;">$description</span>' class='product-thumb' /&gt;&lt;/a&gt;&quot;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>The explode function extracts the three values (separated by the vertical bar) into an array $fullValue, which then can be used to extract the individual values. The ultimate goal is to display the thumbnail, and to make it clickable to show the full size image. The description (&#8216;Very nice product&#8217;) is used as title for the link and as alternate text for the thumbnail.</p>
<p>That&#8217;s all for now. Happy Custom Field. </p>
<img src="http://feeds.feedburner.com/~r/Boostenorg/~4/1erZbai_hQY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.boosten.org/using-custom-fields-in-wordpress-posts/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>A primer on writing WordPress plugins – part 2</title>
		<link>http://www.boosten.org/a-primer-on-writing-wordpress-plugins-part-2/</link>
		<comments>http://www.boosten.org/a-primer-on-writing-wordpress-plugins-part-2/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 18:23:44 +0000</pubDate>
		<dc:creator>Peter Boosten</dc:creator>
				<category><![CDATA[webpublishing]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.boosten.org/?p=269</guid>
		<description><![CDATA[Although the last article delivered a good working plugin for Wordpress, it seems something was missing. This article will focus on an additional aspect: configurable options.]]></description>
			<content:encoded><![CDATA[<p>In the <a href="http://www.boosten.org/a-primer-on-writing-wordpress-plugins/">previous article</a> I described how easy it is to create a useful plugin.</p>
<p>The result was a plugin, that can be used to display a &#8216;read more&#8217; link on an excerpt, which has none by default.</p>
<p>But something is missing. The plugin shows &#8216;Read More&#8217;, and if the user of this plugin wants it to display something different, he or she has to modify the plugin to let it show &#8216;Blah blah blah&#8217; if wanted. All other plugins have cool menus in the admin panel, with cool forms to make changes to their behavior. That&#8217;s something we can easily add to this plugin (and any plugin you create).</p>
<p>Let&#8217;s start. There are actually four things we want to do:</p>
<ol>
<li>create a menu in the admin panel</li>
<li>create a form to enter our custom text</li>
<li>put that value in the database</li>
<li>extract that value to show on the website</li>
</ol>
<p>The cool part of it all is, is that WordPress takes care of all security aspects, and even internationalization is been taken care of.</p>
<h2>Create a menu in the admin panel</h2>
<p>To create a menu item in the admin menu, we have to call the add_action() function, to add an action to well, a hook. This action registers a function, which will actually call the menu building code.</p>
<p>The actual registration looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">add_action<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'admin_menu'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'my_plugin_menu'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>which registers the my_plugin_menu() function to the admin menu. This my_plugin_menu() function creates the actual menu item:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> my_plugin_menu<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  add_options_page<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'WP Excerpt More Options'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'WP Excerpt More'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">8</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'wp-excerpt-more'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'plugin_options'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>I use the add_options_page() function, because this will add the menu item to &#8216;options&#8217;, where most other plugins create their menu items as well. Other possibilities are: add_posts_page() to add a menu item to the posts menu, add_theme_page() to add to the themes menu, add_pages_page() to add&#8230; you get the picture.</p>
<p>These functions take a few options: &#8216;WP Excerpt More Options&#8217; is the text that is displayed in your browser window (and the tab, if applicable &#8211; the page title), &#8216;WP Excerpt More&#8217; is the text shown in the menu (under options). The &#8217;8&#8242; is the minimum capability a user needs to have to access this menu, in this case &#8216;Administrator&#8217;. I would not suggest anything lower than 8. The fourth parameter needs to be an unique identifier, just go ahead and be unique. The last parameter is the function that we&#8217;re going to use to create the actual form in. for now, just add this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> plugin_options<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'&lt;div class=&quot;wrap&quot;&gt;'</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'&lt;p&gt;This is where the form will be.&lt;/p&gt;'</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'&lt;/div&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>If you append these three snippets to the plugin you hopefully copied from the first article, at the bottom, just before the closing php tag, and you open the options menu in the admin panel, then you&#8217;ll actually see an additional menu option, called &#8216;WP Excerpt More&#8217; (or whatever you typed as second parameter), and if you click that, you&#8217;ll see the text from the last snippet.</p>
<h2>Create a form to enter our custom text and adding the value to the database</h2>
<p>I&#8217;m somewhat combining these two, since it could be very messy if we used different files or functions for the form and the submission of it. This is my plugin_options() function (just replace the above one with this one). It&#8217;s kinda long, so bare with me:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">function plugin_options() {
  // variables for the field and option names
  $opt_name = 'wp_excerpt_more';
  $hidden_field_name = 'wp_excerpt_submit_hidden';
  $data_field_name = 'wp_excerpt_more';
&nbsp;
  // Read in existing option value from database
  $opt_val = get_option( $opt_name );
&nbsp;
  // See if the user has posted us some information
  // If they did, this hidden field will be set to 'Y'
  if( $_POST[ $hidden_field_name ] == 'Y' ) {
  // Read their posted value
    $opt_val = $_POST[ $data_field_name ];
&nbsp;
  // Save the posted value in the database
    update_option( $opt_name, $opt_val );
&nbsp;
  // Put an options updated message on the screen
&nbsp;
?&gt;
&lt;div class=&quot;updated&quot;&gt;&lt;p&gt;&lt;strong&gt;&lt; ?php _e('Options saved.', 'mt_trans_domain' ); ?&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/div&gt;
&lt; ?php
&nbsp;
  }
&nbsp;
  // Now display the options editing screen
&nbsp;
  echo '&lt;div class=&quot;wrap&quot;&gt;';
&nbsp;
  // header
&nbsp;
  echo &quot;&lt;h2&gt;&quot; . __( 'Menu WP Excerpt More Plugin Options', 'mt_trans_domain' ) . &quot;&lt;/h2&gt;&quot;;
&nbsp;
  // options form
&nbsp;
?&gt;
&nbsp;
&lt;form name=&quot;form1&quot; method=&quot;post&quot; action=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> esc_url<span style="color: #009900;">&#40;</span><span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'%7E'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'~'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'REQUEST_URI'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;
  &lt;input type=&quot;hidden&quot; name=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$hidden_field_name</span><span style="color: #339933;">;</span> ?<span style="color: #339933;">/&gt;</span><span style="color: #0000ff;">&quot; value=&quot;</span>Y<span style="color: #0000ff;">&quot;&gt;
&nbsp;
  &lt;p&gt;&lt; ?php _e(&quot;</span>Read More String to Display<span style="color: #339933;">:</span><span style="color: #0000ff;">&quot;, 'mt_trans_domain' ); ?&gt;
  &lt;input type=&quot;</span>text<span style="color: #0000ff;">&quot; name=&quot;</span><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$data_field_name</span><span style="color: #339933;">;</span> ?<span style="color: #339933;">/&gt;</span><span style="color: #0000ff;">&quot; value=&quot;</span><span style="color: #339933;">&lt;</span> ?php <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$opt_val</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot; size=&quot;50&quot;&gt;
  &lt;/p&gt;&lt;hr /&gt;
&nbsp;
  &lt;p class=&quot;submit&quot;&gt;
  &lt;input type=&quot;submit&quot; name=&quot;Submit&quot; value=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> _e<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Update Options'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'mt_trans_domain'</span> <span style="color: #009900;">&#41;</span> ?<span style="color: #339933;">/&gt;</span><span style="color: #0000ff;">&quot; /&gt;
  &lt;/p&gt;
&lt;/form&gt;
&nbsp;
&nbsp;
&lt; ?php
&nbsp;
}</span></pre></div></div>

<p>The opt_name variable holds the option name that actually will be in the wp_options table in the database.  I chose wp_excerpt_more, since that somewhat resembles the name of the plugin. Also in this case you need to be unique, what you don&#8217;t want is overwrite some existing (and possibly important) settings. The other two variables are for the form, the hidden_field_name to verify whether submit has been pressed or not, the last one to hold the text typed into the form. In this case we only need one text file (the text that will be displayed in the &#8216;read more&#8217; link).</p>
</pre>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">  <span style="color: #666666; font-style: italic;">// Read in existing option value from database</span>
  <span style="color: #000088;">$opt_val</span> <span style="color: #339933;">=</span> get_option<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$opt_name</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>WordPress delivers us some functions to retrieve option values from, and put option values into the wp_options table, without us actually having to know what this table is called. The get_option() function is the one that retrieves the value. It takes one parameter: the option it's supposed to get the value for. In our case that's the value for 'wp_excerpt_more', if it has one.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">  <span style="color: #666666; font-style: italic;">// See if the user has posted us some information</span>
  <span style="color: #666666; font-style: italic;">// If they did, this hidden field will be set to 'Y'</span>
  <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span> <span style="color: #000088;">$hidden_field_name</span> <span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">'Y'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #666666; font-style: italic;">// Read their posted value</span>
    <span style="color: #000088;">$opt_val</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_POST</span><span style="color: #009900;">&#91;</span> <span style="color: #000088;">$data_field_name</span> <span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Save the posted value in the database</span>
    update_option<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$opt_name</span><span style="color: #339933;">,</span> <span style="color: #000088;">$opt_val</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Put an options updated message on the screen</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span>
<span style="color: #339933;">&lt;</span>div <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;updated&quot;</span><span style="color: #339933;">&gt;&lt;</span>p<span style="color: #339933;">&gt;&lt;</span>strong<span style="color: #339933;">&gt;&lt;</span> ?php _e<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Options saved.'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'mt_trans_domain'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span><span style="color: #339933;">&lt;/</span>strong<span style="color: #339933;">&gt;&lt;/</span>p<span style="color: #339933;">&gt;&lt;/</span>div<span style="color: #339933;">&gt;</span></pre></div></div>

<p>This part checks whether the submit button has been pressed, and if it has, it'll put the text, typed into the form, into the database with the update_option() function. This function needs two parameters: the option the value belongs to, and the actual value. The '_e' function could be replaced by an echo, however this function is internationalization aware (leave the 'mt_trans_domain' for granted).</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&lt; ?php
&nbsp;
  }
&nbsp;
  // Now display the options editing screen
&nbsp;
  echo '&lt;div class=&quot;wrap&quot;&gt;';
&nbsp;
  // header
&nbsp;
  echo &quot;&lt;h2&gt;&quot; . __( 'Menu WP Excerpt More Plugin Options', 'mt_trans_domain' ) . &quot;&lt;/h2&gt;&quot;;
&nbsp;
  // options form
&nbsp;
?&gt;
&nbsp;
&lt;form name=&quot;form1&quot; method=&quot;post&quot; action=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> esc_url<span style="color: #009900;">&#40;</span><span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'%7E'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'~'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'REQUEST_URI'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;
  &lt;input type=&quot;hidden&quot; name=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$hidden_field_name</span><span style="color: #339933;">;</span> ?<span style="color: #339933;">/&gt;</span><span style="color: #0000ff;">&quot; value=&quot;</span>Y<span style="color: #0000ff;">&quot;&gt;
&nbsp;
  &lt;p&gt;&lt; ?php _e(&quot;</span>Read More String to Display<span style="color: #339933;">:</span><span style="color: #0000ff;">&quot;, 'mt_trans_domain' ); ?&gt;
  &lt;input type=&quot;</span>text<span style="color: #0000ff;">&quot; name=&quot;</span><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$data_field_name</span><span style="color: #339933;">;</span> ?<span style="color: #339933;">/&gt;</span><span style="color: #0000ff;">&quot; value=&quot;</span><span style="color: #339933;">&lt;</span> ?php <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$opt_val</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot; size=&quot;50&quot;&gt;
  &lt;/p&gt;&lt;hr /&gt;
&nbsp;
  &lt;p class=&quot;submit&quot;&gt;
  &lt;input type=&quot;submit&quot; name=&quot;Submit&quot; value=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> _e<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Update Options'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'mt_trans_domain'</span> <span style="color: #009900;">&#41;</span> ?<span style="color: #339933;">/&gt;</span><span style="color: #0000ff;">&quot; /&gt;
  &lt;/p&gt;
&lt;/form&gt;
&nbsp;
&nbsp;
&lt; ?php
&nbsp;
}</span></pre></div></div>

<p>This snippet displays the actual form. The div class="wrap" is needed to display the form in the correct admin panel layout, I haven't tried to change that (or leave it out all together). The rest is fairly simple: create a form, that calls itself after submission (that's where we needed the hidden submit field for), read some data (input type="text"), and submit it.</p>
<p>All the above code (which isn't that much) is needed to create a option menu, create a form, and put the option into the database. You can use this part already, however it will not change the text in the web page (the 'Read more' part).</p>
<h2>Extract the option value to show on the website</h2>
<p>Remember this part from the previous article:</p>
</pre>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> WPReadMore_Link<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$post</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// get the URL to the post</span>
  <span style="color: #000088;">$link</span><span style="color: #339933;">=</span>get_permalink<span style="color: #009900;">&#40;</span><span style="color: #000088;">$post</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">ID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// get the post title</span>
  <span style="color: #000088;">$title</span><span style="color: #339933;">=</span><span style="color: #000088;">$post</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">post_title</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// create a Read More and return it</span>
  <span style="color: #b1b100;">return</span> ‘<span style="color: #339933;">&lt;</span>a <span style="color: #000000; font-weight: bold;">class</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;myreadmorelink&quot;</span> href<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;’.<span style="color: #006699; font-weight: bold;">$link</span>. ‘&quot;</span> title<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;’.<span style="color: #006699; font-weight: bold;">$title</span>.‘&quot;</span><span style="color: #339933;">&gt;</span>Read more<span style="color: #339933;">&lt;/</span>a<span style="color: #339933;">&gt;</span>’<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>So we change that into this:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> WPReadMore_Link<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$post</span><span style="color: #339933;">;</span>
  <span style="color: #000088;">$opt_name</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'wp_excerpt_more'</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Read in existing option value from database</span>
  <span style="color: #000088;">$opt_val</span> <span style="color: #339933;">=</span> get_option<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$opt_name</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$opt_val</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #009900;">&#41;</span> 
    <span style="color: #000088;">$opt_val</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;Read more&quot;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
  <span style="color: #666666; font-style: italic;">// get the URL to the post</span>
  <span style="color: #000088;">$link</span><span style="color: #339933;">=</span>get_permalink<span style="color: #009900;">&#40;</span><span style="color: #000088;">$post</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">ID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// get the post title</span>
  <span style="color: #000088;">$title</span><span style="color: #339933;">=</span><span style="color: #000088;">$post</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">post_title</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// create a Read More and return it</span>
  <span style="color: #b1b100;">return</span> <span style="color: #0000ff;">'&lt;div class=&quot;wpexcerptmore&quot;&gt;&lt;a href=&quot;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$link</span><span style="color: #339933;">.</span> <span style="color: #0000ff;">'&quot; title=&quot;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$title</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&quot;&gt;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$opt_val</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&lt;/a&gt;&lt;/div&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The first part is reading the options database:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">  <span style="color: #000088;">$opt_name</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'wp_excerpt_more'</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #666666; font-style: italic;">// Read in existing option value from database</span>
  <span style="color: #000088;">$opt_val</span> <span style="color: #339933;">=</span> get_option<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$opt_name</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$opt_val</span> <span style="color: #339933;">==</span> <span style="color: #0000ff;">&quot;&quot;</span><span style="color: #009900;">&#41;</span> 
    <span style="color: #000088;">$opt_val</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;Read more&quot;</span><span style="color: #339933;">;</span></pre></div></div>

<p>We put, if found in the database, the value for option 'wp_excerpt_more' into the variable $opt_val, and if it's empty (which it is when the plugin is first installed) give it the value 'Read more'. So $opt_val will always have a value, which can be used in the actual display on the web page.</p>
<p>Here's where we use it:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">  <span style="color: #b1b100;">return</span> <span style="color: #0000ff;">'&lt;div class=&quot;wpexcerptmore&quot;&gt;&lt;a href=&quot;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$link</span><span style="color: #339933;">.</span> <span style="color: #0000ff;">'&quot; title=&quot;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$title</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&quot;&gt;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$opt_val</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&lt;/a&gt;&lt;/div&gt;'</span><span style="color: #339933;">;</span></pre></div></div>

<h2>Conclusion</h2>
<p>It could be that I lost you somewhere during this discussion, so here's the complete plugin:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;">&lt; ?php
/*
Plugin Name: WP Excerpt More
Version: 0.7
Description: Automatically adds Read More link to your excerpts.
Author: Peter Boosten
Author URI: http://www.boosten.org
Plugin URL: http://www.boosten.org
*/
&nbsp;
&nbsp;
/* Version check */
global $wp_version;
&nbsp;
$exit_msg='WP Excerpt More requires Wordpress 2.6 or newer.
&lt;a href=&quot;http://codex.wordpress.org/Upgrading_WordpPress&quot;&gt;Please update!';
&nbsp;
if (version_compare($wp_version,&quot;2.6&quot;,&quot;&lt; &quot;))
{
  exit ($exit_msg);
}
&nbsp;
/* Show a Read More link */
&nbsp;
function WPReadMore_Link()
{
  global $post;
  $opt_name = 'wp_excerpt_more';
&nbsp;
  // Read in existing option value from database
  $opt_val = get_option( $opt_name );
  if ($opt_val == &quot;&quot;)
      $opt_val = &quot;Read more&quot;;
&nbsp;
  // get the URL to the post
  $link=get_permalink($post-&gt;ID);
&nbsp;
  // get the post title
  $title=$post-&gt;post_title;
&nbsp;
  // create a Read More and return it
  return '&lt;div class=&quot;wpexcerptmore&quot;&gt;&lt;a href=&quot;'.$link. '&quot; title=&quot;'.$title.'&quot;&gt;'.$opt_val.'&lt;/a&gt;&lt;/div&gt;';
}
&nbsp;
/* Add Read more to the end of the excerpt */
&nbsp;
function WPReadMore_ContentFilter($excerpt)
{
  return $excerpt.WPReadMore_Link();
}
&nbsp;
add_filter('the_excerpt','WPReadMore_ContentFilter');
&nbsp;
/* Vanaf hier is toegevoegd voor options */
&nbsp;
add_action('admin_menu', 'my_plugin_menu');
&nbsp;
function my_plugin_menu() {
//  add_options_page('My Plugin Options', 'My Plugin', 8, 'your-unique-identifier', 'my_plugin_options');
  add_options_page('WP Excerpt More Options', 'WP Excerpt More', 8, 'wp-excerpt-more', 'plugin_options');
}
&nbsp;
function plugin_options() {
  // variables for the field and option names
  $opt_name = 'wp_excerpt_more';
  $hidden_field_name = 'wp_excerpt_submit_hidden';
  $data_field_name = 'wp_excerpt_more';
&nbsp;
  // Read in existing option value from database
  $opt_val = get_option( $opt_name );
&nbsp;
  // See if the user has posted us some information
  // If they did, this hidden field will be set to 'Y'
  if( $_POST[ $hidden_field_name ] == 'Y' ) {
  // Read their posted value
    $opt_val = $_POST[ $data_field_name ];
&nbsp;
  // Save the posted value in the database
    update_option( $opt_name, $opt_val );
&nbsp;
  // Put an options updated message on the screen
&nbsp;
?&gt;
&lt;div class=&quot;updated&quot;&gt;&lt;p&gt;&lt;strong&gt;&lt; ?php _e('Options saved.', 'mt_trans_domain' ); ?&gt;&lt;/strong&gt;&lt;/p&gt;&lt;/div&gt;
&lt; ?php
&nbsp;
  }
&nbsp;
  // Now display the options editing screen
&nbsp;
  echo '&lt;div class=&quot;wrap&quot;&gt;';
&nbsp;
  // header
&nbsp;
  echo &quot;&lt;h2&gt;&quot; . __( 'Menu WP Excerpt More Plugin Options', 'mt_trans_domain' ) . &quot;&lt;/h2&gt;&quot;;
&nbsp;
  // options form
&nbsp;
?&gt;
&nbsp;
&lt;form name=&quot;form1&quot; method=&quot;post&quot; action=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> esc_url<span style="color: #009900;">&#40;</span><span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'%7E'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'~'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'REQUEST_URI'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;
  &lt;input type=&quot;hidden&quot; name=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$hidden_field_name</span><span style="color: #339933;">;</span> ?<span style="color: #339933;">/&gt;</span><span style="color: #0000ff;">&quot; value=&quot;</span>Y<span style="color: #0000ff;">&quot;&gt;
&nbsp;
  &lt;p&gt;&lt; ?php _e(&quot;</span>Read More String to Display<span style="color: #339933;">:</span><span style="color: #0000ff;">&quot;, 'mt_trans_domain' ); ?&gt;
  &lt;input type=&quot;</span>text<span style="color: #0000ff;">&quot; name=&quot;</span><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$data_field_name</span><span style="color: #339933;">;</span> ?<span style="color: #339933;">/&gt;</span><span style="color: #0000ff;">&quot; value=&quot;</span><span style="color: #339933;">&lt;</span> ?php <span style="color: #b1b100;">echo</span> <span style="color: #000088;">$opt_val</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot; size=&quot;50&quot;&gt;
  &lt;/p&gt;&lt;hr /&gt;
&nbsp;
  &lt;p class=&quot;submit&quot;&gt;
  &lt;input type=&quot;submit&quot; name=&quot;Submit&quot; value=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> _e<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Update Options'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'mt_trans_domain'</span> <span style="color: #009900;">&#41;</span> ?<span style="color: #339933;">/&gt;</span><span style="color: #0000ff;">&quot; /&gt;
  &lt;/p&gt;
&nbsp;
&lt;/form&gt;
&nbsp;
&nbsp;
&lt; ?php
&nbsp;
}
&nbsp;
&nbsp;
?&gt;</span></pre></div></div>

<p>And if you really don't have time to type it all, here's the link to the complete plugin: <a href="http://devnull.boosten.org/plugins/wp-excerpt-more.zip">http://devnull.boosten.org/plugins/wp-excerpt-more.zip</a></p>
<p>That's all for now.</p>
<img src="http://feeds.feedburner.com/~r/Boostenorg/~4/g1WEKGs1DQg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.boosten.org/a-primer-on-writing-wordpress-plugins-part-2/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>A primer on writing WordPress plugins</title>
		<link>http://www.boosten.org/a-primer-on-writing-wordpress-plugins/</link>
		<comments>http://www.boosten.org/a-primer-on-writing-wordpress-plugins/#comments</comments>
		<pubDate>Wed, 02 Sep 2009 19:12:58 +0000</pubDate>
		<dc:creator>Peter Boosten</dc:creator>
				<category><![CDATA[webpublishing]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.boosten.org/?p=234</guid>
		<description><![CDATA[Ever needed some functionality in WordPress that is not included by default, or is not provided by one of the gazillion plugins written by others? Then it's time you start writing your own plugins. ]]></description>
			<content:encoded><![CDATA[<p><a href="http://wordpress.org">WordPress</a> is a great (well, in my opinion the greatest) weblog software ever, although it can even be used as a content management system (CMS). It&#8217;s vast community of users provided lots of themes and extensions to the software, and WordPress itself is being improved all the time, be it functionality or bug-fixes.</p>
<p>Suppose you wanted it to extent yourself, say by writing a plugin, how would you go about? Let me tell you.</p>
<p>First of all, plugins are kept in a specific place in the WordPress directory structure, namely in webroot/wp-content/plugins. More complex plugins are consolidated in subdirectories, but simple ones, like we&#8217;re going to write here, can be put in the plugins directory itself.</p>
<p>Let&#8217;s start simple and create a plugin that does absolutely nothing, but still is considered a plugin.</p>
<p>The plugin I eventually describe here will provide a &#8216;read more&#8217; link for excerpts, since they don&#8217;t have that by default.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span> ?php
<span style="color: #666666; font-style: italic;">/*
Plugin Name: WP Excerpt More
Version: 0.1
Description: This plugin adds a Read More link to your excerpts.
Author: Peter Boosten
Author URI: http://www.boosten.org
Plugin URL: http://www.boosten.org
*/</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>Save this to a file called myfirstplugin.php (or any other name you desire) and put it into the plugin directory. If you switch to the admin dashboard of your WordPress and choose plugins from the sidebar, you&#8217;ll actually see the plugin, although deactivated, together with all information you filled in above (Well, you&#8217;ll see my name if you copied the exact information above). You can even activate the plugin.</p>
<p>Let&#8217;s enhance it a bit. Suppose you wanted the plugin to check the version of WordPress it minimal needs (remember I wrote that WordPress gets improved constantly, and some functionality isn&#8217;t available in older versions), then all you have to do is to add the following bit of code:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span> ?php
<span style="color: #666666; font-style: italic;">/*
Plugin Name: WP Excerpt More
Version: 0.2
Description: This plugin adds a Read More link to your excerpts.
Author: Peter Boosten
Author URI: http://www.boosten.org
Plugin URL: http://www.boosten.org
*/</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/* Version check */</span>
<span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$wp_version</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$exit_msg</span><span style="color: #339933;">=</span><span style="color: #0000ff;">'WP Excerpt More requires Wordpress 2.6 or newer. Please update!'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">version_compare</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$wp_version</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;2.6&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;&lt;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #990000;">exit</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$exit_msg</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>WordPress provides us with all kind of useful information, like the version of the software you&#8217;re currently running. This version is communicated through a variable called $wp_version. Just compare that to the version you think minimal is required (2.6 in the above example) and tell the plugin to exit if this doesn&#8217;t meet your requirements. The admin panel will respond with the message you defined in $exit_msg, and the plugin cannot be activated. You can try that yourself if you raise your requirement to a version higher than the current version you&#8217;re running.</p>
<p>Oke, now for the real stuff. Our aim in the plugin was to add a read more link for excerpt, so lets create one.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span> ?php
<span style="color: #666666; font-style: italic;">/*
Plugin Name: WP Excerpt More
Version: 0.3
Description: This plugin adds a Read More link to your excerpts.
Author: Peter Boosten
Author URI: http://www.boosten.org
Plugin URL: http://www.boosten.org
*/</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/* Version check */</span>
<span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$wp_version</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$exit_msg</span><span style="color: #339933;">=</span><span style="color: #0000ff;">'WP Excerpt More requires Wordpress 2.6 or newer. Please update!'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">version_compare</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$wp_version</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;2.6&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;&lt;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #990000;">exit</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$exit_msg</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> WPReadMore_Link<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$post</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// get the URL to the post</span>
	<span style="color: #000088;">$link</span><span style="color: #339933;">=</span>get_permalink<span style="color: #009900;">&#40;</span><span style="color: #000088;">$post</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">ID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// get the post title</span>
	<span style="color: #000088;">$title</span><span style="color: #339933;">=</span><span style="color: #000088;">$post</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">post_title</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// create a Read More and return it</span>
	<span style="color: #b1b100;">return</span> <span style="color: #0000ff;">'&amp;lt;a href=&quot;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$link</span><span style="color: #339933;">.</span> <span style="color: #0000ff;">'&quot; title=&quot;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$title</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&quot;&amp;gt;Read more&amp;lt;/a&amp;gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>That&#8217;s it. You&#8217;ve created a fully functional, and mostly useful plugin. I tell you below how to use it, but let&#8217;s focus on the content of the plugin.</p>
<p>We&#8217;ve created a function called WPReadMore_Link, which needs no parameters to run. It gets however (again) valuable information from WordPress, namely an array called $post. This array is only available in combination with a post, so you&#8217;ll have to use the function defined in this plugin in <a href="http://codex.wordpress.org/The_Loop">the Loop</a>. There are two things we want from that array, the permalink and the title of the post (the latter is not really needed, but it looks kinda cute).</p>
<p>This information is returned to WordPress, disguised as an anchor link, surrounding a text called &#8216;Read more&#8217;.</p>
<p>How would you make this link available in the loop?<br />
Simply locate the place where &#8216;the_excerpt();&#8217; is in the code, and just below it, write &#8216;WPReadMore_Link();&#8217;.</p>
<p>Now you&#8217;ll have a read more link below your excerpt. But wait, what if you would disable (or remove) the plugin again. You&#8217;ll be left with an error message of a not found function. You could do the following:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span> ?php <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">function_exists</span><span style="color: #009900;">&#40;</span>WPReadMore_Link<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">echo</span> WPReadMore_Link<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>instead of just &#8216;WPReadMore_Link();&#8217;.</p>
<p>No rocket science needed here: if the plugin is activated, then the function will exist and will be called whenever the code is parsed, otherwise it won&#8217;t.</p>
<p>In an ideal world, you don&#8217;t want to edit your theme to add this link, but you want the plugin to manage that for itself. For this purpose the kind guys (and gals of course) left us so called plugin hooks, through which we can extend the functionality of existing functions, or alter them altogether. For now we just want to add something, namely add a read more link at the end of the excerpt.</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span> ?php
<span style="color: #666666; font-style: italic;">/*
Plugin Name: WP Excerpt More
Version: 0.4
Description: This plugin adds a Read More link to your excerpts.
Author: Peter Boosten
Author URI: http://www.boosten.org
Plugin URL: http://www.boosten.org
*/</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/* Version check */</span>
<span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$wp_version</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$exit_msg</span><span style="color: #339933;">=</span><span style="color: #0000ff;">'WP Excerpt More requires Wordpress 2.6 or newer. Please update!'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">version_compare</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$wp_version</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;2.6&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;&lt;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #990000;">exit</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$exit_msg</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> WPReadMore_Link<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$post</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// get the URL to the post</span>
	<span style="color: #000088;">$link</span><span style="color: #339933;">=</span>get_permalink<span style="color: #009900;">&#40;</span><span style="color: #000088;">$post</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">ID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// get the post title</span>
	<span style="color: #000088;">$title</span><span style="color: #339933;">=</span><span style="color: #000088;">$post</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">post_title</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// create a Read More and return it</span>
	<span style="color: #b1b100;">return</span> <span style="color: #0000ff;">'&amp;lt;a href=&quot;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$link</span><span style="color: #339933;">.</span> <span style="color: #0000ff;">'&quot; title=&quot;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$title</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&quot;&amp;gt;Read more&amp;lt;/a&amp;gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/* Add Read more to the end of the excerpt */</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> WPReadMore_ContentFilter<span style="color: #009900;">&#40;</span><span style="color: #000088;">$excerpt</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$excerpt</span><span style="color: #339933;">.</span>WPReadMore_Link<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
add_filter<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'the_excerpt'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'WPReadMore_ContentFilter'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>That&#8217;s it. If you remove the function call from the theme, and use the above code, you&#8217;ll still presented with a read more link. How does it work?</p>
<p>We&#8217;ve created a function called WPReadMore_ContentFilter($excerpt), which takes the excerpt text as parameter, and returns the same text, concatenated with whatever is returned by the WPReadMore_Link() function, in this case the read more link. You could reorder the output of this function, and have the read more link before the excerpt (which looks kinda odd, but hey, it&#8217;s your birthday party) by writing this return: return WPReadMore_Link().$excerpt;</p>
<p>The &#8216;add_filter&#8217; function is the most important function: it hooks the WPReadMore_ContentFilter function into the the_excerpt function, so every time the_excerpt() is executed, our function is executed as well. </p>
<p>Just one thing to do, I guess:</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span> ?php
<span style="color: #666666; font-style: italic;">/*
Plugin Name: WP Excerpt More
Version: 0.5
Description: This plugin adds a Read More link to your excerpts.
Author: Peter Boosten
Author URI: http://www.boosten.org
Plugin URL: http://www.boosten.org
*/</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/* Version check */</span>
<span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$wp_version</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$exit_msg</span><span style="color: #339933;">=</span><span style="color: #0000ff;">'WP Excerpt More requires Wordpress 2.6 or newer. Please update!'</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #990000;">version_compare</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$wp_version</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;2.6&quot;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;&lt;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #990000;">exit</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$exit_msg</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> WPReadMore_Link<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$post</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// get the URL to the post</span>
	<span style="color: #000088;">$link</span><span style="color: #339933;">=</span>get_permalink<span style="color: #009900;">&#40;</span><span style="color: #000088;">$post</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">ID</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// get the post title</span>
	<span style="color: #000088;">$title</span><span style="color: #339933;">=</span><span style="color: #000088;">$post</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">post_title</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// create a Read More and return it</span>
	<span style="color: #b1b100;">return</span> <span style="color: #0000ff;">'&amp;lt;a class=&quot;myreadmorelink&quot; href=&quot;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$link</span><span style="color: #339933;">.</span> <span style="color: #0000ff;">'&quot; title=&quot;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$title</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&quot;&amp;gt;Read more&amp;lt;/a&amp;gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/* Add Read more to the end of the excerpt */</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> WPReadMore_ContentFilter<span style="color: #009900;">&#40;</span><span style="color: #000088;">$excerpt</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$excerpt</span><span style="color: #339933;">.</span>WPReadMore_Link<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
add_filter<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'the_excerpt'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'WPReadMore_ContentFilter'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>The only thing I added was a class to the anchor link, since you want to have some styling possibilities afterwards, but you could also embed the anchor link in divs, if you wanted to.</p>
<p>That&#8217;s it folks, enjoy.</p>
<img src="http://feeds.feedburner.com/~r/Boostenorg/~4/GY643hxwuq4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.boosten.org/a-primer-on-writing-wordpress-plugins/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Creating my own LDAP Directory – part 3</title>
		<link>http://www.boosten.org/creating-my-own-ldap-directory-part-3/</link>
		<comments>http://www.boosten.org/creating-my-own-ldap-directory-part-3/#comments</comments>
		<pubDate>Thu, 23 Jul 2009 10:00:35 +0000</pubDate>
		<dc:creator>Peter Boosten</dc:creator>
				<category><![CDATA[freebsd]]></category>
		<category><![CDATA[LDAP]]></category>
		<category><![CDATA[PAM]]></category>

		<guid isPermaLink="false">http://www.boosten.org/?p=128</guid>
		<description><![CDATA[In this third part of my LDAP tutorial I'm describing how Unix could benefit from an LDAP directory by centralizing user- and group administration.]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>It has been a while since I wrote the <a href="http://www.boosten.org/creating-my-own-ldap-directory-part-2/">part two</a>, mainly because of other priorities.</p>
<p>Let&#8217;s see what we got so far (remember the brainstorm from <a href="http://www.boosten.org/creating-my-own-ldap-directory-part-1/">part one</a>):</p>
<p><img src="http://www.boosten.org/wp-content/uploads/2009/07/accomplishments-1.png" alt="accomplishments-1" title="accomplishments-1" width="472" height="342" class="alignnone size-full wp-image-131" /></p>
<p>In <a href="http://www.boosten.org/creating-my-own-ldap-directory-part-1/">part one</a> I created got LDAP running, created a directory and found some use for it as global address book, in <a href="http://www.boosten.org/creating-my-own-ldap-directory-part-2/">part two</a> the apache configuration was done. So those are finished.</p>
<p>Although we got a working directory, it&#8217;s not finished yet: it&#8217;ll grow (more element will be created, and existing elements will get additional elements).</p>
<p>Now I&#8217;m going to focus on the FreeBSD part (actually this will be working on all kind of Unices, but I&#8217;ve only tested in on FreeBSD).</p>
<p>Suppose you have several users and several FreeBSD machines. In the traditional way, if you want all users to log on to all machines, you have to create all user accounts on all machines. If you have only few machines, like I do it can be managed, but one of the major drawbacks is that you actually have as much user databases as you have machines. Users themselves are then responsible for synchronizing passwords between the different machines (assuming users always want one username/password for logging in anywhere).</p>
<p>If you have strong password policies (like maximum lifetime of a password), and users do logon to other machines exceptionally, then those passwords will definitely get out of sync.</p>
<p>Here&#8217;s where LDAP can help: have FreeBSD authenticate users against a central directory, and all your (and your users&#8217;) problems will be over. There will be no need for creating users on the machines itself, and the nice thing is: you can still have control over what machines users are allowed to log in.</p>
<p>It&#8217;s even possible to create a home directory for that user on first login, I&#8217;ll describing that below. What I will not yet describe (maybe in a later article) is mounting a remote home directory automatically during login.</p>
<h2>Preparing FreeBSD</h2>
<p>Configuring LDAP logins on FreeBSD is not that hard, because the main facility for this is already in place: PAM, or Pluggable Authentication Service. Whenever an application can use PAM (and lots of applications can), then with all kind of plugins you can do all kind of cool stuff. For instance, one of the default PAM modules (at least, in FreeBSD 7.2) is pam_passwdqc.so (all standard PAM modules are stored in /usr/lib) facilitates a configurable, although simple, password policy, like minimum allowed password lengths. Other PAM modules are available from the ports collection.</p>
<p>We are going to need three of them: pam_ldap, pam_mkhomedir and nss_ldap. The latter is no PAM module, but is needed for being able to authenticate. The application I&#8217;m going to focus on is login, but it can also be applied to ssh, ftp, telnet and other services.</p>
<p>pam_ldap and nss_ldap depend on the cyrus-sasl and openldap-sasl-client, so these will be installed also if you had not already. In my case I installed the openldap-client, without the sasl-part, so installation failed. I had to reinstall the openldap-client. I used portupgrade for that: </p>
<p><code>portupgrade -fo /net/openldap24-sasl-client net/openldap24-client</code></p>
<p>pam_mkhomedir doesn&#8217;t need any configuring, but the other two will. We are going to create one config file in /usr/local/etc, called ldap.conf, and create a link to another file in the same directory, called nss_ldap.conf</p>
<p>The easiest way to get started is to copy the ldap.conf.dist to ldap.conf (as root, of course)</p>
<p><code><br />
cd /usr/local/etc<br />
cp ldap.conf.dist ldap.conf<br />
ln -s ldap.conf nss_ldap.conf<br />
</code></p>
<p>My ldap.conf looks like this (I&#8217;ve removed all the commented entries, since they&#8217;re not relevant, or not changed from the default):</p>
<p><code><br />
host ldap.boosten.org<br />
base dc=boosten,dc=org<br />
uri ldap://192.168.13.15/<br />
scope sub<br />
</code><br />
<code><br />
pam_filter objectclass=posixAccount<br />
pam_login_attribute uid<br />
</code><br />
<code><br />
pam_min_uid 1000<br />
pam_max_uid 5000<br />
</code><br />
<code><br />
nss_base_passwd        ou=people,dc=boosten,dc=org?one<br />
nss_base_group          ou=groups,dc=boosten,dc=org?one<br />
</code></p>
<p>From the top:<br />
<code><br />
host ldap.boosten.org<br />
base dc=boosten,dc=org<br />
uri ldap://ldap.boosten.org/<br />
scope sub<br />
</code></p>
<p>In this part I define where pam_ldap and nss_ldap can find the LDAP server by defining host and/or uri (I think that one of them actually is enough, and I cannot recall why I ended up with the two of them, but it doesn&#8217;s hurt either), and where the search for users should start. I chose the top of the directory as starting point, and defined the scope to by &#8216;sub&#8217;, which means &#8216;look in sub containers as well&#8217;.</p>
<p><code><br />
pam_filter objectclass=posixAccount<br />
pam_login_attribute uid<br />
</code></p>
<p>These two are to be remembered: whenever a user logs in to the host, pam_ldap will compare the login name to the attribute uid, defined in LDAP, but it will only look for that uid in elements defined as objectClass posixAccount. It&#8217;ll search for other things as well, I&#8217;ll come to that later.</p>
<p><code><br />
pam_min_uid 1000<br />
pam_max_uid 5000<br />
</code></p>
<p>change these parameters as you like: they describe the minimum and maximum user id (called uid, which is rather confusing, because we also defined uid as login name).</p>
<p>Let me clarify: in Unix, you&#8217;re nothing but a number. Yes, it&#8217;s really true. All permissions on files are assigned to numbers, and it are the smart tools that map those numbers, actually called uid&#8217;s to real names: login names. Since LDAP wasn&#8217;t designed solely for Unix, the designers didn&#8217;t follow Unix naming conventions.<br />
So what&#8217;s called a login name in Unix, is an uid in LDAP and the uid in Unix is the uidNumber in LDAP.</p>
<p>Back to those parameters: they let you define what the minimum and maximum uid(Number) is, that can login to that host, using LDAP authentication. I guess it&#8217;s one way of preventing someone logging into the host using a service account, or root (uid 0) when that person somehow got access to the LDAP server and modified stuff.</p>
<p><code><br />
nss_base_passwd        ou=people,dc=boosten,dc=org?one<br />
nss_base_group          ou=groups,dc=boosten,dc=org?one<br />
</code></p>
<p>These parameters tell nss where to look for groups and passwords. The &#8220;?one&#8221; defines whether nss should look in sub containers or not. Since I don&#8217;t have sub containers underneath ou=people or ou=groups, I use &#8220;?one&#8221;, otherwise use &#8220;?sub&#8221;.</p>
<p>The next thing to edit is the /etc/nsswitch.conf. From the man page for that file:</p>
<p><em>The configuration file controls how a process looks up various databases containing information regarding hosts, users (passwords), groups, etc.</em></p>
<p>I changed two entries (for now, but maybe more in future):<br />
<code><br />
group: ldap files<br />
passwd: ldap files<br />
</code></p>
<p>Roughly, the entries mean something like: &#8220;Dear system: look for information on groups or users in the LDAP directory (as configured in the nss_ldap.conf file described earlier), and if you cannot find it in LDAP, look in the traditional files&#8221; (which are /etc/passwd and /etc/group in this case). </p>
<p>The order in the file describes the order of looking: look first in LDAP and then in local files. You could do it the other way around, if you like, but that&#8217;s up to you. </p>
<p>The last file to change is the PAM configuration. These configuration files are located in /etc/pam.d/, and that&#8217;s where we go. my directory looks like this:<br />
<code><br />
README	cron	ftpd	imap	login	passwd	rsh	su	telnetd<br />
atrun	ftp	gdm	kde	other	pop3	sshd	system	xdm<br />
</code></p>
<p>Services installed from ports (like sudo) will put their PAM configuration files in /usr/local/etc/pam.d/.</p>
<p>Like mentioned earlier, for this tutorial I&#8217;m going to change the login service only, so logging in on the console. If you want to apply this to sshd for instance, it&#8217;ll also work, however you have to make sure that your sshd uses PAM for authentication (/etc/ssh/sshd_config). Mine doesn&#8217;t!</p>
<p>First a small PAM course. a PAM configuration file for a service consists of four module types (max): auth, account, session and password.</p>
<p>An auth module prompts for a password to authenticate that the user is who they say they are, and will set any credentials.<br />
An account module handles the authorization (not authentication), based on time, resources etc. If a restriction has been defined for a user in LDAP, like whether he&#8217;s allowed to login to a specific host or not, whis module type will handle this.<br />
A session module is responsible for the housekeeping tasks before and/or after login.<br />
A password module will be responsible if a user changes his password.</p>
<p>A PAM configuration file can have more than one of each module type. This is very important for us, since you want to have a way of logging into the host whenever LDAP is not available, using a local account (for instance root).</p>
<p>Each module type calls a PAM module, and has several control flags: required, requisite, sufficient, binding and optional.</p>
<p>Required means that the calling PAM module should report a success, or the entire request will be denied. For instance you have two account modules one checks if the account has not been deactivated, the other one checks whether the user is allowed to log in on that particular host (it&#8217;s just an example), then both modules would have to be successful, or the user is not allowed to log in.<br />
Requisite means the same as required, however no following PAM modules are executed whenever this PAM module reports failure.<br />
Sufficient means that if this module reports success, no other PAM modules are run, and the request is allowed (assuming any previous required or requisite modules reported success as well). When a sufficient module reports failure, then the request may still be allowed, whenever a following module reports success. This is the one we want.<br />
Binding is the same as sufficient, however on failure the entire request fails.<br />
Optional is ignored, unless the other modules return PAM_IGNORE.</p>
<p>PAM modules can also have arguments, of which the most useful probably is &#8216;debug&#8217;.</p>
<p>Let&#8217;s have a look at my /etc/pam.d/login configuration file. I&#8217;ve highlighted the modifications (additions, and that&#8217;s the beauty of it):<br />
<code><br />
#<br />
# $FreeBSD: src/etc/pam.d/login,v 1.17.8.1 2009/04/15 03:14:26 kensmith Exp $<br />
#<br />
# PAM configuration for the "login" service<br />
#<br />
</code><br />
<code><br />
# auth<br />
<em>auth		sufficient	/usr/local/lib/pam_ldap.so	no_warn</em><br />
auth		sufficient	pam_self.so		no_warn<br />
auth		include		system<br />
</code><br />
<code><br />
# account<br />
account		requisite	pam_securetty.so<br />
account		required	pam_nologin.so<br />
<em>account		sufficient	/usr/local/lib/pam_ldap.so</em><br />
account		include		system<br />
</code><br />
<code><br />
# session<br />
<em>session		required	/usr/local/lib/pam_mkhomedir.so<br />
session		optional	/usr/local/lib/pam_ldap.so</em><br />
session		include		system<br />
</code><br />
<code><br />
# password<br />
<em>password	sufficient	/usr/local/lib/pam_ldap.so md5</em><br />
password	include		system<br />
</code></p>
<p>Several lines hold the word &#8216;include&#8217;: a file called system is included, because obviously some services share common parameters. I could have made my alterations to that system file, and then all services which call this system file would benefit from my LDAP directory, however for educational purposes I only chose one service to be altered. What&#8217;s important is the order: if you have several auth modules, they&#8217;re read from top to bottom, and if you would put the unix authentication (which is defined by pam_unix.so in the system file) before the LDAP authentication (assuming you would not alter the control option from required to sufficient), and a user without local account would try to log in, he would never been able to enter the system, because when a required module fails, the entire request would fail.</p>
<p>Because of that reason, my auth starts with:<br />
<code><br />
auth		sufficient	/usr/local/lib/pam_ldap.so	no_warn<br />
</code></p>
<p>if login is able to match the given user account and password with the information found in LDAP, then login can stop processing other auth modules, if no valid account is found, look further in the other PAM modules.</p>
<p>Same for account: is the information needed in LDAP, use it, otherwise look somewhere else. You might notice the requisite and required modules in the account section. pam_securetty.so checks whether the tty is secured or not, and the user trying to login is superuser (root). If he is, and the tty is insecure, then logging in is not possible. pam_nologin.so checks if the file /etc/nologin exists, and will fail if it does and the user is not superuser (root), or is part of a class which doesn&#8217;t have to comply to that rule (man login.conf). But be assured that a normal user has to comply in a default installation.</p>
<p>The most important session module is the pam_mkhomedir.so: after a user has been granted login access to the host, this module checks whether a home directory exists for that user (as defined in the homeDirectory attribute in LDAP) and creates it if it&#8217;s not.<br />
The session module type also would be the place where you would mount a remote drive to that home directory (not described here).</p>
<p>The password module type lets you specify where an authentication (in this case a password) would be changed if a user types passwd.</p>
<p>This concludes the host part. The beauty of it is that you can copy those three files to all other hosts in your network: all configurations can be the same.<br />
Differences in authorizations can be established from within the LDAP directory.</p>
<h2>Preparing LDAP</h2>
<p>If you followed my tutorials so far, you&#8217;ll notice that you are not able to log in to a host using LDAP (assuming no local user equivalent exists on that host).</p>
<p>The reason is that although we have a working LDAP directory, it doesn&#8217;t contain the information the host is looking for. I log everything (my syslog.conf would contain &#8220;*.* /var/log/complete&#8221; if I would use syslog, so I noticed the following entries (local4.debug) in my log file, even without a user trying to log in:</p>
<p><code><br />
slapd[3263]: conn=243 op=4 SRCH base="ou=people,dc=boosten,dc=org" scope=1 deref=0 filter="(&#038;(objectClass=posixAccount)(uid=smmsp))"<br />
slapd[3263]: conn=243 op=4 SRCH attr=uid userPassword uidNumber gidNumber cn homeDirectory loginShell gecos description objectClass<br />
      shadowLastChange shadowMax shadowExpire<br />
</code><br />
It seems that other services already are trying to log in using LDAP, but since they do not exist in LDAP they&#8217;re tried locally, where they do exist. In this case it&#8217;s smmsp, which is part of sendmail.</p>
<p>Remember we made the pam_ldap.so module &#8216;sufficient&#8217;: if we would have made it &#8216;required&#8217;, or &#8216;binding&#8217;, the the entire request would have failed, and sendmail would not have been able to function normally.</p>
<p>There are actually two interesting facts in these log entries:</p>
<ol>
<li>apparantly, nss_ldap is searching &#8216;ou=people,dc=boosten,dc=org&#8217; for objectClass=posixAccount, and uid=smmsp</li>
<li>it tries to get the following attributes from an entry, once found: &#8216;uid userPassword uidNumber gidNumber cn homeDirectory loginShell gecos description objectClass shadowLastChange shadowMax shadowExpire&#8217;</li>
</ol>
<p>Since we have not yet defined most of these attributes in our directory, we are going to extend one entry, the entry for my daughter Dunja. What do we have already:</p>
<p><code><br />
ra% ldapsearch -H ldap://ldap.boosten.org -b "ou=people,dc=boosten,dc=org" -D "cn=root,dc=boosten,dc=org" -W -LLL "(uid=Dunja)"<br />
Enter LDAP Password:<br />
</code><br />
<code><br />
dn: cn=Dunja Boosten,ou=people,dc=boosten,dc=org<br />
cn: Dunja Boosten<br />
sn: Boosten<br />
givenName: Dunja<br />
objectClass: top<br />
objectClass: person<br />
objectClass: inetOrgPerson<br />
objectClass: organizationalPerson<br />
uid: dunja<br />
userPassword:: <hidden><br />
mail: dunja@boosten.org<br />
</hidden></code></p>
<p>No objectClass=posixAccount can be found, so this account is not going to be searched for when Dunja tries to log in to a host (not that she would, since she&#8217;s only three years of age). </p>
<p>Let&#8217;s have a look at the nis.schema, where the posixAccount is defined:<br />
<code><br />
objectclass ( 1.3.6.1.1.1.2.0 NAME 'posixAccount'<br />
        DESC 'Abstraction of an account with POSIX attributes'<br />
        SUP top AUXILIARY<br />
        MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory )<br />
        MAY ( userPassword $ loginShell $ gecos $ description ) )<br />
</code></p>
<p>The attributes behind MUST and MAY look familiar, don&#8217;t they?</p>
<p>The MUST attributes are mandatory, and already we have two of them defined in our element: cn and uid.<br />
Like mentioned before, uidNumber and gidNumber map to uid and gid in Unix, so these will contain number. Now you will have to make sure that the uidNumber is unique for every element you create within LDAP, or else you will get a access rights hell. The gidNumber doesn&#8217;t have to be unique, since a group of users (as defined by gid or Group ID) can consist of more than one user. FreeBSD however creates for every user a personal group, and in most of the cases gidNumber will match uidNumber.<br />
The homeDirectory attribute should contain the path to the users (hence the name) home directory. Normal practice is to have a home directory in /home/ called like the users login name (or uid attribute): /home/dunja.</p>
<p>The MAY attributes are optional, so it seems a password is optional, a loginShell is optional (not sure what happens if you do not assign this value, so we&#8217;ll try that), gecos information can contain some additional information, like the users phone number (what you would normally change with the chfn command, however I still found no way to alter this information, other than with ldapmodify). Description could hold &#8220;greatest daughter in the world&#8221;, but I would have to do that for both of my daughters.</p>
<p>Let&#8217;s start with the mandatory fields:</p>
<p><code><br />
# Dunja-add.ldif<br />
dn: cn=Dunja Boosten,ou=people,dc=boosten,dc=org<br />
changetype: modify<br />
add: objectClass<br />
objectClass: posixAccount<br />
-<br />
add: uidNumber<br />
uidNumber: 3000<br />
-<br />
add: gidNumber<br />
gidNumber: 3000<br />
-<br />
add: homeDirectory<br />
homeDirectory: /home/dunja<br />
</code></p>
<p>I&#8217;ll have her have a uidNumber that&#8217;s very high, for visibilty. The dashes between all atrtibute actions are mandatory (man ldapmodify or man ldif), without them you will get an error like &#8216;ldapmodify: wrong attributeType at line 5, entry &#8220;cn=&#8230;&#8217;. Let&#8217;s import this into LDAP:<br />
<code><br />
ra% ldapmodify -H ldap://ldap.boosten.org   -D "cn=root,dc=boosten,dc=org" -W  -f dunja-add.ldif<br />
Enter LDAP Password:<br />
modifying entry "cn=Dunja Boosten,ou=people,dc=boosten,dc=org"<br />
</code></p>
<p>Let&#8217;s try if we can log into the host, using this LDAP account (there&#8217;s no local account for Dunja). But before that, let&#8217;s show the contents of /home:</p>
<p><code><br />
ramses% pwd<br />
/home<br />
ramses% ls -l<br />
total 6<br />
drwxr-xr-x  2 bert    bert     512 Jul 23 08:49 bert<br />
drwxr-xr-x  2 jozina  jozina   512 Jul 21 20:33 jozina<br />
drwxr-xr-x  8 peter   peter   1024 Jul 23 10:57 peter<br />
</code></p>
<p>Now trying to log in:</p>
<p><code><br />
FreeBSD.i386 (ramses.egypt.nl) (ttyv0)<br />
</code><br />
<code><br />
login: dunja<br />
Password:<br />
No home directory.<br />
Logging in with home = "/".<br />
Copyright blahblah<br />
</code><br />
<code><br />
$<br />
</code></p>
<p>Hey, this worked. Although it states that there&#8217;s no home directory, pam_mkhomedir actually made one:</p>
<p><code><br />
ramses% pwd<br />
/home<br />
ramses% ls -l<br />
total 8<br />
drwxr-xr-x  2 bert    bert     512 Jul 23 08:49 bert<br />
drwxr-xr-x  2 dunja   <strong>3000</strong>     512 Jul 23 10:58 dunja<br />
drwxr-xr-x  2 jozina  jozina   512 Jul 21 20:33 jozina<br />
drwxr-xr-x  8 peter   peter   1024 Jul 23 10:57 peter<br />
</code></p>
<p>logging out and in (or is it: &#8216;off&#8217; and &#8216;on&#8217;?) again, corrects that first error message, and puts you right in the right directory.</p>
<p>There are (at least) two things not right yet:</p>
<ol>
<li>I don&#8217;t have a shell (echo $SHELL shows nothing), but since I&#8217;m able to look around I must have, probably /bin/sh</li>
<li>the listing of /home shows the group ID, and not a name. Obviously there&#8217;s no group 3000, which we will call dunja.</li>
</ol>
<p>Let&#8217;s correct both. First the shell:<br />
<code><br />
# dunja-shell.ldif<br />
dn: cn=Dunja Boosten,ou=people,dc=boosten,dc=org<br />
changetype: modify<br />
add: loginShell<br />
loginShell: /usr/local/bin/zsh<br />
</code></p>
<p><code><br />
ra% ldapmodify -H ldap://ldap.boosten.org   -D "cn=root,dc=boosten,dc=org" -W  -f dunja-shell.ldif<br />
Enter LDAP Password:<br />
modifying entry "cn=Dunja Boosten,ou=people,dc=boosten,dc=org"<br />
</code></p>
<p>Oke, this works. No let&#8217;s create a group. Remember from part one that I created an Organizational Unit called &#8220;ou=groups,dc=boosten,dc=org&#8221;, and earlier in this article I defined the following parameter in /usr/local/etc/ldap.conf (or nss-ldap.conf, it&#8217;s the same file):<br />
<code><br />
nss_base_group          ou=groups,dc=boosten,dc=org?one<br />
</code></p>
<p>So from my log file I discover this:<br />
<code><br />
slapd[6276]: conn=81 op=4 SRCH base="ou=groups,dc=boosten,dc=org" scope=1 deref=0 filter="(&#038;(objectClass=posixGroup)(gidNumber=3000))"<br />
slapd[6276]: conn=81 op=4 SRCH attr=cn userPassword memberUid uniqueMember gidNumber<br />
</code></p>
<p>nss_ldap searches for a posixGroup objectclass, with gidNumber 3000 in &#8220;ou=groups,dc=boosten,dc=org&#8221; and requests 5 attributes from it. The posixGroup objectClass has two mandatory attributes: cn and gidNumber, all others are optional.</p>
<p>We give nss_ldap what it wants: a group.<br />
<code><br />
# group-3000.ldif<br />
dn: cn=dunja,ou=groups,dc=boosten,dc=org<br />
objectClass: posixGroup<br />
cn: dunja<br />
gidNumber: 3000<br />
memberUid: 3000<br />
</code><code></p>
<p>The memberUid actually isn't necessary, but it looks nice. Now add it:<br />
</code><code><br />
ra% ldapadd -H ldap://ldap.boosten.org   -D "cn=root,dc=boosten,dc=org" -W  -f group-3000.ldif<br />
Enter LDAP Password:<br />
adding new entry "cn=dunja,ou=groups,dc=boosten,dc=org"<br />
</code></p>
<p>Works like charm. It even works already, without logging back in:<br />
<code><br />
ramses% ls -l<br />
total 8<br />
drwxr-xr-x  2 bert    bert     512 Jul 23 08:49 bert<br />
drwxr-xr-x  2 dunja   <strong>dunja</strong>    512 Jul 23 10:58 dunja<br />
drwxr-xr-x  2 jozina  jozina   512 Jul 21 20:33 jozina<br />
drwxr-xr-x  8 peter   peter   1024 Jul 23 10:57 peter<br />
</code></p>
<p>Logging out and in again solves the shell as well.</p>
<p>This concludes this part.</p>
<p>references:<br />
<a href="http://www.boosten.org/creating-my-own-ldap-directory-part-1/">Part one</a><br />
<a href="http://www.boosten.org/creating-my-own-ldap-directory-part-2/">Part two</a></p>
<img src="http://feeds.feedburner.com/~r/Boostenorg/~4/OJPv75_IhOw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.boosten.org/creating-my-own-ldap-directory-part-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>About stats – part 2</title>
		<link>http://www.boosten.org/about-stats-part-2/</link>
		<comments>http://www.boosten.org/about-stats-part-2/#comments</comments>
		<pubDate>Mon, 22 Jun 2009 06:00:33 +0000</pubDate>
		<dc:creator>Peter Boosten</dc:creator>
				<category><![CDATA[freebsd]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://www.boosten.org/about-stats-part-2/</guid>
		<description><![CDATA[My second article on my alternative way of collecting stats from different machines.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.boosten.org/newsite/?p=15">Last week</a> I wrote about collecting stats. If you collect long enough, you can create some pretty graphs from them.</p>
<p>But you can do more: for instance, you could use these as heartbeats.</p>
<p>Let suppose, one machine stopped sending those collecting email messages. Several problems could be causing this, like the internet connection for that server went down. Or you internet connection went down. Or the email server went down. Anyway, you would like to be notified of such an event, because you would want to look into that.</p>
<p>For that purpose I wrote a cronjob on my central host (the one with the MySQL server), to check when the other servers sent something the last time.</p>
<p>I created a cronjob, that would fire a shell script every five minutes. That shell script would look like this:</p>
<pre><span style="font-family: courier new,courier;">#!/bin/sh

HOSTS='validmst04 validmst03 isis muth ra ramses loghost'
CURRENT=`/bin/date +%s`
TENMINUTES=`/bin/expr ${CURRENT} - 600`

for a in ${HOSTS}; do
LASTENTRY=`/usr/local/bin/mysql -BNe \
  'select distinct unix_timestamp(date)\
  from stats\
  where server = "'"${a}"'"\
  order by date desc limit 1'`
if [ ${TENMINUTES} -gt ${LASTENTRY} ]; then       
  if [ -f /tmp/${a}.heartbeat ]; then           
    touch /tmp/${a}.heartbeat       
  else           
    touch /tmp/${a}.heartbeat         
    echo "No stats received from ${a} since `date -r ${LASTENTRY}`" | mail -s "ALERT: ${a}" peter
  fi
else
  if [ -f /tmp/${a}.heartbeat ]; then
    rm /tmp/${a}.heartbeat
    echo "${a} is sending stats again" | mail -s "ALERT END: ${a}" peter
  fi
fi
done</span></pre>
<p>The variable HOSTS is filled with all hosts I would like to keep an eye on, and the threshold for a server not sending email I defined as 10 minutes (the variable TENMINUTES substracts 600 seconds from the CURRENT time, which is the number of seconds since January 1, 1970 &#8211; date +%s).</p>
<p>In the SQL query, I convert the date of the last entry to seconds (unix_timestamp) and compare this with the value I calculated in TENMINUTES. If the TENMINUTES variable is greater than the last entry in the database for that server, then I send mysql an alert and create a &lt;server&gt;.heartbeat file in /tmp. This file acts as a semaphore: if I would not create this file and test for it, I would receive such an alert every five minutes, as long as my host receives no updates from the collecting host.</p>
<p>If I receive data again, I simply delete the semaphore, and everybody is happy again.</p>
<p>One other problem I&#8217;ve encountered was sending the information about the email statistics on my email relays.</p>
<p>For instance, I wanted to know who sends email to whom and when. No problem there. But I also wanted to know which emails were rejected and why.</p>
<p>For rejecting email I use two different methods: the first are DNS based blacklists, which are fairly effective in blocking spam, the other one is the virus scanner (ClamAV) together with MimeDefang. In addition to the normal ClamAV virus definitions, I use the signature files from SaneSecurity in otder to filter spam. In order to make some great stats I needed the sending address, the recipient address, the sending host (IP address), the date/time this message had been delivered, and of course the reason why it had been blocked (or put into quarantaine), thus the &#8216;virus name&#8217;.</p>
<p>These statistics are collected from the maillogs on a daily bases, with this script:</p>
<pre><span style="font-family: courier new,courier;">#!/usr/bin/awk -f
#

BEGIN {
    FS = ","
}
{
    split($1, ve, " ");
    if (ve[6] == "MDLOG" &amp;&amp; ($3 == "virus" || $3 == "modify" || $3 == "bad_filename" || $3 == "really_bad_filename")) {
        printf("%s %s %s;%s;%s;%s;%s;%s;%s;%s\n",ve[2],ve[1],ve[3],ve[4],$3,$4,$2,$5,$6,$7);
    }
}
END {}</span></pre>
<p>MimeDefang has a very distinct way of logging, therefore searching the logs for viruses has been made very easy. This script is run on the logging of the yesterdays&#8217; maillog and redirected into /tmp/vrschk-$TODAY (where $TODAY is substituted by the current date).</p>
<p>Because I wanted to mail the results every day to myself, I had to embed them into an email. Here comes the problem.</p>
<p>Some of the signatures look into the headers searching for domain names, and based on the result the email is quarantained. But since I wanted the sending address in my results list as well, the statistics mail would get quarantained as well.</p>
<p>The solution was simple: just encrypt the message, and decrypt it again on my server.</p>
<p>Sending:</p>
<pre><span style="font-family: courier new,courier;">/usr/sbin/sendmail -t &lt;&lt;EOF
From: some-email-address
To: another-email-address
X-Process: SECRETKEY-2</span></pre>
<pre><span style="font-family: courier new,courier;">Subject: Validmst04 Viruses

`cat /tmp/vrschk-$TODAY | crypt aaa | uuencode testfile`

EOF</span></pre>
<p>In this script I attach the contents of the result of the previous script into an email message, just after I encrypted it with the crypt command (and key &#8216;aaa&#8217;, but that doesn&#8217;t really matter, as long as it matches the key the attachment is decrypted with).</p>
<p>The reason for the encryption isn&#8217;t security (therefore I use crypt to encrypt it), but to prevent the ClamAV from recognizing the email as spam.</p>
<p>In this email I didn&#8217;t use a &#8216;KEY=SECRETKEY&#8217; construction in the body, but advanced to a better solution and put the identifier in the head of the email. The effect is the same, procmail (who&#8217;s processing this email) can make decisions based on keys in the header or in the body, whatever you like. But if it&#8217;s in the header it makes processing of the body easier.</p>
<p>This is the promail recipe:</p>
<pre><span style="font-family: courier new,courier;">:0 bw:*
 ^X-Process: SECRETKEY-2
| formail -I "" | uudecode  -o /dev/stdout| crypt aaa| grep -v "^$" &gt;&gt;/home/peter/development/programm/php/virus</span></pre>
<p>I search for the X-Process header, and if it matches, I process the body.</p>
<p>&#8216;formail -I &#8220;&#8221;&#8216; removes all header, &#8216;uudecode -o /dev/stdout&#8217; undoes the &#8216;uuencode&#8217; in the sending script, &#8216;crypt aaa&#8217; decrypts the contents, and &#8216;grep&#8217; removes all empty lines and puts the results into a file called /home/peter/development/programm/php/virus. I could have make the contents disappear automatically in a table in my MySQL database, but I chose to do this manually by a php script. In the beginning I always want to have complete control, therefore I do things manually, and for some reason I never changed this to automatic processing.</p>
<p>Looks like a new project <img src='http://www.boosten.org/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
<img src="http://feeds.feedburner.com/~r/Boostenorg/~4/GaLBxu_fEvQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://www.boosten.org/about-stats-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
