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

<channel>
	<title>GeneralThreat.com &#187; David</title>
	<atom:link href="http://www.generalthreat.com/author/admin/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.generalthreat.com</link>
	<description>Dangerously different projects and code</description>
	<lastBuildDate>Sun, 19 Jan 2014 20:00:34 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.2.38</generator>
	<item>
		<title>Grappling with BP theme compatibility</title>
		<link>http://www.generalthreat.com/2013/08/grappling-with-bp-theme-compatibility/</link>
		<comments>http://www.generalthreat.com/2013/08/grappling-with-bp-theme-compatibility/#comments</comments>
		<pubDate>Wed, 28 Aug 2013 18:16:26 +0000</pubDate>
		<dc:creator><![CDATA[David]]></dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[buddypress]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.generalthreat.com/?p=104</guid>
		<description><![CDATA[Theme compatibility was introduced in BuddyPress 1.7 and allows site operators to use BP with any available WordPress theme. I have been way behind at updating BP Group Hierarchy to support theme compatibility, and&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[<p><a href="http://codex.buddypress.org/theme-compatibility/">Theme compatibility</a> was introduced in BuddyPress 1.7 and allows site operators to use BP with any available WordPress theme. I have been way behind at updating <a href="http://wordpress.org/plugins/bp-group-hierarchy/">BP Group Hierarchy</a> to support theme compatibility, and as a result the Group Tree page looks like garbage when not using a theme that was written for BuddyPress. This post is about the effort to fix that.</p>
<p>If you are writing a normal BuddyPress plugin &#8212; one that adds pages rather than replacing them &#8212; see <a href="http://codex.buddypress.org/theme-compatibility/upgrading-older-plugins-that-bundle-custom-templates-for-bp-1-7/">this excellent article</a> (and <a href="http://codex.buddypress.org/theme-compatibility/how-to-enjoy-bp-theme-compat-in-plugins/">this one too</a>) at the BuddyPress Codex for info on how to implement BP theme compatibility.</p>
<h2>First idea: Replace the content from <code>directory_content</code> with the group tree.</h2>
<p><code>BP_Groups_Theme_Compat::directory_content()</code> is the native BP function that displays the group list page. It&#8217;s called as a hook to a filter called <code>bp_replace_the_content</code>, so the content should be available for further filtering after it runs.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * (BP 1.7+) Filter the theme-compatibility content for a group tree page
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> bp_group_hierarchy_inject_group_tree<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        add_filter<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_replace_the_content'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'bp_group_hierarchy_buffer_group_tree'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">100</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">function</span> bp_group_hierarchy_buffer_group_tree<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$content</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #990000;">ob_start</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$loop_template</span> <span style="color: #339933;">=</span> apply_filters<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_located_template'</span><span style="color: #339933;">,</span> locate_template<span style="color: #009900;">&#40;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;tree/index.php&quot;</span> <span style="color: #009900;">&#41;</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> <span style="color: #0000ff;">&quot;tree/index.php&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        load_template<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$loop_template</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        <span style="color: #000088;">$output</span> <span style="color: #339933;">=</span> <span style="color: #990000;">ob_get_clean</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$output</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// If admin says only show the group tree (and we are in theme compat), do it:</span>
add_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'groups_directory_groups_setup'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'bp_group_hierarchy_inject_group_tree'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><strong>Result:</strong> No dice. Directory content is echoed to the screen, not returned to the filter chain. The group tree appears below the flat group list.</p>
<h2>Workaround / second idea: Unhook the <code>directory_content</code> function so it doesn&#8217;t echo.</h2>
<p>Here&#8217;s a snippet that I threw together testing this out (warning: closure => PHP 5.3+ !):</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
 * (BP 1.7+) Filter the theme-compatibility content for a group tree page
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> bp_group_hierarchy_inject_group_tree<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        add_filter<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_replace_the_content'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                <span style="color: #009933; font-style: italic;">/**
                 * Filter is hooked by a method of an anonymous instance...
                 * Search all registered listeners and pick off the BP_Groups_Theme_Compat one.
                 */</span>
&nbsp;
                <span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$wp_filter</span><span style="color: #339933;">;</span>
&nbsp;
                <span style="color: #b1b100;">foreach</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$wp_filter</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'bp_replace_the_content'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">10</span><span style="color: #009900;">&#93;</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$key</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$filter</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                        <span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$filter</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'function'</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #990000;">is_a</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$filter</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'function'</span><span style="color: #009900;">&#93;</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: #0000ff;">'BP_Groups_Theme_Compat'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
                                <span style="color: #666666; font-style: italic;">// Found and removing the native content</span>
                                <span style="color: #990000;">unset</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$wp_filter</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'bp_replace_the_content'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">10</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$key</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                        <span style="color: #009900;">&#125;</span>
                <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">1</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        add_filter<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_replace_the_content'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'bp_group_hierarchy_buffer_group_tree'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">100</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
<span style="color: #000000; font-weight: bold;">function</span> bp_group_hierarchy_buffer_group_tree<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$content</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
        <span style="color: #666666; font-style: italic;">/* Same as before */</span>
        <span style="color: #b1b100;">return</span> <span style="color: #000088;">$output</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// If admin says only show the group tree (and we are in theme compat), do it:</span>
add_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'groups_directory_groups_setup'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'bp_group_hierarchy_inject_group_tree'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><strong>Result:</strong> Works well but is pretty awkward and brittle. It looks like the kind of solution I&#8217;d really like to avoid.</p>
<p>Let&#8217;s try something completely different. <img src="http://www.generalthreat.com/wordpress/wp-includes/images/smilies/simple-smile.png" alt=":)" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<h2>Third idea: Use BP Theme Compat functions to replace the loop template file.</h2>
<p>BuddyPress theme compatibility adds a lot of flexibility in how content is gathered for the site. I actually find the theme compatibility process much more intuitive to work with than the traditional template loading process.</p>
<p>Here are some highlights:</p>
<ol>
<li><code>bp_register_template_stack()</code> lets you add a source of template files without filtering <code>bp_located_template</code>. Nice!</li>
<li><code>bp_get_template_part()</code> offers an easy way to switch out template files on the fly that is just not possible with <code>load_template</code>.</li>
</ol>
<p>Is it really this easy?</p>
<p><strong>SPOILER ALERT:</strong> This does not work for BP Group Hierarchy. But for most applications, I think this is the best way to conditionally replace a BP page with content from a plugin.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * (BP 1.7+) Add plugin templates folder to list of available template paths
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> bp_group_hierarchy_register_template_location<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: #990000;">dirname</span><span style="color: #009900;">&#40;</span> <span style="color: #009900; font-weight: bold;">__FILE__</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/templates/'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * (BP 1.7+) Replace groups/groups-loop with tree/tree-loop depending on user settings
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> bp_group_hierarchy_maybe_replace_group_loop_template<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$templates</span><span style="color: #339933;">,</span> <span style="color: #000088;">$slug</span><span style="color: #339933;">,</span> <span style="color: #000088;">$name</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'groups/groups-loop'</span> <span style="color: #339933;">!=</span> <span style="color: #000088;">$slug</span> <span style="color: #009900;">&#41;</span>
		<span style="color: #b1b100;">return</span> <span style="color: #000088;">$templates</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'tree/tree-loop.php'</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;">'bp_register_template_stack'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
	bp_register_template_stack<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_group_hierarchy_register_template_location'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// If admin says only show the group tree (and we are in theme compat), do it:</span>
add_filter<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_get_template_part'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'bp_group_hierarchy_maybe_replace_group_loop_template'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">3</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><strong>Result:</strong> Works(!)<br />
But when you trigger an AJAX request, the unaltered ID on the &#8220;All Groups&#8221; tab leads BP to load the flat list.<br />
We also still need to hook the <code>bp_located_template</code> filter to find stylesheets, since we are enqueue-ing them instead of loading the contents inline.<br />
It also also removes the ability to customize the &#8220;Group Tree&#8221; label, a feature added by popular demand.</p>
<h2>Fourth idea: Use BP Theme Compat functions to replace the whole Groups list page.</h2>
<p>This is really just a twist on how things are currently handled, and it looks like the current way will be around as long as BP-compatible themes bypass <code>bp_get_template_part</code>.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * (BP 1.7+) Add plugin templates folder to list of available template paths
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> bp_group_hierarchy_register_template_location<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: #990000;">dirname</span><span style="color: #009900;">&#40;</span> <span style="color: #009900; font-weight: bold;">__FILE__</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'/templates/'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * (BP 1.7+) Replace groups/index with tree/index-compat depending on user settings
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> bp_group_hierarchy_maybe_replace_group_index_template<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$templates</span><span style="color: #339933;">,</span> <span style="color: #000088;">$slug</span><span style="color: #339933;">,</span> <span style="color: #000088;">$name</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'groups/index'</span> <span style="color: #339933;">!=</span> <span style="color: #000088;">$slug</span> <span style="color: #009900;">&#41;</span>
		<span style="color: #b1b100;">return</span> <span style="color: #000088;">$templates</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'tree/index-compat.php'</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;">'bp_register_template_stack'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
	bp_register_template_stack<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_group_hierarchy_register_template_location'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// If admin says only show the group tree (and we are in theme compat), do it:</span>
add_filter<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_get_template_part'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'bp_group_hierarchy_maybe_replace_group_index_template'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">3</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><strong>Result:</strong> Works seamlessly. It even allows BP to load templates from the stylesheet and template directories before falling back to those included with the plugin.</p>
<p>The only drawback is that it requires a new template file, the group tree version of the <code>bp-templates/bp-legacy/buddypress/groups/index.php</code> file from BP. Which is to say that it adds another layer of template hijinks and possible theme compatibility issues rather than removing an existing one.</p>
<h2>Wrap up</h2>
<p>I don&#8217;t know if this is the strategy that will ultimately make it into the plugin, but it is straightforward and has performed well in early tests. In the meantime, I hope this post will be useful to anyone else trying to do something crazy and ill-advised with BuddyPress.</p>
<p>If you use any of the techniques on this page, please drop me a line in the comments and let me know how they worked for you. And if you have any suggestions on techniques that work even better than these, please send those along too. <img src="http://s.w.org/images/core/emoji/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.generalthreat.com/2013/08/grappling-with-bp-theme-compatibility/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Make P2 posts private by default (and control them with tags)</title>
		<link>http://www.generalthreat.com/2013/06/make-p2-posts-private-by-default-and-control-them-with-tags/</link>
		<comments>http://www.generalthreat.com/2013/06/make-p2-posts-private-by-default-and-control-them-with-tags/#comments</comments>
		<pubDate>Sun, 30 Jun 2013 20:02:24 +0000</pubDate>
		<dc:creator><![CDATA[David]]></dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[p2]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.generalthreat.com/?p=101</guid>
		<description><![CDATA[The Wordpress theme <a href="http://p2theme.com/">P2</a> is great for collaboration and team discussion. Sometimes that discussion can be entirely public, and at other times it makes sense to put the entire site behind a login screen. But what if you want to combine a private discussion stream with public pages? Or mix public posts with private ones? This post will show you how to mix and match private and public posts on your P2 blog and will set up a framework for controlling post behavior through tags.]]></description>
				<content:encoded><![CDATA[<p>The WordPress theme <a href="http://p2theme.com/">P2</a> is great for collaboration and team discussion. Sometimes that discussion can be entirely public, and at other times it makes sense to put the entire site behind a login screen. But what if you want to combine a private discussion stream with public pages? Or mix public posts with private ones? P2 emphasizes quick and easy posting by streamlining the process, but this comes at the expense of options.</p>
<p>This post will show you how to mix and match private and public posts on your P2 blog and will set up a framework for controlling post behavior through tags.</p>
<p>No changes to P2&#8217;s files are needed, and this trick will work even with older versions on the theme. This code should be placed in your child theme&#8217;s <code>functions.php</code> file or in a plugin of your own. There&#8217;s a <a href="#combined">combined block</a> at the bottom of this post for easy copy and paste.</p>
<h2><a name="step1"></a>1. Hook P2&#8217;s post save mechanism</h2>
<p>While P2 exposes limited posting options, authors using the back-end dashboard have access to the full publishing UI. So we want to make sure to target only posts made from the front-end to avoid confusion for authors using full UI.</p>
<p>Loading our handlers this way allows us to ensure that only P2 posts are affected by these magic tags.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
 * Use this action to catch requests to P2 AJAX functions
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> gtp2_add_hooks<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	add_filter<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'wp_insert_post_data'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'gtp2_maybe_make_post_private'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	add_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'pre_get_posts'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'gtp2_include_private_posts'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
add_action<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'p2_ajax'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'gtp2_add_hooks'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h2>2. Check for magic tags when saving</h2>
<p>Having hooked the action above, we know that the function below will only run on P2 posts. First, the list of tags is split into an array so we can look for them more easily. Then, we search for any tags we have decided will control post behavior, and change the post accordingly.</p>
<p><strong>Check out lines 21-24</strong> &mdash; this is where the magic happens. We check whether the post is tagged <code>public</code>. If it is, we leave it alone (P2 posts are public by default). If it isn&#8217;t, we change its status to private.</p>
<p>This example only implements a single check, but you can create as many as you want.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
 * Change post status to private unless it is tagged &quot;public&quot;
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> gtp2_maybe_make_post_private<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$data</span><span style="color: #339933;">,</span> <span style="color: #000088;">$postarr</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000088;">$tags</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$postarr</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'tags_input'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Tag processing borrowed from wp_set_post_terms()
	 */</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> <span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$tags</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$comma</span> <span style="color: #339933;">=</span> _x<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">','</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'tag delimiter'</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: #0000ff;">','</span> <span style="color: #339933;">!==</span> <span style="color: #000088;">$comma</span> <span style="color: #009900;">&#41;</span>
			<span style="color: #000088;">$tags</span> <span style="color: #339933;">=</span> <span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$comma</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">','</span><span style="color: #339933;">,</span> <span style="color: #000088;">$tags</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$tags</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">','</span><span style="color: #339933;">,</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$tags</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot; <span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\t</span><span style="color: #000099; font-weight: bold;">\r</span><span style="color: #660099; font-weight: bold;">\0</span><span style="color: #660099; font-weight: bold;">\x0B</span>,&quot;</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: #009933; font-style: italic;">/**
	 * Look for tags and control what they do here
	 */</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> <span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'public'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$tags</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// Change attributes of the post here</span>
		<span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'post_status'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'private'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Make sure to return the data!</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$data</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h2>3. Fix the in-page refresh</h2>
<p>P2&#8217;s fancy in-page refresh only loads public posts. To make our change seamless to users, this needs to be expanded to load private posts too. We&#8217;ll need to add one more short function to accomplish this. You may have seen a hint of it in <a href="#step1">Step 1</a>, but here&#8217;s the function itself.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
 * Expand query to include all post status values visible to current user
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> gtp2_include_private_posts<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$obj</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$obj</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'post_status'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'any'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>That&#8217;s it! Users logged in with Editor or Administrator privileges won&#8217;t notice a difference, but other users and anonymous visitors will see only their own posts and those tagged <code>public</code>.</p>
<p>Feel free to drop me a line in the comments if you have any questions or find a use for this on your own sites!</p>
<hr />
<h2><a name="combined"></a>The whole thing</h2>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/**
 * Make all P2 posts Private unless they are tagged &quot;public&quot;
 */</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Use this action to catch requests to P2 AJAX functions
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> gtp2_add_hooks<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	add_filter<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'wp_insert_post_data'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'gtp2_maybe_make_post_private'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">2</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	add_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'pre_get_posts'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'gtp2_include_private_posts'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
add_action<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'p2_ajax'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'gtp2_add_hooks'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Change post status to private unless it is tagged &quot;public&quot;
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> gtp2_maybe_make_post_private<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$data</span><span style="color: #339933;">,</span> <span style="color: #000088;">$postarr</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000088;">$tags</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$postarr</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'tags_input'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #009933; font-style: italic;">/**
	 * Tag processing borrowed from wp_set_post_terms()
	 */</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> <span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$tags</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$comma</span> <span style="color: #339933;">=</span> _x<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">','</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'tag delimiter'</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: #0000ff;">','</span> <span style="color: #339933;">!==</span> <span style="color: #000088;">$comma</span> <span style="color: #009900;">&#41;</span>
			<span style="color: #000088;">$tags</span> <span style="color: #339933;">=</span> <span style="color: #990000;">str_replace</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$comma</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">','</span><span style="color: #339933;">,</span> <span style="color: #000088;">$tags</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$tags</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">','</span><span style="color: #339933;">,</span> <span style="color: #990000;">trim</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$tags</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot; <span style="color: #000099; font-weight: bold;">\n</span><span style="color: #000099; font-weight: bold;">\t</span><span style="color: #000099; font-weight: bold;">\r</span><span style="color: #660099; font-weight: bold;">\0</span><span style="color: #660099; font-weight: bold;">\x0B</span>,&quot;</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: #009933; font-style: italic;">/**
	 * Look for tags and control what they do here
	 */</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> <span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'public'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$tags</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #666666; font-style: italic;">// Change attributes of the post here</span>
		<span style="color: #000088;">$data</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'post_status'</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'private'</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Make sure to return the data!</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$data</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 * Expand query to include all post status values visible to the current user
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> gtp2_include_private_posts<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$obj</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$obj</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">set</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'post_status'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'any'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://www.generalthreat.com/2013/06/make-p2-posts-private-by-default-and-control-them-with-tags/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Serving koha-common with Plack</title>
		<link>http://www.generalthreat.com/2013/04/serving-koha-common-with-plack/</link>
		<comments>http://www.generalthreat.com/2013/04/serving-koha-common-with-plack/#comments</comments>
		<pubDate>Tue, 16 Apr 2013 01:21:59 +0000</pubDate>
		<dc:creator><![CDATA[David]]></dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[Koha]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://www.generalthreat.com/?p=98</guid>
		<description><![CDATA[An update to my post on running the koha-common OPAC on Plack. With Koha 3.10 both the OPAC and Intranet can take advantage of the speed and efficiency of the Plack server. Follow these simple steps to get your catalog running better than ever, or follow the link to github for a script to handle the setup for you!]]></description>
				<content:encoded><![CDATA[<p>This post builds on my <a href="http://www.generalthreat.com/2012/09/serving-the-koha-common-opac-with-plack/">last Koha post about running the OPAC on Plack</a> and will modify some of the files from that post. If you haven&#8217;t read it, it is a good background post but the snippets are no longer up-to-date.</p>
<p>Except where noted, I put these files in a new <code>/usr/share/koha/misc/plack</code> folder. This guide and these code samples assume you will too.</p>
<p><strong>Hey!</strong> Do you want the speed of Plack but don&#8217;t want to deal with all of these files? Check out <a href="https://github.com/JerseyConnect/Plackify-koha-common">Plackify koha-common</a> on github! This post will eventually go out of date, but the github project will always have the latest scripts and a painless installer.</p>
<p>Let&#8217;s begin!</p>
<h2>1. Create the PSGI application file</h2>
<h3><code>koha.psgi:</code></h3>
<p>This is the file that will do the heavy lifting for your Koha install. It is used to run both Intranet and OPAC front-end sites.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl</span>
<span style="color: #000000; font-weight: bold;">use</span> Plack<span style="color: #339933;">::</span><span style="color: #006600;">Builder</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Plack<span style="color: #339933;">::</span><span style="color: #006600;">App</span><span style="color: #339933;">::</span><span style="color: #006600;">CGIBin</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Plack<span style="color: #339933;">::</span><span style="color: #006600;">App</span><span style="color: #339933;">::</span><span style="color: #006600;">Directory</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> lib<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;/usr/share/koha/lib&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> C4<span style="color: #339933;">::</span><span style="color: #006600;">Context</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> C4<span style="color: #339933;">::</span><span style="color: #006600;">Languages</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> C4<span style="color: #339933;">::</span><span style="color: #006600;">Members</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> C4<span style="color: #339933;">::</span><span style="color: #006600;">Dates</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> C4<span style="color: #339933;">::</span><span style="color: #006600;">Boolean</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> C4<span style="color: #339933;">::</span><span style="color: #006600;">Letters</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> C4<span style="color: #339933;">::</span><span style="color: #006600;">Koha</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> C4<span style="color: #339933;">::</span><span style="color: #006600;">XSLT</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> C4<span style="color: #339933;">::</span><span style="color: #006600;">Branch</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> C4<span style="color: #339933;">::</span><span style="color: #006600;">Category</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$root</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$ENV</span><span style="color: #009900;">&#123;</span>INTRANETDIR<span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span>
                <span style="color: #0000ff;">$ENV</span><span style="color: #009900;">&#123;</span>INTRANETDIR<span style="color: #009900;">&#125;</span> <span style="color: #339933;">.</span> <span style="color: #ff0000;">'/cgi-bin'</span> <span style="color: #339933;">:</span>
                <span style="color: #0000ff;">$ENV</span><span style="color: #009900;">&#123;</span>OPACDIR<span style="color: #009900;">&#125;</span> <span style="color: #339933;">.</span> <span style="color: #ff0000;">'/cgi-bin/opac'</span> <span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$app</span><span style="color: #339933;">=</span>Plack<span style="color: #339933;">::</span><span style="color: #006600;">App</span><span style="color: #339933;">::</span><span style="color: #006600;">CGIBin</span><span style="color: #339933;">-&gt;</span><span style="color: #000000; font-weight: bold;">new</span><span style="color: #009900;">&#40;</span>root <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$root</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
builder <span style="color: #009900;">&#123;</span>
&nbsp;
        mount <span style="color: #ff0000;">&quot;/opac-tmpl&quot;</span> <span style="color: #339933;">=&gt;</span> Plack<span style="color: #339933;">::</span><span style="color: #006600;">App</span><span style="color: #339933;">::</span><span style="color: #006600;">File</span><span style="color: #339933;">-&gt;</span><span style="color: #000000; font-weight: bold;">new</span><span style="color: #009900;">&#40;</span>root <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">&quot;/usr/share/koha/opac/htdocs/opac-tmpl&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        mount <span style="color: #ff0000;">&quot;/intranet-tmpl&quot;</span> <span style="color: #339933;">=&gt;</span> Plack<span style="color: #339933;">::</span><span style="color: #006600;">App</span><span style="color: #339933;">::</span><span style="color: #006600;">File</span><span style="color: #339933;">-&gt;</span><span style="color: #000000; font-weight: bold;">new</span><span style="color: #009900;">&#40;</span>root <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">&quot;/usr/share/koha/intranet/htdocs/intranet-tmpl&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
        mount <span style="color: #ff0000;">&quot;/cgi-bin/koha&quot;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$app</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h2>2. Create startup scripts for both the intranet and OPAC</h2>
<p>These scripts will handle starting your Plack OPAC and Intranet (respectively) in a way that can be controlled by `koha-common` style start and stop commands.</p>
<p><strong>Note:</strong> These scripts assume that you installed Starman from CPAN. If you used your distro&#8217;s package manager, you should check your starman path and update these scripts if needed.</p>
<h3><code>opac-plack.sh:</code></h3>
<p>Make sure this script is executable!</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
<span style="color: #666666; font-style: italic;"># --max-requests = decreased from 1000 to 50 to keep memory usage sane</span>
<span style="color: #666666; font-style: italic;"># --workers = number of cores on machine</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">test</span> <span style="color: #000000; font-weight: bold;">!</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000; font-weight: bold;">&amp;</span>amp; <span style="color: #007800;">site</span>=<span style="color: #007800;">$1</span> <span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000; font-weight: bold;">&amp;</span>amp; <span style="color: #7a0874; font-weight: bold;">shift</span>
<span style="color: #007800;">dir</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">dirname</span> <span style="color: #007800;">$0</span><span style="color: #000000; font-weight: bold;">`</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">KOHA_CONF</span>=<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>koha<span style="color: #000000; font-weight: bold;">/</span>sites<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$site</span><span style="color: #000000; font-weight: bold;">/</span>koha-conf.xml
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">OPACDIR</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$( xmlstarlet sel -t -v 'yazgfs/config/opacdir' $KOHA_CONF | sed 's,/cgi-bin/opac,,' )</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">LOGDIR</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$( xmlstarlet sel -t -v 'yazgfs/config/logdir' $KOHA_CONF )</span>&quot;</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">MEMCACHED_SERVERS</span>=localhost:<span style="color: #000000;">11211</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">MEMCACHED_NAMESPACE</span>=<span style="color: #007800;">$site</span>
&nbsp;
<span style="color: #007800;">PIDFILE</span>=<span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>run<span style="color: #000000; font-weight: bold;">/</span>koha<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$site</span><span style="color: #000000; font-weight: bold;">/</span>opac-plack.pid
&nbsp;
<span style="color: #007800;">SOCKET</span>=<span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>run<span style="color: #000000; font-weight: bold;">/</span>koha<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$site</span><span style="color: #000000; font-weight: bold;">/</span>opac-plack.sock
<span style="color: #666666; font-style: italic;">#PORT=5000</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># uncomment to enable logging</span>
<span style="color: #007800;">opt</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$opt</span> --access-log <span style="color: #007800;">$LOGDIR</span>/opac-access.log --error-log <span style="color: #007800;">$LOGDIR</span>/opac-error.log&quot;</span>
<span style="color: #007800;">opt</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$opt</span> -M FindBin --max-requests 50 --workers 2 -E deployment&quot;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$SOCKET</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #007800;">opt</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$opt</span> --listen <span style="color: #007800;">$SOCKET</span> -D --pid <span style="color: #007800;">$PIDFILE</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">elif</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$PORT</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #007800;">opt</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$opt</span> --port <span style="color: #007800;">$PORT</span> -D --pid <span style="color: #007800;">$PIDFILE</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<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>starman <span style="color: #007800;">$opt</span> <span style="color: #007800;">$dir</span><span style="color: #000000; font-weight: bold;">/</span>koha.psgi</pre></td></tr></table></div>

<h3><code>intranet-plack.sh:</code></h3>
<p>Make sure this script is executable!</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
<span style="color: #666666; font-style: italic;"># --max-requests = decreased from 1000 to 50 to keep memory usage sane</span>
<span style="color: #666666; font-style: italic;"># --workers = number of cores on machine</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">test</span> <span style="color: #000000; font-weight: bold;">!</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000; font-weight: bold;">&amp;</span>amp; <span style="color: #007800;">site</span>=<span style="color: #007800;">$1</span> <span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000; font-weight: bold;">&amp;</span>amp; <span style="color: #7a0874; font-weight: bold;">shift</span>
<span style="color: #007800;">dir</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">dirname</span> <span style="color: #007800;">$0</span><span style="color: #000000; font-weight: bold;">`</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">KOHA_CONF</span>=<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>koha<span style="color: #000000; font-weight: bold;">/</span>sites<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$site</span><span style="color: #000000; font-weight: bold;">/</span>koha-conf.xml
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">INTRANETDIR</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$( xmlstarlet sel -t -v 'yazgfs/config/intranetdir' $KOHA_CONF | sed 's,/cgi-bin,,' )</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">LOGDIR</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$( xmlstarlet sel -t -v 'yazgfs/config/logdir' $KOHA_CONF )</span>&quot;</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">MEMCACHED_SERVERS</span>=localhost:<span style="color: #000000;">11211</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">MEMCACHED_NAMESPACE</span>=<span style="color: #007800;">$site</span>
&nbsp;
<span style="color: #007800;">PIDFILE</span>=<span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>run<span style="color: #000000; font-weight: bold;">/</span>koha<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$site</span><span style="color: #000000; font-weight: bold;">/</span>intranet-plack.pid
&nbsp;
<span style="color: #007800;">SOCKET</span>=<span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>run<span style="color: #000000; font-weight: bold;">/</span>koha<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$site</span><span style="color: #000000; font-weight: bold;">/</span>intranet-plack.sock
<span style="color: #666666; font-style: italic;">#PORT=5000</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># uncomment to enable logging</span>
<span style="color: #007800;">opt</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$opt</span> --access-log <span style="color: #007800;">$LOGDIR</span>/intranet-access.log --error-log <span style="color: #007800;">$LOGDIR</span>/intranet-error.log&quot;</span>
<span style="color: #007800;">opt</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$opt</span> -M FindBin --max-requests 50 --workers 2 -E deployment&quot;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$SOCKET</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #007800;">opt</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$opt</span> --listen <span style="color: #007800;">$SOCKET</span> -D --pid <span style="color: #007800;">$PIDFILE</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">elif</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$PORT</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #007800;">opt</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$opt</span> --port <span style="color: #007800;">$PORT</span> -D --pid <span style="color: #007800;">$PIDFILE</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<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>starman <span style="color: #007800;">$opt</span> <span style="color: #007800;">$dir</span><span style="color: #000000; font-weight: bold;">/</span>koha.psgi</pre></td></tr></table></div>

<h2>2a. Scripts for opening access to socket files</h2>
<p><strong>Note:</strong> If you&#8217;re using sockets instead of TCP ports on Linux, you&#8217;ll need to make sure they are world-writable. The following two scripts can be run by <code>koha-start-plack</code> to make sure the sockets are available to any application.</p>
<h3><code>unlock-opac-plack.sh:</code></h3>
<p>Make sure this script is executable!</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">test</span> <span style="color: #000000; font-weight: bold;">!</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000; font-weight: bold;">&amp;</span>amp; <span style="color: #007800;">site</span>=<span style="color: #007800;">$1</span> <span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000; font-weight: bold;">&amp;</span>amp; <span style="color: #7a0874; font-weight: bold;">shift</span>
&nbsp;
<span style="color: #007800;">timeout</span>=<span style="color: #000000;">0</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Waiting for OPAC Plack socket for <span style="color: #007800;">$site</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">while</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #000000; font-weight: bold;">!</span> <span style="color: #660033;">-S</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>run<span style="color: #000000; font-weight: bold;">/</span>koha<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$site</span><span style="color: #000000; font-weight: bold;">/</span>opac-plack.sock <span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000; font-weight: bold;">&amp;</span>amp; <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$timeout</span> <span style="color: #660033;">-lt</span> <span style="color: #000000;">10</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #000000; font-weight: bold;">do</span>
        <span style="color: #c20cb9; font-weight: bold;">sleep</span> <span style="color: #000000;">1</span>
        <span style="color: #007800;">timeout</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #007800;">$timeout</span> + <span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">done</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">chmod</span> <span style="color: #000000;">777</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>run<span style="color: #000000; font-weight: bold;">/</span>koha<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$site</span><span style="color: #000000; font-weight: bold;">/</span>opac-plack.sock
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;OPAC Plack socket open for <span style="color: #007800;">$site</span>&quot;</span></pre></td></tr></table></div>

<h3><code>unlock-intranet-plack.sh:</code></h3>
<p>Make sure this script is executable!</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">test</span> <span style="color: #000000; font-weight: bold;">!</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000; font-weight: bold;">&amp;</span>amp; <span style="color: #007800;">site</span>=<span style="color: #007800;">$1</span> <span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000; font-weight: bold;">&amp;</span>amp; <span style="color: #7a0874; font-weight: bold;">shift</span>
&nbsp;
<span style="color: #007800;">timeout</span>=<span style="color: #000000;">0</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Waiting for Intranet Plack socket for <span style="color: #007800;">$site</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">while</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #000000; font-weight: bold;">!</span> <span style="color: #660033;">-S</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>run<span style="color: #000000; font-weight: bold;">/</span>koha<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$site</span><span style="color: #000000; font-weight: bold;">/</span>intranet-plack.sock <span style="color: #7a0874; font-weight: bold;">&#93;</span> <span style="color: #000000; font-weight: bold;">&amp;</span>amp;<span style="color: #000000; font-weight: bold;">&amp;</span>amp; <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$timeout</span> <span style="color: #660033;">-lt</span> <span style="color: #000000;">10</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #000000; font-weight: bold;">do</span>
        <span style="color: #c20cb9; font-weight: bold;">sleep</span> <span style="color: #000000;">1</span>
        <span style="color: #007800;">timeout</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #007800;">$timeout</span> + <span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">done</span>
&nbsp;
<span style="color: #c20cb9; font-weight: bold;">chmod</span> <span style="color: #000000;">777</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>run<span style="color: #000000; font-weight: bold;">/</span>koha<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$site</span><span style="color: #000000; font-weight: bold;">/</span>intranet-plack.sock
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Intranet Plack socket open for <span style="color: #007800;">$site</span>&quot;</span></pre></td></tr></table></div>

<h2>3. Create control scripts for startup and shutdown</h2>
<p>Finally, create the koha-common style start and stop scripts to control your Plack processes.</p>
<h3><code>/usr/sbin/koha-start-plack:</code></h3>
<p>This script will start Plack processes for both the Intranet and the OPAC. Like other koha-common scripts, it takes the name of the instance as a parameter. Make sure it&#8217;s executable!</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># koha-start-plack -- Start plack processes for named Koha instances</span>
<span style="color: #666666; font-style: italic;">#</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">set</span> <span style="color: #660033;">-e</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">for</span> name <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #ff0000;">&quot;$@&quot;</span>
<span style="color: #000000; font-weight: bold;">do</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Starting OPAC Plack server for <span style="color: #007800;">$name</span>&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">exec</span> start-stop-daemon \
        <span style="color: #660033;">--start</span> \
        <span style="color: #660033;">--chuid</span> <span style="color: #007800;">$name</span>-koha \
        <span style="color: #660033;">--exec</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>share<span style="color: #000000; font-weight: bold;">/</span>koha<span style="color: #000000; font-weight: bold;">/</span>misc<span style="color: #000000; font-weight: bold;">/</span>plack<span style="color: #000000; font-weight: bold;">/</span>opac-plack.sh <span style="color: #660033;">--</span> <span style="color: #007800;">$name</span> \
        <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>share<span style="color: #000000; font-weight: bold;">/</span>koha<span style="color: #000000; font-weight: bold;">/</span>misc<span style="color: #000000; font-weight: bold;">/</span>plack<span style="color: #000000; font-weight: bold;">/</span>unlock-opac-plack.sh <span style="color: #007800;">$name</span>
&nbsp;
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Starting Intranet Plack server for <span style="color: #007800;">$name</span>&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">exec</span> start-stop-daemon \
        <span style="color: #660033;">--start</span> \
        <span style="color: #660033;">--chuid</span> <span style="color: #007800;">$name</span>-koha \
        <span style="color: #660033;">--exec</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>share<span style="color: #000000; font-weight: bold;">/</span>koha<span style="color: #000000; font-weight: bold;">/</span>misc<span style="color: #000000; font-weight: bold;">/</span>plack<span style="color: #000000; font-weight: bold;">/</span>intranet-plack.sh <span style="color: #660033;">--</span> <span style="color: #007800;">$name</span> \
        <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>share<span style="color: #000000; font-weight: bold;">/</span>koha<span style="color: #000000; font-weight: bold;">/</span>misc<span style="color: #000000; font-weight: bold;">/</span>plack<span style="color: #000000; font-weight: bold;">/</span>unlock-intranet-plack.sh <span style="color: #007800;">$name</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">done</span></pre></td></tr></table></div>

<h3><code>/usr/sbin/koha-stop-plack:</code></h3>
<p>This script will stop Plack processes for both the Intranet and the OPAC. It also takes the name of the instance as a parameter. Make sure it&#8217;s executable!</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># koha-stop-plack -- Stop plack processes for named Koha instances</span>
&nbsp;
stopopac<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
   <span style="color: #7a0874; font-weight: bold;">local</span> <span style="color: #007800;">name</span>=<span style="color: #ff0000;">&quot;$1&quot;</span>
   <span style="color: #7a0874; font-weight: bold;">exec</span> start-stop-daemon \
        <span style="color: #660033;">--stop</span> \
        <span style="color: #660033;">--quiet</span> \
        <span style="color: #660033;">--pidfile</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>run<span style="color: #000000; font-weight: bold;">/</span>koha<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$name</span><span style="color: #000000; font-weight: bold;">/</span>opac-plack.pid
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
stopstaff<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
   <span style="color: #7a0874; font-weight: bold;">local</span> <span style="color: #007800;">name</span>=<span style="color: #ff0000;">&quot;$1&quot;</span>
   <span style="color: #7a0874; font-weight: bold;">exec</span> start-stop-daemon \
        <span style="color: #660033;">--stop</span> \
        <span style="color: #660033;">--quiet</span> \
        <span style="color: #660033;">--pidfile</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>run<span style="color: #000000; font-weight: bold;">/</span>koha<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$name</span><span style="color: #000000; font-weight: bold;">/</span>intranet-plack.pid
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">for</span> name <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #ff0000;">&quot;$@&quot;</span>
<span style="color: #000000; font-weight: bold;">do</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Stopping Plack servers for <span style="color: #007800;">$name</span>&quot;</span>
    stopopac <span style="color: #ff0000;">&quot;<span style="color: #007800;">$name</span>&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> stopstaff <span style="color: #ff0000;">&quot;<span style="color: #007800;">$name</span>&quot;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">done</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Servers stopped&quot;</span></pre></td></tr></table></div>

<h2>4. Prepare Koha to launch Plack</h2>
<h3><code>/etc/init.d/koha-common:</code></h3>
<p>There are two final changes needed to make Plack a first class part of your koha-common install. Both are made to your <code>/etc/init.d/koha-common</code> file, but they&#8217;re both really simple.</p>
<p>First, add the new koha-start-plack script to the <code>do_start()</code> function, just after the <code>koha-start-zebra</code> line.</p>
<pre>
     koha-start-plack $(koha-list --enabled)
</pre>
<p>Then add the new koha-stop-plack script to the <code>do_stop()</code> function, just after the <code>koha-stop-zebra</code> line.</p>
<pre>
    koha-stop-plack $(koha-list) || true
</pre>
<p>That&#8217;s it! Stop and start your koha-common service to enjoy your new Plack infrastructure.</p>
<h2>Problems? &mdash; Check:</h2>
<ul>
<li>log directory is writable by your *-koha user</li>
<li>tmp directory for compiled templates is writable by your *-koha user</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.generalthreat.com/2013/04/serving-koha-common-with-plack/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Plugins now available on GitHub</title>
		<link>http://www.generalthreat.com/2012/12/plugins-now-available-on-github/</link>
		<comments>http://www.generalthreat.com/2012/12/plugins-now-available-on-github/#comments</comments>
		<pubDate>Tue, 11 Dec 2012 02:42:41 +0000</pubDate>
		<dc:creator><![CDATA[David]]></dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[projects]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.generalthreat.com/?p=97</guid>
		<description><![CDATA[Most of my WordPress plugins are now mirrored on GitHub! This includes Networks for WordPress, which I have traditionally not linked back to this site.]]></description>
				<content:encoded><![CDATA[<p>Most of my WordPress plugins are <a href="https://github.com/ddean4040">now mirrored on GitHub</a>! </p>
<p>This includes Networks for WordPress, which I have traditionally not linked back to this site.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.generalthreat.com/2012/12/plugins-now-available-on-github/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating a (relatively) secure dynamic PHP test environment with nginx</title>
		<link>http://www.generalthreat.com/2012/11/creating-a-secure-dynamic-env/</link>
		<comments>http://www.generalthreat.com/2012/11/creating-a-secure-dynamic-env/#comments</comments>
		<pubDate>Fri, 30 Nov 2012 02:51:54 +0000</pubDate>
		<dc:creator><![CDATA[David]]></dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.generalthreat.com/?p=95</guid>
		<description><![CDATA[I&#8217;ve been working on a deployment tool for WordPress development environments; one that can quickly provision and maintain the dizzying array of sites needed to test plugins against different versions of WordPress (with and&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve been working on a deployment tool for WordPress development environments; one that can quickly provision and maintain the dizzying array of sites needed to test plugins against different versions of WordPress (with and w/o Multisite), BuddyPress, bbPress, etc.</p>
<p>Some cocktail napkin math suggested at least 20 combinations were needed to cover all the currently-supported configurations. Besides the chore of setting up environments for each, the need to add or remove environments as components are updated makes a manual deployment effort seem ridiculous.</p>
<p>While I&#8217;m finishing up work on that tool, I thought I&#8217;d start by posting the web server and PHP configs I&#8217;m using to make this happen.</p>
<h3>nginx Configuration</h3>
<p>I went with nginx because of its low memory usage and its handy regular-expression hostname matching, which I find more flexible and less kludgey for this application than mod_vhost_alias or mod_rewrite. This nginx config will provide the flexibility of dynamically-creating sites while still providing some isolation between them.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="nginx" style="font-family:monospace;">server {
        server_name ~^(.*)\.dev.your.domain$ ;
&nbsp;
        set $instance $1;
        set $session_root /var/www/dev/$instance/sessions;
&nbsp;
        root /var/www/dev/$instance/html;
        index index.php;
&nbsp;
        location ~ \.php$ {
&nbsp;
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
&nbsp;
                fastcgi_pass unix:/var/run/fpm-devsites.sock;
#               fastcgi_pass 127.0.0.1:9000
                fastcgi_param PATH_INFO $fastcgi_path_info;
                fastcgi_param SCRIPT_FILENAME  $document_root$fastcgi_script_name;
                fastcgi_param PHP_ADMIN_VALUE  &quot;open_basedir=$document_root\nsession.save_path=$session_root&quot;;
                include /etc/nginx/fastcgi_params;
&nbsp;
        }
&nbsp;
        location / {
                try_files $uri $uri/ /index.php;
        }
}</pre></td></tr></table></div>

<p>Thanks to mike at <a href="http://michaelshadle.com/2011/02/11/setting-php-ini-parameters-from-nginx">http://michaelshadle.com/2011/02/11/setting-php-ini-parameters-from-nginx</a> for the great guide to the PHP_ADMIN_VALUE param.</p>
<h3>PHP-FPM Configuration</h3>
<p>Ideally each site would have its own FPM pool, but that would mean root privileges were needed to provision new sites. So a single but separate pool for the dev environments was a necessary compromise. The goal of dynamically creating sites through an unprivileged web interface also meant that the <code>devsites</code> pool needed to run as the web user.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="ini" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">; Start a new pool named 'www'.</span>
<span style="color: #666666; font-style: italic;">; the variable $pool can we used in any directive and will be replaced by the</span>
<span style="color: #666666; font-style: italic;">; pool name ('www' here)</span>
<span style="color: #000066; font-weight:bold;"><span style="">&#91;</span>devsites<span style="">&#93;</span></span>
&nbsp;
<span style="color: #666666; font-style: italic;">; Unix user/group of processes</span>
<span style="color: #666666; font-style: italic;">; Note: The user is mandatory. If the group is not set, the default user's group</span>
<span style="color: #666666; font-style: italic;">;       will be used.</span>
<span style="color: #000099;">user</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> www-data</span>
<span style="color: #000099;">group</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> www-data</span>
&nbsp;
<span style="color: #666666; font-style: italic;">; The address on which to accept FastCGI requests.</span>
<span style="color: #666666; font-style: italic;">; Valid syntaxes are:</span>
<span style="color: #666666; font-style: italic;">;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific address on</span>
<span style="color: #666666; font-style: italic;">;                            a specific port;</span>
<span style="color: #666666; font-style: italic;">;   'port'                 - to listen on a TCP socket to all addresses on a</span>
<span style="color: #666666; font-style: italic;">;                            specific port;</span>
<span style="color: #666666; font-style: italic;">;   '/path/to/unix/socket' - to listen on a unix socket.</span>
<span style="color: #666666; font-style: italic;">; Note: This value is mandatory.</span>
<span style="color: #000099;">listen</span> <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> /var/run/fpm-$pool.sock</span>
&nbsp;
<span style="color: #666666; font-style: italic;">; Set permissions for unix socket, if one is used. In Linux, read/write</span>
<span style="color: #666666; font-style: italic;">; permissions must be set in order to allow connections from a web server. Many</span>
<span style="color: #666666; font-style: italic;">; BSD-derived systems allow connections regardless of permissions.</span>
<span style="color: #666666; font-style: italic;">; Default Values: user and group are set as the running user</span>
<span style="color: #666666; font-style: italic;">;                 mode is set to 0666</span>
listen.owner <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> www-data</span>
listen.group <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> www-data</span>
listen.mode <span style="color: #000066; font-weight:bold;">=</span><span style="color: #660066;"> 0666</span></pre></td></tr></table></div>

<p>If you&#8217;ve found this helpful (or troublesome), feel free to drop me a line in the comments below!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.generalthreat.com/2012/11/creating-a-secure-dynamic-env/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Serving the koha-common OPAC with Plack</title>
		<link>http://www.generalthreat.com/2012/09/serving-the-koha-common-opac-with-plack/</link>
		<comments>http://www.generalthreat.com/2012/09/serving-the-koha-common-opac-with-plack/#comments</comments>
		<pubDate>Tue, 25 Sep 2012 18:58:06 +0000</pubDate>
		<dc:creator><![CDATA[David]]></dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[Koha]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://www.generalthreat.com/?p=93</guid>
		<description><![CDATA[If you&#8217;ve set up a Koha instance and been less than impressed with the responsiveness of the OPAC, this post is for you. Thanks to the hard work of the Koha Debian package team,&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[<p>If you&#8217;ve set up a Koha instance and been less than impressed with the responsiveness of the OPAC, this post is for you.</p>
<p>Thanks to the hard work of the Koha Debian package team, it&#8217;s easier than ever to get a functional Koha install up and running. But once you&#8217;ve set up your new instance, you may find the catalog a little sluggish. If you&#8217;ve followed the steps on the <a href="http://wiki.koha-community.org/wiki/Plack">Koha Plack wiki page</a> but found they don&#8217;t work for the koha-common package, here are a few changes that will set things right.</p>
<p>Before we begin, make sure you are running at least Koha 3.8. Earlier versions are not compatible with Plack, so results may be unpredictable.<br />
Also make sure you have installed all Plack dependencies as listed in the Koha wiki.<br />
Finally, it helps to have already created your Koha instance (with <code>koha-create</code>). Whew!</p>
<p>Except where noted, I put these files in a new <code>/usr/share/koha/misc/plack</code> folder. This guide and these code samples assume you will too.</p>
<h2>1. Creating the Koha PSGI wrapper</h2>
<h3>Create <code>koha.psgi</code></h3>
<p>This file is adapted from the example found on the <a href="http://wiki.koha-community.org/wiki/Plack">Koha Plack wiki page</a>. The <code>lib</code> and <code>$root</code> variables have been fixed for koha-common, and a lot of debugging hooks have been removed. The static file paths are correct, but those files should really be served by something leaner like nginx.</p>
<p><ins datetime="2013-01-07T14:17:35+00:00"><strong>Update (1/7/2013):</strong> I&#8217;ve tweaked this file to allow it to be used for serving the Koha staff site as well, since that is supported with Plack as of 3.10. A more complete guide for that is coming soon, so stay tuned!</ins></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="perl" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/usr/bin/perl</span>
<span style="color: #000000; font-weight: bold;">use</span> Plack<span style="color: #339933;">::</span><span style="color: #006600;">Builder</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Plack<span style="color: #339933;">::</span><span style="color: #006600;">App</span><span style="color: #339933;">::</span><span style="color: #006600;">CGIBin</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> Plack<span style="color: #339933;">::</span><span style="color: #006600;">App</span><span style="color: #339933;">::</span><span style="color: #006600;">Directory</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">use</span> lib<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;/usr/share/koha/lib&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> C4<span style="color: #339933;">::</span><span style="color: #006600;">Context</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> C4<span style="color: #339933;">::</span><span style="color: #006600;">Languages</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> C4<span style="color: #339933;">::</span><span style="color: #006600;">Members</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> C4<span style="color: #339933;">::</span><span style="color: #006600;">Dates</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> C4<span style="color: #339933;">::</span><span style="color: #006600;">Boolean</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> C4<span style="color: #339933;">::</span><span style="color: #006600;">Letters</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> C4<span style="color: #339933;">::</span><span style="color: #006600;">Koha</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> C4<span style="color: #339933;">::</span><span style="color: #006600;">XSLT</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> C4<span style="color: #339933;">::</span><span style="color: #006600;">Branch</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">use</span> C4<span style="color: #339933;">::</span><span style="color: #006600;">Category</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$root</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$ENV</span><span style="color: #009900;">&#123;</span>INTRANETDIR<span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span>
                <span style="color: #0000ff;">$ENV</span><span style="color: #009900;">&#123;</span>INTRANETDIR<span style="color: #009900;">&#125;</span> <span style="color: #339933;">.</span> <span style="color: #ff0000;">'/cgi-bin'</span> <span style="color: #339933;">:</span>
                <span style="color: #0000ff;">$ENV</span><span style="color: #009900;">&#123;</span>OPACDIR<span style="color: #009900;">&#125;</span> <span style="color: #339933;">.</span> <span style="color: #ff0000;">'/cgi-bin/opac'</span> <span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$app</span><span style="color: #339933;">=</span>Plack<span style="color: #339933;">::</span><span style="color: #006600;">App</span><span style="color: #339933;">::</span><span style="color: #006600;">CGIBin</span><span style="color: #339933;">-&gt;</span><span style="color: #000000; font-weight: bold;">new</span><span style="color: #009900;">&#40;</span>root <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$root</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
builder <span style="color: #009900;">&#123;</span>
&nbsp;
        mount <span style="color: #ff0000;">&quot;/opac-tmpl&quot;</span>     <span style="color: #339933;">=&gt;</span> Plack<span style="color: #339933;">::</span><span style="color: #006600;">App</span><span style="color: #339933;">::</span><span style="color: #006600;">File</span><span style="color: #339933;">-&gt;</span><span style="color: #000000; font-weight: bold;">new</span><span style="color: #009900;">&#40;</span>root <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">&quot;/usr/share/koha/opac/htdocs/opac-tmpl&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        mount <span style="color: #ff0000;">&quot;/intranet-tmpl&quot;</span> <span style="color: #339933;">=&gt;</span> Plack<span style="color: #339933;">::</span><span style="color: #006600;">App</span><span style="color: #339933;">::</span><span style="color: #006600;">File</span><span style="color: #339933;">-&gt;</span><span style="color: #000000; font-weight: bold;">new</span><span style="color: #009900;">&#40;</span>root <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">&quot;/usr/share/koha/intranet/htdocs/intranet-tmpl&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        mount <span style="color: #ff0000;">&quot;/cgi-bin/koha&quot;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$app</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>As the docs say, at this point you can test the OPAC with plackup. Just replace <code>[YOUR INSTANCE NAME]</code> with your instance name in the following and give it a shot.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;OPACDIR=/usr/share/koha/opac/ <span style="color: #000099; font-weight: bold;">\
</span>	KOHA_CONF=/etc/koha/sites/SITE/koha-conf.xml <span style="color: #000099; font-weight: bold;">\
</span>	sudo -u SITE-koha -E plackup --reload /usr/share/koha/misc/plack/koha.psgi&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> \
	<span style="color: #c20cb9; font-weight: bold;">sed</span> s<span style="color: #000000; font-weight: bold;">/</span>SITE<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">&#91;</span>YOUR INSTANCE NAME<span style="color: #7a0874; font-weight: bold;">&#93;</span><span style="color: #000000; font-weight: bold;">/</span>g <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sh</span></pre></td></tr></table></div>

<p>Open your web browser of choice and visit <code>http://[YOUR SERVER IP]:5000/cgi-bin/koha/opac-main.pl</code>.</p>
<p><strong>Congratulations!</strong> You have a working OPAC running over twice as fast as it was just moments ago.</p>
<p>For production use, you&#8217;ll want to set up a more stable application server. The rest of this article will guide you through making your new OPAC a permanent part of your Koha install by setting up a Starman server and running it through koha-common&#8217;s control systems. </p>
<p>To continue, press <code>Ctrl + C</code> to break out of plackup.</p>
<h2>2. Serving the OPAC with Starman</h2>
<h3>Create <code>opac-plack.sh</code></h3>
<p>This was adapted from the <code>opac-plack.sh</code> example posted <a href="http://lists.koha-community.org/pipermail/koha-patches/2012-March/016881.html">on the patches mailing list</a>. Create it in your <code>/usr/share/koha/misc/plack</code> directory.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh -xe</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">test</span> <span style="color: #000000; font-weight: bold;">!</span> <span style="color: #660033;">-z</span> <span style="color: #ff0000;">&quot;$1&quot;</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #007800;">site</span>=<span style="color: #007800;">$1</span> <span style="color: #000000; font-weight: bold;">&amp;&amp;</span> <span style="color: #7a0874; font-weight: bold;">shift</span>
<span style="color: #007800;">dir</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">dirname</span> <span style="color: #007800;">$0</span><span style="color: #000000; font-weight: bold;">`</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">KOHA_CONF</span>=<span style="color: #000000; font-weight: bold;">/</span>etc<span style="color: #000000; font-weight: bold;">/</span>koha<span style="color: #000000; font-weight: bold;">/</span>sites<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$site</span><span style="color: #000000; font-weight: bold;">/</span>koha-conf.xml
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">OPACDIR</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$( xmlstarlet sel -t -v 'yazgfs/config/opacdir' $KOHA_CONF | sed 's,/cgi-bin/opac,,' )</span>&quot;</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">LOGDIR</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$( xmlstarlet sel -t -v 'yazgfs/config/logdir' $KOHA_CONF )</span>&quot;</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">MEMCACHED_SERVERS</span>=localhost:<span style="color: #000000;">11211</span>
<span style="color: #7a0874; font-weight: bold;">export</span> <span style="color: #007800;">MEMCACHED_NAMESPACE</span>=<span style="color: #007800;">$site</span>
&nbsp;
<span style="color: #007800;">PIDFILE</span>=<span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>run<span style="color: #000000; font-weight: bold;">/</span>koha<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$site</span><span style="color: #000000; font-weight: bold;">/</span>plack.pid
&nbsp;
<span style="color: #666666; font-style: italic;"># Use one of these lines to choose between TCP port and UNIX socket listeners</span>
<span style="color: #666666; font-style: italic;">#SOCKET=/var/run/koha/$site/plack.sock</span>
<span style="color: #007800;">PORT</span>=<span style="color: #000000;">5000</span>
&nbsp;
<span style="color: #007800;">opt</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$opt</span> --access-log <span style="color: #007800;">$LOGDIR</span>/opac-access.log --error-log <span style="color: #007800;">$LOGDIR</span>/opac-error.log&quot;</span>
<span style="color: #007800;">opt</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$opt</span> -M FindBin --max-requests 50 --workers 2 -E deployment&quot;</span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$SOCKET</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #007800;">opt</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$opt</span> --listen <span style="color: #007800;">$SOCKET</span> -D --pid <span style="color: #007800;">$PIDFILE</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">elif</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$PORT</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #007800;">opt</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$opt</span> --port <span style="color: #007800;">$PORT</span> -D --pid <span style="color: #007800;">$PIDFILE</span>&quot;</span>
<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>starman <span style="color: #007800;">$opt</span> <span style="color: #007800;">$dir</span><span style="color: #000000; font-weight: bold;">/</span>koha.psgi</pre></td></tr></table></div>

<p>Make the script executable with: <code>chmod +x opac-plack.sh</code></p>
<p>Also be sure to make note of the port (or socket file path) in this file, since that&#8217;s how you&#8217;ll access the OPAC.</p>
<p>You may have noticed that the <code>opac-plack.sh</code> file takes an argument not present in the original. That&#8217;s because we&#8217;re going to control it with koha-common&#8217;s startup infrastructure.</p>
<h2>3. Controlling the OPAC server</h2>
<p>First we need to create startup and shutdown scripts for Plack.</p>
<h3>Create <code>/usr/sbin/koha-start-plack</code></h3>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># koha-start-plack -- Start Plack processes for named Koha instances</span>
<span style="color: #666666; font-style: italic;">#</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">set</span> <span style="color: #660033;">-e</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">for</span> name <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #ff0000;">&quot;$@&quot;</span>
<span style="color: #000000; font-weight: bold;">do</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Starting Plack server for <span style="color: #007800;">$name</span>&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">exec</span> start-stop-daemon \
        <span style="color: #660033;">--start</span> \
        <span style="color: #660033;">--chuid</span> <span style="color: #007800;">$name</span>-koha \
        <span style="color: #660033;">--exec</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>share<span style="color: #000000; font-weight: bold;">/</span>koha<span style="color: #000000; font-weight: bold;">/</span>misc<span style="color: #000000; font-weight: bold;">/</span>plack<span style="color: #000000; font-weight: bold;">/</span>opac-plack.sh <span style="color: #660033;">--</span> <span style="color: #007800;">$name</span>
<span style="color: #000000; font-weight: bold;">done</span></pre></td></tr></table></div>

<h3>Create <code>/usr/sbin/koha-stop-plack</code></h3>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/sh</span>
<span style="color: #666666; font-style: italic;">#</span>
<span style="color: #666666; font-style: italic;"># koha-stop-plack -- Stop Plack processes for named Koha instances</span>
<span style="color: #666666; font-style: italic;">#</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">set</span> <span style="color: #660033;">-e</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">for</span> name <span style="color: #000000; font-weight: bold;">in</span> <span style="color: #ff0000;">&quot;$@&quot;</span>
<span style="color: #000000; font-weight: bold;">do</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Stopping Plack server for <span style="color: #007800;">$name</span>&quot;</span>
    <span style="color: #7a0874; font-weight: bold;">exec</span> start-stop-daemon \
        <span style="color: #660033;">--stop</span> \
        <span style="color: #660033;">--pidfile</span> <span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>run<span style="color: #000000; font-weight: bold;">/</span>koha<span style="color: #000000; font-weight: bold;">/</span><span style="color: #007800;">$name</span><span style="color: #000000; font-weight: bold;">/</span>plack.pid
<span style="color: #000000; font-weight: bold;">done</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;Servers stopped&quot;</span></pre></td></tr></table></div>

<p>Be sure to make these scripts executable when you&#8217;re finished!</p>
<h2>4. Preparing for lanch</h2>
<p>Now we update the koha-common init script to start and stop the Plack servers along with the rest of our Koha infrastructure.</p>
<h3>Edit <code>/etc/init.d/koha-common</code></h3>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
</pre></td><td class="code"><pre class="diff" style="font-family:monospace;">do_start<span style="">&#40;</span><span style="">&#41;</span>
<span style="">&#123;</span>
    # We insure all required directories exist, including disabled ones.
    koha-create-dirs $<span style="">&#40;</span>koha-list<span style="">&#41;</span>
    koha-start-zebra $<span style="">&#40;</span>koha-list --enabled<span style="">&#41;</span>
<span style="color: #00b000;">+    koha-start-plack $<span style="">&#40;</span>koha-list --enabled<span style="">&#41;</span></span>
<span style="">&#125;</span>
&nbsp;
#
# Function that stops the daemon/service
#
do_stop<span style="">&#40;</span><span style="">&#41;</span>
<span style="">&#123;</span>
    # We stop everything, including disabled ones.
    koha-stop-zebra $<span style="">&#40;</span>koha-list<span style="">&#41;</span> || true
<span style="color: #00b000;">+    koha-stop-plack $<span style="">&#40;</span>koha-list<span style="">&#41;</span> || true</span>
<span style="">&#125;</span></pre></td></tr></table></div>

<h3>Restart koha-common</h3>
<p>Now you are ready to put your OPAC into service. Restart your koha-common services with:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="bash" style="font-family:monospace;">service koha-common stop
service koha-common start</pre></td></tr></table></div>

<p><strong>That&#8217;s it!</strong> Your Plack OPAC will now start with your server each time it is restarted, or each time you start and stop the koha-common services. You can also use the <code>koha-[start|stop]-plack</code> scripts to control your OPAC manually, if needed.</p>
<p>Drop me a line in the comments if you have questions or suggestions, or if this article has helped you get the most from your Koha install!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.generalthreat.com/2012/09/serving-the-koha-common-opac-with-plack/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extending BuddyPress Group Hierarchy &#8211; Adding Breadcrumbs to Your Theme</title>
		<link>http://www.generalthreat.com/2012/04/extending-buddypress-group-hierarchy-adding-breadcrumbs-to-your-theme/</link>
		<comments>http://www.generalthreat.com/2012/04/extending-buddypress-group-hierarchy-adding-breadcrumbs-to-your-theme/#comments</comments>
		<pubDate>Wed, 04 Apr 2012 17:49:34 +0000</pubDate>
		<dc:creator><![CDATA[David]]></dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[buddypress]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.generalthreat.com/?p=87</guid>
		<description><![CDATA[Once you&#8217;ve created a hierarchy of BuddyPress groups, you can help your users navigate and give your site the professional touch by including group breadcrumbs where appropriate. Here&#8217;s how! Step One: Change the link&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[<p>Once you&#8217;ve created a hierarchy of BuddyPress groups, you can help your users navigate and give your site the professional touch by including group breadcrumbs where appropriate. Here&#8217;s how!</p>
<h3>Step One: Change the link at the top of every group page to a trail of links to parent groups</h3>
<p>This is the easy part! BuddyPress Group Hierarchy includes a function, <code>bp_group_hierarchy_breadcrumbs()</code>, that will generate a string of links to a group and all its parents. Use it in the Groups loop, and no parameter is required. </p>
<p><strong>Note:</strong> If you need to pass in a different group for some reason, you&#8217;ll need to use <code>bp_group_hierarchy_get_breadcrumbs( $separator = '|', $group = false )</code> function and echo the result yourself. This tutorial won&#8217;t address using that more advanced function.</p>
<p>Just locate your theme&#8217;s <code>groups/single/group-header.php</code> file, and find the current group header which will look something like this:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">&lt;h2&gt;&lt;a href=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_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; title=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_name<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;&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_name<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>&lt;/a&gt;&lt;/h2&gt;</pre></td></tr></table></div>

<p>Replace it with this simple line:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">&lt;h2&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_hierarchy_breadcrumbs<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/h2&gt;</pre></td></tr></table></div>

<h3>Step Two: Change the page title on group pages to reflect your group structure</h3>
<p>Changing the page title is more complicated. BuddyPress builds its page titles with a function hooked to the <code>wp_title</code> filter. This function in turn presents its own filter, and that&#8217;s the one we have to hook to put breadcrumbs in the title of our Group page. This makes sure our filtering function runs only when BuddyPress is enabled and on as few pages as necessary.</p>
<p>If you zoned out during that bit, don&#8217;t worry! Just place the code below into your theme&#8217;s <code>functions.php</code> file.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">add_filter<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_modify_page_title'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'my_func_group_breadcrumbs'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">4</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> my_func_group_breadcrumbs<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$processed_title</span><span style="color: #339933;">,</span> <span style="color: #000088;">$title</span><span style="color: #339933;">,</span> <span style="color: #000088;">$sep</span><span style="color: #339933;">,</span> <span style="color: #000088;">$seplocation</span>  <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$bp</span><span style="color: #339933;">;</span>
&nbsp;
 	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> bp_is_active<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'groups'</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span> <span style="color: #990000;">empty</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$bp</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">groups</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">current_group</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$processed_title</span> <span style="color: #339933;">=</span> <span style="color: #990000;">substr</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$processed_title</span><span style="color: #339933;">,</span> <span style="color: #990000;">strpos</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$processed_title</span><span style="color: #339933;">,</span> <span style="color: #000088;">$sep</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #000088;">$processed_title</span> <span style="color: #339933;">=</span> bp_group_hierarchy_get_full_name<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'|'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$bp</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">groups</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">current_group</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">' '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$processed_title</span><span style="color: #339933;">;</span>
 	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$processed_title</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>This function strips the group name from the page title, but re-adds the names of the group and all its ancestors. The <code>bp_group_hierarchy_get_full_name</code> function works like the <code>bp_group_hierarchy_get_breadcrumbs</code> function I mentioned earlier, but it builds a plain text list instead of a list of links.</p>
<p>That&#8217;s it!  Check back soon for a reference child theme, implementing this technique. As always, if you have any questions or problems adding this to your site, or if you have a novel implementation you&#8217;d like to share, please post in the comments below!</p>
<p><ins datetime="2012-04-06T15:02:01+00:00"><strong>Update:</strong> As promised, here is the sample child theme! <a href="http://www.generalthreat.com/downloads/GroupBreadcrumbs.zip" title="Download BuddyPress Group Hierarchy Breadcrumbs - Sample Theme">BuddyPress Group Hierarchy Breadcrumbs - Sample Theme</a></ins></p>
]]></content:encoded>
			<wfw:commentRss>http://www.generalthreat.com/2012/04/extending-buddypress-group-hierarchy-adding-breadcrumbs-to-your-theme/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Adding Externally-Authenticated Users to BuddyPress</title>
		<link>http://www.generalthreat.com/2012/02/adding-externally-authenticated-users-to-buddypress/</link>
		<comments>http://www.generalthreat.com/2012/02/adding-externally-authenticated-users-to-buddypress/#comments</comments>
		<pubDate>Wed, 29 Feb 2012 01:49:26 +0000</pubDate>
		<dc:creator><![CDATA[David]]></dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[buddypress]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.generalthreat.com/?p=85</guid>
		<description><![CDATA[BuddyPress does a great job integrating new users who register through your WordPress site into the community &#8212; optionally synchronizing profile information between BP and WP, and creating an activity feed item for new&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[<p>BuddyPress does a great job integrating new users who register through your WordPress site into the community &mdash; optionally synchronizing profile information between BP and WP, and creating an activity feed item for new user signups.</p>
<p>But what about users who login against an external authentication provider, and whose accounts are created and managed by such a system? Today we&#8217;re going to look at how to bring those users into the community in the same way as those who registered locally. Be warned &mdash; this is a fairly dense piece, especially if you haven&#8217;t worked with an <code>authenticate</code> filter before.</p>
<h3>A crash course on <code>authenticate</code></h3>
<p>If you are using (or writing) an external authentication plugin, you&#8217;ll need a function hooked to the <code>authenticate</code> filter. This function is where your plugin gets a chance to authenticate users against your outside system. It is also where your users will have subordinate WordPress accounts made and managed by the external system.</p>
<p>A very quick example:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> my_func_to_authenticate<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$user</span><span style="color: #339933;">,</span> <span style="color: #000088;">$username</span><span style="color: #339933;">,</span> <span style="color: #000088;">$password</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
 <span style="color: #666666; font-style: italic;">// if $user is a valid WP_User, authenticated by an upstream filter</span>
 <span style="color: #666666; font-style: italic;">// pass these params to the external auth source for verification</span>
 <span style="color: #666666; font-style: italic;">// proceed if user is logged in, otherwise return a WP_Error</span>
<span style="color: #009900;">&#125;</span>
add_filter<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'authenticate'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'my_func_to_authenticate'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">3</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h3>The first login</h3>
<p>The first time your users log in to your WordPress install using their external credentials, you&#8217;ll probably want to create a WP account for them. You may skip this if you&#8217;re just trying to restrict read access, but this is about BuddyPress, so I&#8217;m assuming you want them to post and contribute to the site. <img src="http://www.generalthreat.com/wordpress/wp-includes/images/smilies/simple-smile.png" alt=":)" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>Here&#8217;s a rundown of the process:</p>
<ol>
<li>Suppress the BuddyPress activation email</li>
<li>Create WP user account</li>
<li>Update user meta and, optionally, xprofile data</li>
<li>Activate user and set proper <code>display_name</code></li>
<li>Publish activity stream message about new user, with properly-formatted display name</li>
</ol>
<h4>Suppress the BuddyPress activation email</h4>
<p>These users are already verified by virtue of being in our external auth system, so an activation email would just be confusing.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #009933; font-style: italic;">/** Suppress activation key email for users logging in with external auth */</span>
add_filter<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_core_signup_send_activation_key'</span><span style="color: #339933;">,</span> <span style="color: #990000;">create_function</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">''</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'return false;'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h4>Create WordPress user account</h4>
<p>Normally, you&#8217;d use <code><a href="http://codex.wordpress.org/Function_Reference/wp_create_user">wp_create_user</a></code> (or <code><a href="http://codex.wordpress.org/Function_Reference/wp_insert_user">wp_insert_user</a></code> if you want access to the full set of user properties).<br />
But BuddyPress comes with a wrapper function that can be used to do a lot of the heavy lifting for us.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$new_user</span> <span style="color: #339933;">=</span> bp_core_signup_user<span style="color: #009900;">&#40;</span>
	<span style="color: #000088;">$user_login</span><span style="color: #339933;">,</span>
	<span style="color: #000088;">$user_password</span><span style="color: #339933;">,</span>
	<span style="color: #000088;">$user_email</span><span style="color: #339933;">,</span>
	<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</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> is_wp_error<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<h4>Update user meta and, optionally, xprofile data</h4>
<p>There are actually a few ways to handle this, ranging from bull-in-a-china-shop overwriting to graceful but more complicated filtering. Which one you choose may depend on your comfort with WP or PHP, which BuddyPress features you have enabled, or the structure of your authentication script.</p>
<p><div class='postTabs_divs postTabs_curr_div' id='postTabs_0_85'>
<span class='postTabs_titles'><b>Easiest</b></span></p>
<h5>Easiest</h5>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$display_name</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$first_name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">' '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$last_name</span><span style="color: #339933;">;</span>
&nbsp;
update_user_meta<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'nickname'</span><span style="color: #339933;">,</span>   <span style="color: #000088;">$display_name</span>  <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
update_user_meta<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'first_name'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$first_name</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
update_user_meta<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'last_name'</span><span style="color: #339933;">,</span>  <span style="color: #000088;">$last_name</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> bp_is_active<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'xprofile'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
	xprofile_set_field_data<span style="color: #009900;">&#40;</span> bp_xprofile_fullname_field_name<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">,</span> <span style="color: #000088;">$display_name</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Even though setting the xprofile value, above, should take care of this, </span>
<span style="color: #666666; font-style: italic;">// testing revealed that we needed to prime the cache with the right value</span>
wp_cache_set<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_user_fullname_'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">,</span> <span style="color: #000088;">$display_name</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'bp'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>PROS: </p>
<ul>
<li>Very straightforward and procedural &mdash; no objects or data sharing needed</li>
<li>Complete control over format of display_name and BP fullname field</li>
<li>Control over any other BP xprofile values you want to set</li>
<li>Does not require xprofile or WP-BP profile sync in order to operate</li>
</ul>
<p>CONS:</p>
<ul>
<li>Will ultimately drift out of sync with BP development</li>
<li>Still need to set the display_name property below</li>
<li>Might as well use <code>wp_insert_user</code>, since we&#8217;re manually adding so much</li>
</ul>
<p></div>

<div class='postTabs_divs' id='postTabs_1_85'>
<span class='postTabs_titles'><b>Shortest</b></span></p>
<h5>Shortest</h5>
<p>Replace the <code>bp_core_signup_user</code> call above with this:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$new_user</span> <span style="color: #339933;">=</span> bp_core_signup_user<span style="color: #009900;">&#40;</span>
	<span style="color: #000088;">$login_name</span><span style="color: #339933;">,</span>
	<span style="color: #000088;">$password</span><span style="color: #339933;">,</span>
	<span style="color: #000088;">$email</span><span style="color: #339933;">,</span>
	<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
		<span style="color: #0000ff;">'profile_field_ids'</span> <span style="color: #339933;">=&gt;</span> bp_xprofile_fullname_field_name<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">&quot;field_{bp_xprofile_fullname_field_name()}&quot;</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$display_name</span>
	<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>PROS: </p>
<ul>
<li>Uses BP to eliminate the need for additional filters or processing</li>
<li>Least code redundancy of all</li>
<li>Can supply additional xprofile fields to be added to the new user</li>
<li>Most natural method in terms of program flow</li>
</ul>
<p>CONS:</p>
<ul>
<li>Complex meta parameter structure can be difficult to read</li>
<li>Parameter or data structure may change in future BP releases</li>
<li>Requires xprofile and WP-BP profile sync to update WP display_name and usermeta</li>
</ul>
<p></div>

<div class='postTabs_divs' id='postTabs_2_85'>
<span class='postTabs_titles'><b>Fanciest</b></span></p>
<h5>Fanciest</h5>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> my_display_name_filter<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$user_id</span><span style="color: #339933;">,</span> <span style="color: #000088;">$user_login</span><span style="color: #339933;">,</span> <span style="color: #000088;">$user_password</span><span style="color: #339933;">,</span> <span style="color: #000088;">$user_email</span><span style="color: #339933;">,</span> <span style="color: #000088;">$usermeta</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// must get $display_name from another part of the authentication process</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> bp_is_active<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'xprofile'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		xprofile_set_field_data<span style="color: #009900;">&#40;</span> bp_xprofile_fullname_field_name<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">,</span> <span style="color: #000088;">$display_name</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Change your authenticate function to look like this:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> my_func_to_authenticate<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$user</span><span style="color: #339933;">,</span> <span style="color: #000088;">$username</span><span style="color: #339933;">,</span> <span style="color: #000088;">$password</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// ... authenticate user</span>
	add_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_core_signup_user'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'my_display_name_filter'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">9</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">5</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$new_user</span> <span style="color: #339933;">=</span> bp_core_signup_user<span style="color: #009900;">&#40;</span>
		<span style="color: #000088;">$login_name</span><span style="color: #339933;">,</span>
		<span style="color: #000088;">$password</span><span style="color: #339933;">,</span>
		<span style="color: #000088;">$email</span><span style="color: #339933;">,</span>
		<span style="color: #990000;">array</span><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: #009900;">&#125;</span></pre></td></tr></table></div>

<p>PROS: </p>
<ul>
<li>Uses BP filters for forward compatibility</li>
<li>Reduces the amount of repeated code</li>
</ul>
<p>CONS:</p>
<ul>
<li>Requires an object or data-sharing infrastructure to get user details to the filter</li>
<li>Requires xprofile and WP-BP profile sync to  update WP display_name and usermeta</li>
</ul>
<p></div>

</p>
<hr />
Now that the xprofile and usermeta data are set up, it&#8217;s time to activate the user! This is done by simply setting the <code>user_status</code> column to <code>0</code>.</p>
<h4>Activate user (and set proper display_name, if needed)</h4>
<p><ins datetime="2012-08-06T23:43:09+00:00"><strong>Update 08-06-2012:</strong> I used to recommend <code>wp_update_user</code> for this, but that has proven unreliable on a recent project. So to be safe, just use a direct query.</ins></p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// activate user and set display name appropriately</span>
<span style="color: #000088;">$wpdb</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$wpdb</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">prepare</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;UPDATE <span style="color: #006699; font-weight: bold;">$wpdb-&gt;users</span> SET display_name=<span style="color: #009933; font-weight: bold;">%s</span>, user_status=0 WHERE ID=<span style="color: #009933; font-weight: bold;">%d</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$display_name</span><span style="color: #339933;">,</span> <span style="color: #000088;">$new_user</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>And if you set <code>$display_name</code> above, use the shortened version:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// activate user</span>
<span style="color: #000088;">$wpdb</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$wpdb</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">prepare</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;UPDATE <span style="color: #006699; font-weight: bold;">$wpdb-&gt;users</span> SET user_status=0 WHERE ID=<span style="color: #009933; font-weight: bold;">%d</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$new_user</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h4>Publish an activity stream message about the new user and notify the site admin</h4>
<p>Since the display_name property and associated xprofile field are finally set the way we want them, it&#8217;s time to trigger the activity stream message and administrator notification.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">bp_core_new_user_activity<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
wp_new_user_notification<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h4>And you&#8217;re done!</h4>
<p>Return a <code>WP_User</code> object to let other authentication filters know you&#8217;ve handled this user.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">new</span> WP_User<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h3>A complete example</h3>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> my_func_to_authenticate<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$user</span><span style="color: #339933;">,</span> <span style="color: #000088;">$username</span><span style="color: #339933;">,</span> <span style="color: #000088;">$password</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #666666; font-style: italic;">// if $user is a valid WP_User, authenticated by an upstream filter</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #990000;">is_a</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$user</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'WP_User'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #b1b100;">return</span> <span style="color: #000088;">$user</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// pass these params to the external auth source for verification</span>
	<span style="color: #666666; font-style: italic;">// proceed if user is logged in, otherwise return a WP_Error</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$user_details</span> <span style="color: #339933;">=</span> my_external_auth<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$username</span><span style="color: #339933;">,</span> <span style="color: #000088;">$password</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// for simplicity's sake, I'm assuming that $user_details is an array with all the right keys</span>
		<span style="color: #666666; font-style: italic;">// in practice, more checks would be required</span>
		<span style="color: #990000;">extract</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$user_details</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// this function returns the new user account ID if successful</span>
		<span style="color: #000088;">$new_user</span> <span style="color: #339933;">=</span> bp_core_signup_user<span style="color: #009900;">&#40;</span>
			<span style="color: #000088;">$username</span><span style="color: #339933;">,</span>
			<span style="color: #000088;">$password</span><span style="color: #339933;">,</span>
			<span style="color: #000088;">$user_email</span><span style="color: #339933;">,</span>
			<span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// If signup returned an error, skip the rest</span>
		<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span> is_wp_error<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #b1b100;">return</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
&nbsp;
		<span style="color: #000088;">$display_name</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$first_name</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">' '</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$last_name</span><span style="color: #339933;">;</span>
&nbsp;
		update_user_meta<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'nickname'</span><span style="color: #339933;">,</span>   <span style="color: #000088;">$display_name</span>  <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		update_user_meta<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'first_name'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$first_name</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		update_user_meta<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'last_name'</span><span style="color: #339933;">,</span>  <span style="color: #000088;">$last_name</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> bp_is_active<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'xprofile'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
			xprofile_set_field_data<span style="color: #009900;">&#40;</span> bp_xprofile_fullname_field_name<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">,</span> <span style="color: #000088;">$display_name</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// Even though setting the xprofile value, above, should take care of this, </span>
		<span style="color: #666666; font-style: italic;">// testing revealed that we needed to prime the cache with the right value</span>
		wp_cache_set<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_user_fullname_'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$new_user</span><span style="color: #339933;">,</span> <span style="color: #000088;">$display_name</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'bp'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #666666; font-style: italic;">// activate user and set display name appropriately</span>
		<span style="color: #000088;">$wpdb</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span> <span style="color: #000088;">$wpdb</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">prepare</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">&quot;UPDATE <span style="color: #006699; font-weight: bold;">$wpdb-&gt;users</span> SET display_name=<span style="color: #009933; font-weight: bold;">%s</span>, user_status=0 WHERE ID=<span style="color: #009933; font-weight: bold;">%d</span>&quot;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$display_name</span><span style="color: #339933;">,</span> <span style="color: #000088;">$new_user</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		bp_core_new_user_activity<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		wp_new_user_notification<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">new</span> WP_User<span style="color: #009900;">&#40;</span> <span style="color: #000088;">$new_user</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #666666; font-style: italic;">// you can return FALSE, or a WP_Error if you have something specific to say</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000000; font-weight: bold;">new</span> WP_Error<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'login_failed'</span><span style="color: #339933;">,</span> __<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'Could not authenticate user'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
add_filter<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'authenticate'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'my_func_to_authenticate'</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">10</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">3</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>If you have questions, or if you put this to use in your next project, feel free to drop me a line in the comments!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.generalthreat.com/2012/02/adding-externally-authenticated-users-to-buddypress/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Extending BuddyPress Group Hierarchy &#8211; Creating a Member Groups list</title>
		<link>http://www.generalthreat.com/2012/01/extending-buddypress-group-hierarchy-list-member-groups/</link>
		<comments>http://www.generalthreat.com/2012/01/extending-buddypress-group-hierarchy-list-member-groups/#comments</comments>
		<pubDate>Sun, 29 Jan 2012 19:44:39 +0000</pubDate>
		<dc:creator><![CDATA[David]]></dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[buddypress]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.generalthreat.com/?p=82</guid>
		<description><![CDATA[In this post, I&#8217;m going to show you how to create a Member Groups page/list/widget, with a little background on how Group Hierarchy extends the BuddyPress Groups loop. BuddyPress Groups loop overview If you&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[<p>In this post, I&#8217;m going to show you how to create a Member Groups page/list/widget, with a little background on how Group Hierarchy extends the BuddyPress Groups loop.</p>
<h2>BuddyPress Groups loop overview</h2>
<p>If you aren&#8217;t familiar with <code>bp_has_groups()</code> from looking at the BuddyPress theme files, you should take a look at <a href="http://codex.buddypress.org/developer-docs/custom-buddypress-loops/the-groups-loop/">this overview</a> from the BP Codex before continuing.</p>
<p>In a nutshell, <code>bp_has_groups()</code> accepts a series of parameters which it uses to populate the global <code>$groups_template</code> variable with a set of groups. This, in turn, allows all the cool template functions to work without parameters cluttering up your theme file.</p>
<h2>How Group Hierarchy changes the Loop</h2>
<p>BuddyPress Group Hierarchy changes this in two important ways:</p>
<ol>
<li><code>bp_has_groups()</code> creates a set of <code>BP_Groups_Hierarchy</code> objects instead of <code>BP_Groups_Group</code> objects</li>
<li><code>bp_has_groups_hierarchy()</code> extends the loop with a <code>parent_id</code> parameter for getting only child groups of the passed group ID</li>
</ol>
<p>There are more changes made just for the Group Tree, but that&#8217;s enough to get us started. Onward!</p>
<h2>Creating a Member Groups list</h2>
<p>Before we build our Member Groups page / widget / list, there&#8217;s something you should know about working &#8220;in the loop,&#8221; i.e. in the context of the current group. The only thing telling BuddyPress what group we&#8217;re looking at is the <code>$groups_template</code> variable introduced above. Our member group list is going to change that variable, so we need to save its current state and restore it when we&#8217;re done.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// If you're in a function, bring $groups_template into scope</span>
<span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$groups_template</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Save the current group context for later</span>
<span style="color: #000088;">$current_group_template</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$groups_template</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Using the Codex article I posted at the top as a reference, you&#8217;ll see how easy it is to create a Member Groups page / widget / whatever.</p>
<p>Just replace:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> bp_has_groups<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></pre></td></tr></table></div>

<p>with:</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> bp_has_groups_hierarchy<span style="color: #009900;">&#40;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> 
	<span style="color: #0000ff;">'type'</span>      <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'alphabetical'</span><span style="color: #339933;">,</span>
	<span style="color: #0000ff;">'parent_id'</span> <span style="color: #339933;">=&gt;</span> bp_get_current_group_id<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> 
<span style="color: #009900;">&#41;</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></pre></td></tr></table></div>

<p>&#8230;and the rest works as is! Since 1.3.0, pagination is handled automatically.</p>
<p>Don&#8217;t forget to restore the original context!</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000088;">$groups_template</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$current_group_template</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<h2>A complete example</h2>
<p>Here&#8217;s a quick example that adds a list of Member Groups on the Members page, above the list of users. Drop this in your <code>functions.php</code> file, or in a custom plugin, but note that it will only display if the parent group has at least one member!</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
add_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_before_group_members_content'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'my_func_list_member_groups'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> my_func_list_member_groups<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;">// If you're in a function, bring $groups_template into scope</span>
	<span style="color: #000000; font-weight: bold;">global</span> <span style="color: #000088;">$groups_template</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Save the current group context for later</span>
	<span style="color: #000088;">$current_group_template</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$groups_template</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> bp_has_groups_hierarchy<span style="color: #009900;">&#40;</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> 
		<span style="color: #0000ff;">'type'</span>      <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'alphabetical'</span><span style="color: #339933;">,</span>
		<span style="color: #0000ff;">'parent_id'</span> <span style="color: #339933;">=&gt;</span> bp_get_current_group_id<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
	<span style="color: #009900;">&#41;</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;
	&lt;h3&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> _e<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'Member Groups'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;br /&gt;&amp;nbsp;&lt;/h3&gt;
&nbsp;
	&lt;div class=&quot;pagination&quot;&gt;
&nbsp;
		&lt;div class=&quot;pag-count&quot; id=&quot;group-dir-count&quot;&gt;
			<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_groups_pagination_count<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
		&lt;/div&gt;
&nbsp;
		&lt;div class=&quot;pagination-links&quot; id=&quot;group-dir-pag&quot;&gt;
			<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_groups_pagination_links<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
		&lt;/div&gt;
&nbsp;
	&lt;/div&gt;
&nbsp;
	&lt;ul id=&quot;groups-list&quot; class=&quot;item-list&quot;&gt;
	<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span> bp_groups<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> bp_the_group<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;
		&lt;li&gt;
			&lt;div class=&quot;item-avatar&quot;&gt;
				&lt;a href=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_permalink<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_avatar<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'type=thumb&amp;width=50&amp;height=50'</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/a&gt;
			&lt;/div&gt;
&nbsp;
			&lt;div class=&quot;item&quot;&gt;
				&lt;div class=&quot;item-title&quot;&gt;&lt;a href=&quot;<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_permalink<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&quot;&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_name<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/a&gt;&lt;/div&gt;
				&lt;div class=&quot;item-meta&quot;&gt;&lt;span class=&quot;activity&quot;&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #990000;">printf</span><span style="color: #009900;">&#40;</span> __<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'active %s ago'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'buddypress'</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> bp_get_group_last_active<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/span&gt;&lt;/div&gt;
&nbsp;
				&lt;div class=&quot;item-desc&quot;&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_description_excerpt<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/div&gt;
&nbsp;
				<span style="color: #000000; font-weight: bold;">&lt;?php</span> do_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_directory_groups_item'</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
				&lt;/div&gt;
&nbsp;
			&lt;div class=&quot;action&quot;&gt;
				<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_join_button<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
				&lt;div class=&quot;meta&quot;&gt;
					<span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_type<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span> / <span style="color: #000000; font-weight: bold;">&lt;?php</span> bp_group_member_count<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
				&lt;/div&gt;
&nbsp;
				<span style="color: #000000; font-weight: bold;">&lt;?php</span> do_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_directory_groups_actions'</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
			&lt;/div&gt;
&nbsp;
			&lt;div class=&quot;clear&quot;&gt;&lt;/div&gt;
		&lt;/li&gt;
&nbsp;
	<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endwhile</span><span style="color: #339933;">;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
	&lt;/ul&gt;
&nbsp;
		<span style="color: #000000; font-weight: bold;">&lt;?php</span> do_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'bp_after_member_groups_loop'</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">else</span><span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>
&nbsp;
		&lt;div id=&quot;message&quot; class=&quot;info&quot;&gt;
		&lt;p&gt;<span style="color: #000000; font-weight: bold;">&lt;?php</span> _e<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'There were no member groups found.'</span> <span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">?&gt;</span>&lt;/p&gt;
		&lt;/div&gt;
&nbsp;
	<span style="color: #000000; font-weight: bold;">&lt;?php</span> <span style="color: #b1b100;">endif</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// restore original group context!</span>
	<span style="color: #000088;">$groups_template</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$current_group_template</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>That&#8217;s it! Drop me a line in the comments if you find a novel use for this technique.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.generalthreat.com/2012/01/extending-buddypress-group-hierarchy-list-member-groups/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Highlighting Features with WordPress Admin Pointers &#8211; A Quick Guide for Plugin Authors</title>
		<link>http://www.generalthreat.com/2012/01/highlighting-features-with-wordpress-admin-pointers/</link>
		<comments>http://www.generalthreat.com/2012/01/highlighting-features-with-wordpress-admin-pointers/#comments</comments>
		<pubDate>Mon, 02 Jan 2012 05:24:12 +0000</pubDate>
		<dc:creator><![CDATA[David]]></dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>

		<guid isPermaLink="false">http://www.generalthreat.com/?p=80</guid>
		<description><![CDATA[Here&#8217;s a quick intro to admin pointers for plugins to WordPress 3.3+, based on some work I recently put into making the help system in Networks more intuitive: Step One &#8212; Add the admin&#46;&#46;&#46;]]></description>
				<content:encoded><![CDATA[<p>Here&#8217;s a quick intro to admin pointers for plugins to WordPress 3.3+, based on some work I recently put into making the help system in <a href="http://wordpress.org/extend/plugins/networks-for-wordpress/" title="Networks for WordPress">Networks</a> more intuitive:</p>
<h3>Step One &mdash; Add the admin pointer style and script to your page</h3>
<p>This is a fairly standard chain of <code>admin_menu</code> action functions, which should look familiar if you&#8217;re using a class for your plugin. If they don&#8217;t, some <a href="http://codex.wordpress.org/Administration_Menus">light background reading</a> may be in order.</p>
<p>You&#8217;ll need to create a script file for your admin page to follow this guide, although you could also dump the required JavaScript into the admin page itself.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;">&nbsp;
<span style="color: #000000; font-weight: bold;">function</span> admin_menu<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_page</span> <span style="color: #339933;">=</span> add_menu_page<span style="color: #009900;">&#40;</span> __<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'My Page'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> __<span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'My Page'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'manage_options'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'my-page'</span><span style="color: #339933;">,</span> <span style="color: #000000; font-weight: bold;">FUNCTION</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	wp_register_script<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'my_admin_js'</span><span style="color: #339933;">,</span> plugins_url<span style="color: #009900;">&#40;</span>SCRIPT <span style="color: #990000;">FILE</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">__FILE__</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jquery'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	add_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'admin_print_scripts-'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_page</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">&amp;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'add_admin_scripts'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	add_action<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'admin_print_styles-'</span> <span style="color: #339933;">.</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">admin_page</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">&amp;</span><span style="color: #000088;">$this</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'add_admin_styles'</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;">function</span> add_admin_styles<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	wp_enqueue_style<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'wp-pointer'</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> add_admin_scripts<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	wp_enqueue_script<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'wp-pointer'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jquery'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	wp_enqueue_script<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'my_admin_js'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'jquery'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	wp_localize_script<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'my_admin_js'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'strings'</span><span style="color: #339933;">,</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">localize_admin_js</span><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: #009900;">&#125;</span></pre></td></tr></table></div>

<p>In addition to enqueueing the admin pointer CSS and script files, we&#8217;ve set up a localization function.  Beside being good coding practice, generating the strings for the admin pointer here, instead of in the script file, is going to allow us to use a nice shortcut.</p>
<h3>Step Two &mdash; Build the pointer text and check for dismissal</h3>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">function</span> localize_admin_js<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #000088;">$pointer_text</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'&lt;h3&gt;'</span> <span style="color: #339933;">.</span> esc_js<span style="color: #009900;">&#40;</span> __<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'My Pointer Header'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;/h3&gt;'</span><span style="color: #339933;">;</span>
	<span style="color: #000088;">$pointer_text</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">'&lt;p&gt;'</span> <span style="color: #339933;">.</span> esc_js<span style="color: #009900;">&#40;</span> __<span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">'This is the text of my pointer.'</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span> <span style="color: #0000ff;">'&lt;/p&gt;'</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Get the list of dismissed pointers for the user</span>
	<span style="color: #000088;">$dismissed</span> <span style="color: #339933;">=</span> <span style="color: #990000;">explode</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">','</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#40;</span>string<span style="color: #009900;">&#41;</span> get_user_meta<span style="color: #009900;">&#40;</span> get_current_user_id<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'dismissed_wp_pointers'</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #666666; font-style: italic;">// Check whether our pointer has been dismissed</span>
	<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <span style="color: #990000;">in_array</span><span style="color: #009900;">&#40;</span> POINTER HANDLE<span style="color: #339933;">,</span> <span style="color: #000088;">$dismissed</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$pointer_text</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
		<span style="color: #0000ff;">'pointerText'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #000088;">$pointer_text</span>
	<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>In testing, setting the pointer text to <code>''</code> was sufficient to hide the pointer from the screen. However, we can add another layer of protection in the script, which you&#8217;ll see below.</p>
<h3>Step Three &#8211; Script the pointer object gracefully</h3>
<p>If you don&#8217;t already have an admin script file, you&#8217;ll need to create one for this step.</p>

<div class="wp_syntax"><table><tr><td class="code"><pre class="javascript" style="font-family:monospace;">jQuery<span style="color: #009900;">&#40;</span>document<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">ready</span><span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
	<span style="color: #006600; font-style: italic;">/** Check that pointer support exists AND that text is not empty */</span>
	<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span><span style="color: #009900;">&#40;</span>jQuery<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">pointer</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #3366CC;">'undefined'</span> <span style="color: #339933;">&amp;&amp;</span> strings.<span style="color: #660066;">pointerText</span> <span style="color: #339933;">!=</span> <span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		jQuery<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#OBJECT_YOU_WANT_TO_POINT_AT'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">pointer</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
			content    <span style="color: #339933;">:</span> strings.<span style="color: #660066;">pointerText</span><span style="color: #339933;">,</span>
			close  <span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				jQuery.<span style="color: #660066;">post</span><span style="color: #009900;">&#40;</span> ajaxurl<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
					pointer<span style="color: #339933;">:</span> POINTER HANDLE<span style="color: #339933;">,</span>
					action<span style="color: #339933;">:</span> <span style="color: #3366CC;">'dismiss-wp-pointer'</span>
				<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
		<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">pointer</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'open'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Note the <code>close</code> property of the pointer object: calling this action hooks us right into WordPress&#8217;s pointer management, so that when the user clicks the <code>Dismiss</code> button, our pointer is added to his list of dismissed pointers.  The <code>wp-pointer</code> stylesheet takes care of making the pointer look right so long as there&#8217;s an <code>&lt;h3&gt;</code> and one or more paragraphs, and the close button is added and wired up automatically.</p>
<p>Hope this helps anyone wishing to use this neat, new feature!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.generalthreat.com/2012/01/highlighting-features-with-wordpress-admin-pointers/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Page Caching using disk: enhanced

 Served from: www.generalthreat.com @ 2026-06-10 03:43:59 by W3 Total Cache -->