<?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>Marcus Povey &#187; plugins</title>
	<atom:link href="http://www.marcus-povey.co.uk/tag/plugins/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.marcus-povey.co.uk</link>
	<description>Making the world a better place, one byte at a time...</description>
	<lastBuildDate>Mon, 06 Feb 2012 19:13:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.1</generator>
	<atom:link rel='hub' href='http://www.marcus-povey.co.uk/?pushpress=hub'/>
		<item>
		<title>Loosely coupled Elgg extensions (Captcha example)</title>
		<link>http://www.marcus-povey.co.uk/2009/06/15/loosely-coupled-elgg-extensions-captcha-example/</link>
		<comments>http://www.marcus-povey.co.uk/2009/06/15/loosely-coupled-elgg-extensions-captcha-example/#comments</comments>
		<pubDate>Mon, 15 Jun 2009 16:41:07 +0000</pubDate>
		<dc:creator>Marcus Povey</dc:creator>
				<category><![CDATA[elgg]]></category>
		<category><![CDATA[#ue]]></category>
		<category><![CDATA[actions]]></category>
		<category><![CDATA[captcha]]></category>
		<category><![CDATA[extend]]></category>
		<category><![CDATA[hooks]]></category>
		<category><![CDATA[plugins]]></category>

		<guid isPermaLink="false">http://www.marcus-povey.co.uk/?p=206</guid>
		<description><![CDATA[One thing we try and do when working on a new Elgg feature is &#8211; where we can &#8211; couple things together as loosely as possible and provide hooks for third party developers to extend Elgg and fill in any blanks. A good example of where this has been done is the newly introduced Captcha [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://xkcd.com/233/"><img src="http://www.marcus-povey.co.uk/wp-content/a_new_captcha_approach.png" border="0" alt="A new CAPTCHA approach" width="300" align="right" /></a>One thing we try and do when working on a new Elgg feature is &#8211; where we can &#8211; <a href="http://en.wikipedia.org/wiki/Coupling_(computer_science)">couple things together as loosely as possible</a> and provide hooks for third party developers to extend Elgg and fill in any blanks.</p>
<p>A good example of where this has been done is the newly introduced <a href="http://en.wikipedia.org/wiki/Captcha">Captcha</a> functionality available in the latest <a href="http://www.elgg.org/download/nightly/">nightly testing builds of Elgg</a>.</p>
<p>The Captcha functionality is provided by a module which extends a view called &#8220;<a href="https://code.elgg.org/elgg/trunk/views/default/input/captcha.php">input/captcha</a>&#8220;. This view is blank by default but is used in several places such as user registration and the lost password form.</p>
<p>This means two things; firstly that if a Captcha module isn&#8217;t installed or enabled then forms behave normally, and secondly it becomes a trivial matter for third party modules to provide their own Captcha functionality.</p>
<p>This same mechanism is how the <a href="http://community.elgg.org/pg/plugins/marcus/read/142964/example-url-shortening-service-using-3lacc">URL shortener module</a> works by the way.</p>
<p>Next, the Captcha module <a href="http://www.marcus-povey.co.uk/2009/05/08/extendin-actions-in-elgg/">extends a number of actions</a> to require a correctly validated Captcha code. This list itself is the product of a <a href="http://docs.elgg.org/wiki/PluginHooks">plugin hook</a> which returns an array of actions which require Captcha validation:</p>
<blockquote><p><code>$actions = array();<br />
$actions = trigger_plugin_hook('actionlist', 'captcha', null, $actions);</code></p></blockquote>
<blockquote><p><code>...</code></p></blockquote>
<blockquote><p><code>function captcha_actionlist_hook($hook, $entity_type, $returnvalue, $params)<br />
{<br />
if (!is_array($returnvalue))<br />
$returnvalue = array();</code></p>
<p><code>$returnvalue[] = 'register';<br />
$returnvalue[] = 'user/requestnewpassword';</code></p>
<p><code>return $returnvalue;<br />
}</code></p></blockquote>
<p>The reason why the list of actions is provided this way is twofold, firstly it lets modules use Captcha functionality in their own code through a generic interface, and secondly it is harder to spoof than looking for some marker in the form code.</p>
<p>The Captcha itself injects a server generated token into the form, which together with the user&#8217;s response to the characters generated in an image are used to validate that the user is indeed human.</p>
<p>As we can see, Elgg asks to be provided with a Captcha if one is available by including a specific view, but is agnostic as to where (or indeed if) this functionality is supplied.</p>
<p>By using the techniques available to an Elgg programmer I was able to loosely couple the Captcha system to Elgg in such a way that a third party can easily use the same techniques to provide a more advanced module.</p>
<p>Happy coding!</p>
<p><small>Image &#8220;<a href="http://xkcd.com/233/">A new Captcha approach</a>&#8221; by <a href="http://www.xkcd.com">XKCD</a></small></p>
<div class="wsbuttons">
	<div class="shareblob facebook">
		<div class="fb-like" data-href="http://www.marcus-povey.co.uk/2009/06/15/loosely-coupled-elgg-extensions-captcha-example/" data-send="false" data-layout="box_count" data-width="60" data-show-faces="false" data-colorscheme="light"></div>
	</div>

	<div class="shareblob google">
		<div class="g-plusone" data-size="tall" data-href="http://www.marcus-povey.co.uk/2009/06/15/loosely-coupled-elgg-extensions-captcha-example/"></div>
	</div>

	<div class="shareblob twitter">
		<div class="twitter">
			<a href="https://twitter.com/share?url=http%3A%2F%2Fwww.marcus-povey.co.uk%2F2009%2F06%2F15%2Floosely-coupled-elgg-extensions-captcha-example%2F&count=vertical" class="twitter-share-button" data-lang="en">Tweet</a>
			<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
		</div>
	</div>

</div>
	]]></content:encoded>
			<wfw:commentRss>http://www.marcus-povey.co.uk/2009/06/15/loosely-coupled-elgg-extensions-captcha-example/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>All about themes</title>
		<link>http://www.marcus-povey.co.uk/2008/09/15/all-about-themes/</link>
		<comments>http://www.marcus-povey.co.uk/2008/09/15/all-about-themes/#comments</comments>
		<pubDate>Mon, 15 Sep 2008 18:54:57 +0000</pubDate>
		<dc:creator>Marcus Povey</dc:creator>
				<category><![CDATA[elgg]]></category>
		<category><![CDATA[#ue]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[themes]]></category>

		<guid isPermaLink="false">http://www.marcus-povey.co.uk/?p=87</guid>
		<description><![CDATA[Themes for Elgg are both extremely easy to develop and incredibly powerful. Using themes you can completely change how an Elgg install looks and feels (and even behaves). Since there has been a fair amount of discussion of themes on the groups, I thought it would be a good idea to write a brief post [...]]]></description>
			<content:encoded><![CDATA[<p>Themes for Elgg are both extremely easy to develop and incredibly powerful. Using themes you can completely change how an Elgg install looks and feels (and even behaves).</p>
<p>Since there has been a fair amount of discussion of themes on the groups, I thought it would be a good idea to write a brief post about it.</p>
<p>Themes use two key Elgg concepts &#8211; namely, the <a href="http://docs.elgg.org/wiki/Plugin_development">plugin architecture</a> and the <a href="http://docs.elgg.org/wiki/Views">views system</a>.</p>
<p>By far the easiest and flexible way to make a theme for Elgg is to build it as a plugin. This makes it easy to distribute (since they are self contained) and lets you turn the theme on and off from the admin panel (making the theming process far less invasive!)</p>
<p>What you must first do is create a new plugin directory under /mod (<a href="http://docs.elgg.org/wiki/Plugin_development#Core_requirements">documented here</a>). In a nutshell; create a directory in the name of your theme, a new start.php and a new <a href="http://docs.elgg.org/wiki/Manifests">manifest.xml</a>.</p>
<p>Once you&#8217;ve done this you then can start modifying views. This can be done either by extension or by view overriding.</p>
<p><strong>View extension</strong><br />
The first way is to add extra stuff to an existing view via the extend view function from within your start.php&#8217;s initialisation function.</p>
<p>For example, the following start.php will add <code>mytheme/spotlight</code> to the already existing site spotlight:</p>
<blockquote><p><code>&lt;?php</code></p>
<p><code>function mytheme_init()<br />
{<br />
extend_view('page_elements/spotlight','mytheme/spotlight');<br />
}</code></p>
<p><code>register_elgg_event_handler('init','system','mytheme_init');</code></p>
<p><code>?&gt;</code></p></blockquote>
<p><strong>View overriding</strong><br />
The next method is to override an existing theme, completely replacing it with the one provided by your plugin.</p>
<p>View files provided by plugins automatically take precedence over views from the core. So all we have to do to entirely replace the existing spotlight is to create a new spotlight.php in the appropriate hierarchy.</p>
<p>So, if the original view is stored in:</p>
<p><code>/elgg/views/default/page_elements/spotlight.php</code></p>
<p>We need to create the file:</p>
<p><code>/elgg/mod/mytheme/views/default/page_elements/spotlight.php</code></p>
<p>Now, when we go to the admin panel and activate our theme the spotlight will be replaced by whatever you put in that file. Simple eh?</p>
<p>You can of course do this with any view.</p>
<p>Using a combination of these methods means you can replace the entire look and feel of a site very quickly indeed, although I would suggest that you start slowly since many views do some quite complicated things.</p>
<div class="wsbuttons">
	<div class="shareblob facebook">
		<div class="fb-like" data-href="http://www.marcus-povey.co.uk/2008/09/15/all-about-themes/" data-send="false" data-layout="box_count" data-width="60" data-show-faces="false" data-colorscheme="light"></div>
	</div>

	<div class="shareblob google">
		<div class="g-plusone" data-size="tall" data-href="http://www.marcus-povey.co.uk/2008/09/15/all-about-themes/"></div>
	</div>

	<div class="shareblob twitter">
		<div class="twitter">
			<a href="https://twitter.com/share?url=http%3A%2F%2Fwww.marcus-povey.co.uk%2F2008%2F09%2F15%2Fall-about-themes%2F&count=vertical" class="twitter-share-button" data-lang="en">Tweet</a>
			<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
		</div>
	</div>

</div>
	]]></content:encoded>
			<wfw:commentRss>http://www.marcus-povey.co.uk/2008/09/15/all-about-themes/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Import and Export in Elgg 1.0</title>
		<link>http://www.marcus-povey.co.uk/2008/07/31/import-and-export-in-elgg-10-2/</link>
		<comments>http://www.marcus-povey.co.uk/2008/07/31/import-and-export-in-elgg-10-2/#comments</comments>
		<pubDate>Thu, 31 Jul 2008 17:13:44 +0000</pubDate>
		<dc:creator>Marcus Povey</dc:creator>
				<category><![CDATA[elgg]]></category>
		<category><![CDATA[export]]></category>
		<category><![CDATA[import]]></category>
		<category><![CDATA[plugins]]></category>

		<guid isPermaLink="false">http://www.marcus-povey.co.uk/?p=56</guid>
		<description><![CDATA[Perhaps one of the most useful and unique features about Elgg 1.0 is its ability to import and export data. Initially this is accomplished via OpenDD, but we have added hooks which make it very easy to add other formats. I&#8217;m going to talk a little bit about how this works. Firstly, Export. Export works [...]]]></description>
			<content:encoded><![CDATA[<p>Perhaps one of the most useful and unique features about Elgg 1.0 is its ability to import and export data. Initially this is accomplished via OpenDD, but we have added hooks which make it very easy to add other formats.</p>
<p>I&#8217;m going to talk a little bit about how this works. Firstly, Export.</p>
<p>Export works via the <a href="http://docs.elgg.org/wiki/Views">views system</a>, and involves creating a brand new view hierarchy for your new format.</p>
<p>We first need to <a href="http://docs.elgg.org/wiki/Tutorials">create a plugin</a>, and in this plugin we create a &#8220;views&#8221; directory. We need to then create a new directory for your format, and then create a couple of views underneath.</p>
<p><img class="alignleft" style="float: left;"src="http://www.marcus-povey.co.uk/wp-content/viewsactions.png" alt="" width="216" height="330" />The image to the left shows the necessary file hierarchy that you need to create &#8211; in this instance to export &#8220;myformat&#8221;.</p>
<p>Create a directory called &#8220;export&#8221;. In this directory place the three php files &#8211; <code>entity.php</code>, <code>metadata.php</code> and <code>relationship.php</code> &#8211; which handle entities, metadata (and annotations) and relationships respectively.</p>
<p>Each of these files are passed objects via <code>$vars</code>. Depending on which file you are in, this might be <code>$vars['entity']</code>, <code>$vars['metadata']</code> or <code>$vars['relationship']</code>.</p>
<p>It is then up to you to encode and output the object according to your format.</p>
<p>All that remains is to provide the <code>pageshell</code> which handles how the overall page is displayed. This file may set the content-type header or provide wrapping tags (e.g. for XML output).</p>
<p><code>pageshell.php</code> is passed <code>$vars['body']</code> containing the output of your other files.</p>
<p>Providing a handler to deal with importing data is also fairly simple, and works through the <a href="http://docs.elgg.org/wiki/Actions">action interface</a>.</p>
<p>In your plugin&#8217;s init function register the action &#8220;import/YOURFORMAT&#8221;, and point it to your <code>actions/import/myformat.php</code>, e.g.</p>
<blockquote>
<pre>&lt;?php

	function myformatplugin_init()
	{
		global $CONFIG;

		// Register import action
		register_action('import/myformat', false,
		  $CONFIG-&gt;pluginspath . "myformatplugin_init/actions/import/myformat.php");
	}

	// Initialise
	register_elgg_event_handler('init','system','myformatplugin_init');
?&gt;</pre>
</blockquote>
<p>This will then register an import action which will be picked up by the administrator import export utility. Your action can access the information it needs to import with the call:</p>
<blockquote><p><code>$data = get_input('data');</code></p></blockquote>
<p>Elgg 1.0 will ship with native support for <a href="http://www.opendd.net">OpenDD</a> (both import and export) which will allow administrators to migrate between <a href="http://classic.elgg.org">Elgg classic</a> and the new codebase with a minimum amount of effort.</p>
<p>Elgg 1.0 also offers export views in JSON and PHP native, making it easier to reference the data directly and create mashups.</p>
<p>Over time we will be adding more import and export functionality, and I hope you will be too!</p>
<div class="wsbuttons">
	<div class="shareblob facebook">
		<div class="fb-like" data-href="http://www.marcus-povey.co.uk/2008/07/31/import-and-export-in-elgg-10-2/" data-send="false" data-layout="box_count" data-width="60" data-show-faces="false" data-colorscheme="light"></div>
	</div>

	<div class="shareblob google">
		<div class="g-plusone" data-size="tall" data-href="http://www.marcus-povey.co.uk/2008/07/31/import-and-export-in-elgg-10-2/"></div>
	</div>

	<div class="shareblob twitter">
		<div class="twitter">
			<a href="https://twitter.com/share?url=http%3A%2F%2Fwww.marcus-povey.co.uk%2F2008%2F07%2F31%2Fimport-and-export-in-elgg-10-2%2F&count=vertical" class="twitter-share-button" data-lang="en">Tweet</a>
			<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
		</div>
	</div>

</div>
	]]></content:encoded>
			<wfw:commentRss>http://www.marcus-povey.co.uk/2008/07/31/import-and-export-in-elgg-10-2/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Plugin settings on Elgg 1</title>
		<link>http://www.marcus-povey.co.uk/2008/06/20/plugin-settings-on-elgg-1/</link>
		<comments>http://www.marcus-povey.co.uk/2008/06/20/plugin-settings-on-elgg-1/#comments</comments>
		<pubDate>Fri, 20 Jun 2008 18:48:48 +0000</pubDate>
		<dc:creator>Marcus Povey</dc:creator>
				<category><![CDATA[elgg]]></category>
		<category><![CDATA[plugins]]></category>

		<guid isPermaLink="false">http://www.marcus-povey.co.uk/?p=43</guid>
		<description><![CDATA[Whew, well it&#8217;s been a monumentally busy development week on the new Elgg 1.0 codebase. The whole team has been working hard putting things together, and I&#8217;ve written so much cool stuff its hard to know where to begin. Much of the really cool stuff I&#8217;ve been working on has been under the hood (XML-RPC, [...]]]></description>
			<content:encoded><![CDATA[<p>Whew, well it&#8217;s been a monumentally busy development week on the new Elgg 1.0 codebase. The whole team has been working hard putting things together, and I&#8217;ve written so much cool stuff its hard to know where to begin.</p>
<p>Much of the really cool stuff I&#8217;ve been working on has been under the hood (XML-RPC, PAM, API etc), but I&#8217;ll start with giving a brief summary of what I was working on today &#8211; plugin administration.</p>
<p>As with Elgg Classic, Elgg 1 supports plugins modules. However, these modules can be turned on and off by the administrator (in much the same way as wordpress plugins can be). They can also have settings edited.</p>
<p>There are two things as a plugin writer to do to take full advantage of this:</p>
<p><strong>Manifests</strong></p>
<p>Manifests tell Elgg a little bit about your plugin. Your plugin will still work without them, but I highly recommend you use them.</p>
<p>Simply create a file called <code>manifest.xml</code> in your plugin&#8217;s top level directory that looks something like this:</p>
<blockquote><p><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
&lt;plugin_manifest&gt;<br />
&lt;field key="author" value="Marcus Povey" /&gt;<br />
&lt;field key="version" value="1.0" /&gt;<br />
&lt;field key="description" value="My first plugin!" /&gt;<br />
&lt;field key="website" value="http://www.marcus-povey.co.uk/" /&gt;<br />
&lt;field key="copyright" value="(C) MyCorp 2008" /&gt;<br />
&lt;field key="licence" value="GNU Public License version 2" /&gt;<br />
&lt;/plugin_manifest&gt;</code></p></blockquote>
<p><strong>Per-plugin settings</strong></p>
<p>These let you provide some admin controlled configuration options for your plugin. Adding these is relatively simple.</p>
<ol>
<li>Create a file in your plugin&#8217;s view folder called <code>settings/PLUGINNAME/edit.php</code>, where <code>PLUGINNAME</code> is the name of your plugin&#8217;s directory in the mod hierarchy.</li>
<li>Fill this file with the form elements you want to display together with internationalised text labels. Note: you don&#8217;t need to add a save button or the form, this will be handled by the framework.</li>
<li>Set the <code>name</code> attribute in your form components to <code>param[VARNAME]</code> where <code>VARNAME</code> is the name of the variable. These will be saved as metadata attached to a <code>plugin</code> entity. So, if your variable is called param[myparameter] your entity (which is also passed to this view as <code>$vars['entity']</code>) will be called <code>$vars['entity']-&gt;myparameter</code>.</li>
</ol>
<p>Here is an example of this view:</p>
<blockquote><p><code>&lt;p&gt;<br />
&lt;?php echo elgg_echo('myplugin:settings:limit'); ?&gt;</code></p>
<p><code>&lt;select name="params[limit]"&gt;<br />
&lt;option value="5" &lt;?php if ($vars['entity']-&gt;limit == 5) echo " selected=\"yes\" "; ?&gt;&gt;5&lt;/option&gt;<br />
&lt;option value="8" &lt;?php if ((!$vars['entity']-&gt;limit) || ($vars['entity']-&gt;limit == 8)) echo " selected=\"yes\" "; ?&gt;&gt;8&lt;/option&gt;<br />
&lt;option value="12" &lt;?php if ($vars['entity']-&gt;limit == 12) echo " selected=\"yes\" "; ?&gt;&gt;12&lt;/option&gt;<br />
&lt;option value="15" &lt;?php if ($vars['entity']-&gt;limit == 15) echo " selected=\"yes\" "; ?&gt;&gt;15&lt;/option&gt;<br />
&lt;/select&gt;<br />
&lt;/p&gt;</code></p></blockquote>
<p>Fun! fun!</p>
<div class="wsbuttons">
	<div class="shareblob facebook">
		<div class="fb-like" data-href="http://www.marcus-povey.co.uk/2008/06/20/plugin-settings-on-elgg-1/" data-send="false" data-layout="box_count" data-width="60" data-show-faces="false" data-colorscheme="light"></div>
	</div>

	<div class="shareblob google">
		<div class="g-plusone" data-size="tall" data-href="http://www.marcus-povey.co.uk/2008/06/20/plugin-settings-on-elgg-1/"></div>
	</div>

	<div class="shareblob twitter">
		<div class="twitter">
			<a href="https://twitter.com/share?url=http%3A%2F%2Fwww.marcus-povey.co.uk%2F2008%2F06%2F20%2Fplugin-settings-on-elgg-1%2F&count=vertical" class="twitter-share-button" data-lang="en">Tweet</a>
			<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
		</div>
	</div>

</div>
	]]></content:encoded>
			<wfw:commentRss>http://www.marcus-povey.co.uk/2008/06/20/plugin-settings-on-elgg-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

