{"id":2432,"date":"2012-01-28T16:50:15","date_gmt":"2012-01-28T15:50:15","guid":{"rendered":"http:\/\/www.devco.net\/?p=2432"},"modified":"2012-01-28T16:50:21","modified_gmt":"2012-01-28T15:50:21","slug":"writing-oldskool-plugins","status":"publish","type":"post","link":"https:\/\/www.devco.net\/archives\/2012\/01\/28\/writing-oldskool-plugins.php","title":{"rendered":"Writing Oldskool Plugins"},"content":{"rendered":"
Earlier this week I wrote about Oldskool<\/a> which is a Gem extendable search tool. Today I want to show how to create a plugin for it to query some custom source.<\/p>\n <\/a>We’ll build a plugin that shows Puppet Type references, you can see how it will look in the image, click for a larger version.<\/p>\n The end result is that I can just search for “type exec” to get the correct documentation for my Puppet install. I’ll go quite quick through all the various bits here, the complete working plugin is in my GitHub<\/a>.<\/p>\n The nice thing about rendering the type references locally is that you can choose exactly which version to render the docs for and you could possibly also render docs for locally written types that are not part of Puppet – not tried to see how you might render custom types though.<\/p>\n Plugins are made up of a few things that should have predictable names, in the case of our Puppet plugin I decided to call it puppet<\/em> which means we need a class called <\/code><\/p>\n The The I wrote a class called We then create a simple menu that’s just an array of title<\/em> and url<\/em> pairs that will be used to build the top menu that you see in the screenshot.<\/p>\n And finally we just return a hash. The hash that you return must<\/strong> include a template<\/em> key the rest is optional, I override the meaning of the word template a bit – probably should have chosen a better name:<\/p>\n You can see in the code above I passed the menu in as :topmenu<\/em> you could also pass it back as :sidemenu<\/em> which will create buttons down the side of the page, you can use both menus and buttons at the same time.<\/p>\n This takes care of creating the data to display but not yet the displaying aspect. The call to plugin_template(:type)<\/em> will read the contents of the type.erb<\/em> in the plugins view<\/em> directory and return the contents. The Oldskool framework will then render that template making your returned hash available in @result<\/em><\/p>\n Here’s the first part of the view in question, you can see the whole thing here<\/a>:<\/p>\n <\/code><\/p>\nOldskool::PuppetHandler<\/code> that does the work for that plugin. You can see the one here and it goes in
lib\/oldskool\/puppet_handler.rb<\/code> in your gem:<\/p>\n
<\/p>\n
\r\nmodule Oldskool\r\n class PuppetHandler\r\n def initialize(params, keyword, config)\r\n @params = params\r\n @keyword = keyword\r\n @config = config\r\n self\r\n end\r\n\r\n def plugin_template(template)\r\n File.read(File.expand_path(\"..\/..\/..\/views\/#{template}.erb\", __FILE__))\r\n end\r\n\r\n def handle_request(keyword, query)\r\n type = Puppetdoc.new(query)\r\n\r\n menu = [{:title => \"Type Reference\", :url => \"http:\/\/docs.puppetlabs.com\/references\/stable\/type.html\"},\r\n {:title => \"Function Reference\", :url => \"http:\/\/docs.puppetlabs.com\/references\/stable\/function.html\"},\r\n {:title => \"Language Guide\", :url => \"http:\/\/docs.puppetlabs.com\/guides\/language_guide.html\"}]\r\n\r\n {:template => plugin_template(:type), :type => type.doc, :topmenu => menu}\r\n end\r\n end\r\nend\r\n<\/pre>\n
initialize<\/code> and
plugin_template<\/code> methods will rarely change, the
handle_request<\/code> is where the magic happens. It gets called with the keyword and the query, so I set this up to respond to searched like
type exec<\/code>. If you needed any kind of configuration data from the main Oldskool config file you’d just add data to that YAML file and the data would be available in
@config<\/code>.<\/p>\n
keyword<\/code> would be
type<\/code> and the
query<\/code> would be
exec<\/code>. The idea is that we could route for example
type<\/code> as well as
function<\/code> keywords into the plugin and then do different things with the query string.<\/p>\n
Puppetdoc<\/code> that takes care of the Puppet introspection, I won’t go into the details but you can see it here<\/a>, it just returns a hash with all the Markdown for each parameter, meta parameter and the type itself.<\/p>\n
\n
<\/p>\n
\r\n<% unless @error %>\r\n
<%= @result[:type][:name].to_s.capitalize %> version <%= @result[:type][:version] %><\/h2>\r\n<% end %>\r\n<\/pre>\n