<?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>Don&#039;t Forget to Plant It! &#187; plugins</title>
	<atom:link href="http://blog.codeeg.com/tag/plugins/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.codeeg.com</link>
	<description></description>
	<lastBuildDate>Wed, 28 Jul 2010 12:22:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Taming Beast: How to Extend Beast using Plugins</title>
		<link>http://blog.codeeg.com/2007/09/04/taming-beast-how-to-extend-beast-using-plugins/</link>
		<comments>http://blog.codeeg.com/2007/09/04/taming-beast-how-to-extend-beast-using-plugins/#comments</comments>
		<pubDate>Wed, 05 Sep 2007 03:10:44 +0000</pubDate>
		<dc:creator>Calvin</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[beast forums]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://blog.codeeg.com/2007/09/04/taming-beast-how-to-extend-beast-using-plugins/</guid>
		<description><![CDATA[If you&#8217;re building a Ruby on Rails application and are in need of some forums functionality, you&#8217;ve most likely have looked into Beast. However, Beast is very limited in functionality (which I actually think is a good thing), so you might find yourself needing to extend Beast to do the things you want. Fortunately, Beast [...]]]></description>
			<content:encoded><![CDATA[<p></p><p>If you&#8217;re building a Ruby on Rails application and are in need of some forums functionality, you&#8217;ve most likely have looked into Beast.  However, Beast is very limited in functionality (which I actually think is a good thing), so you might find yourself needing to extend Beast to do the things you want.</p>
<p>Fortunately, Beast has a plugin feature that will easily allow you to do this.  In this post, I&#8217;ll cover how you would do this, using my StyleEditor plugin as an example.</p>
<h2>The Plugin File Structure</h2>
<p>First, let&#8217;s cover plugin file structure.  This is what my StyleEditor plugin looks like:</p>
<p><img class="alignnone size-full wp-image-112" src="http://blog2.codeeg.com/wp-content/uploads/2008/06/beast_plugin_dir_structure.png" alt="" width="162" height="223" /></p>
<p>Here are the important points to note:</p>
<ul>
<li><strong>app:</strong> The directory structure of this directory should follow the same conventions as the main Rails <em>app/</em> directory.  Code located in this directory follow the same class loading (and reloading) rules as the main <em>app/</em> directory.</li>
<li><strong>lib/beast/plugins/style_editor.rb:</strong> This is the plugin class, where all the magic happens.  The name of the file should be the tableized version of the plugin&#8217;s actual class name.  The plugin class file <strong>must</strong> be located in <em>beast/plugins</em>, or else Rails will not be able to find it.</li>
</ul>
<h2>The Plugin Class</h2>
<p>Here&#8217;s what&#8217;s the plugin class should look like:</p>
<pre>module Beast
  module Plugins
    class StyleEditor &lt; Beast::Plugin
      author 'Calvin Yu - boardista.com'
      version '0001'
      homepage 'http://boardista.com'
      notes 'Style Editing Support'

      %w( controllers helpers models ).each do |dir|
        path = File.join(plugin_path, 'app', dir)
        Dependencies.load_paths &lt;&lt; File.expand_path(path) if File.exist?(path)
      end

      def initialize
        super
        ApplicationController.prepend_view_path File.join(StyleEditor::plugin_path, 'app', 'views')
        # Patch Beast code here.
      end

      def install
        super
        # Run any install processes here.
      end
    end # end StyleEditor class
  end # end Plugins module
end # end Beast module</pre>
<p>You can see what <a href="http://svn.codeeg.com/beast/style_editor/lib/beast/plugins/style_editor.rb">the final source looks like here</a>.  Here are some things to note about this class:</p>
<ul>
<li>The <em>author</em>, <em>version</em>, <em>homepage</em>, and <em>notes</em> methods provide some meta information for the plugin.</li>
<li>The <em>Dependencies.load_paths</em> call will configure the sub-directories under <em>app/</em> so that they&#8217;ll be dynamically loaded by Rail&#8217;s dependency resolution process.</li>
<li>The <em>ApplicationController.prepend_view_path</em> call will prepend this plugin&#8217;s view path ahead of the normal Rails view path <strong>and any other view paths configured by other plugins loaded before it</strong>.  This is important to remember if views aren&#8217;t being rendered like you&#8217;re expecting them to.</li>
<li>Any changes to existing Rails or Beast controllers, models, etc. should go into <em>initialize</em>, in the form of monkey patches and mixins.</li>
<li>Any installation tasks, such as file copy, should go into the <em>install</em> method.</li>
</ul>
<h2>Adding New Routes</h2>
<p>I needed to create some new routes for my <em>StylesController</em>, so I used the <em>route</em> method of the <em>Beast::Plugin</em> class to install them:</p>
<pre><code># add this within the class scope of the StyleEditorroute :resources, 'styles'</code></pre>
<p>I&#8217;m using the RESTful syntax to creating routes here, but you can also use <em>:connect</em> and named routes as well.</p>
<h2>Updating the Beast Schema</h2>
<p>To update the Beast Schema, all I needed to do is to create a Schema class within the scope of your plugin class:<br />
<code> </code></p>
<pre>class Schema &lt; ActiveRecord::Migration
  def self.install
    create_table :style_options do |t|
      t.string :name
      t.string :value
      t.integer :style_id
    end

    create_table :styles do |t|
      t.string :name
      t.string :template_name
      t.boolean :active
      t.timestamps
    end
  end

  def self.uninstall
    drop_table :styles
    drop_table :style_options
  end
end # end Schema class</pre>
<p>The code in <em>install/uninstall</em> methods will work just like the <em>up/down</em> methods in a typical migration class.  There is an issue where there&#8217;s no support for handling db changes overtime &#8212; hopefully someone will find a nice way to handle this (any takers?).</p>
<h2>Using the Rails Console</h2>
<p>At some point, you&#8217;ll want to do some quick tests to make sure your plugin changes are working as you expect them to, and try to test them from the console.  If you have tried to this already, you&#8217;ll quickly find that your changes for some reason won&#8217;t work.  Don&#8217;t fret, the reason why it doesn&#8217;t work is because the plugins aren&#8217;t initialize until the <em>Dispatcher</em> receives its first request.  So, if you do want to test your changes in the console, you&#8217;ll need to run this command first:</p>
<pre><code>Dispatcher.send :prepare_application</code></pre>
<h2>Installing a Plugin</h2>
<p>Once you&#8217;re done with your plugin, you&#8217;ll need to install it.  This step is pretty easy.  First, install your beast plugins into <em>vendor/beast</em>, then run the plugin install method:</p>
<p><code>script/runner 'Beast::Plugins::StyleEditor.install'</code></p>
<p>Some plugins might have some additional installation instructions, so I would suggest looking at the <em>README</em> file (and if you&#8217;re developing on a plugin, make sure to put your install instructions in the README).</p>
<h2>That&#8217;s It!</h2>
<p>It&#8217;s important to note that Beast plugin system is an evolving system, and the steps I laid out here are what worked best for me through the process of trial an error.  I&#8217;d love to hear what conclusions others have come to in their plugin development exploits.  If you want to get a better feel of what an actual Beast plugin looks like, you can check out the plugins that I&#8217;ve developed at <a href="http://svn.codeeg.com/beast">http://svn.codeeg.com/beast</a>.  If you want to see what those plugins look like in action, you can check them out on <a href="http://boardista.com">Boardista.com</a>.</p>
<p class="poweredbyperformancing">Powered by <a href="http://scribefire.com/">ScribeFire</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codeeg.com/2007/09/04/taming-beast-how-to-extend-beast-using-plugins/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
