<?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>usefulfor.com/ruby &#187; dradis</title>
	<atom:link href="http://usefulfor.com/ruby/category/dradis/feed/" rel="self" type="application/rss+xml" />
	<link>http://usefulfor.com/ruby</link>
	<description>ruby goodness for your daily needs</description>
	<lastBuildDate>Mon, 07 Dec 2009 23:20:56 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>How to create a dradis export plugin?</title>
		<link>http://usefulfor.com/ruby/2009/03/27/how-to-create-a-dradis-export-plugin/</link>
		<comments>http://usefulfor.com/ruby/2009/03/27/how-to-create-a-dradis-export-plugin/#comments</comments>
		<pubDate>Fri, 27 Mar 2009 01:04:47 +0000</pubDate>
		<dc:creator>etd</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[dradis]]></category>

		<guid isPermaLink="false">http://usefulfor.com/ruby/?p=87</guid>
		<description><![CDATA[Although we presented some of this concepts already in dradis reporting: quick &#38; neat word export, here is the step by step guide to get an export plugin recognised by the dradis framework and ready to use!
Update (2009-04-09): Checkout the new import/export plugin generators at dradis community forums.

Generate the plugin skeleton

$ ./script/generate plugin my_export
  [...]]]></description>
			<content:encoded><![CDATA[<p>Although we presented some of this concepts already in <a href="http://usefulfor.com/ruby/2009/02/15/dradis-reporting-quick-neat-word-export/">dradis reporting: quick &amp; neat word export</a>, here is the step by step guide to get an export plugin recognised by the <a href="http://dradisframework.org/">dradis framework</a> and ready to use!</p>
<p><strong>Update (2009-04-09)</strong>: Checkout the new import/export plugin generators at <a href="http://dradisframework.org/community/index.php?topic=7.msg9">dradis community forums</a>.<br />
<span id="more-87"></span></p>
<h3>Generate the plugin skeleton</h3>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">$ .<span style="color: #000000; font-weight: bold;">/</span>script<span style="color: #000000; font-weight: bold;">/</span>generate plugin my_export
      create  vendor<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>my_export<span style="color: #000000; font-weight: bold;">/</span>lib
      create  vendor<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>my_export<span style="color: #000000; font-weight: bold;">/</span>tasks
      create  vendor<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>my_export<span style="color: #000000; font-weight: bold;">/</span><span style="color: #7a0874; font-weight: bold;">test</span>
      create  vendor<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>my_export<span style="color: #000000; font-weight: bold;">/</span>README
      create  vendor<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>my_export<span style="color: #000000; font-weight: bold;">/</span>MIT-LICENSE
      create  vendor<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>my_export<span style="color: #000000; font-weight: bold;">/</span>Rakefile
      create  vendor<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>my_export<span style="color: #000000; font-weight: bold;">/</span>init.rb
      create  vendor<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>my_export<span style="color: #000000; font-weight: bold;">/</span>install.rb
      create  vendor<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>my_export<span style="color: #000000; font-weight: bold;">/</span>uninstall.rb
      create  vendor<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>my_export<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>my_export.rb
      create  vendor<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>my_export<span style="color: #000000; font-weight: bold;">/</span>tasks<span style="color: #000000; font-weight: bold;">/</span>my_export_tasks.rake
      create  vendor<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>my_export<span style="color: #000000; font-weight: bold;">/</span>test<span style="color: #000000; font-weight: bold;">/</span>my_export_test.rb</pre></div></div>

<p>Edit <code>vendor/plugins/my_export/init.rb</code> to include the main plugin library:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># Include hook code here</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'my_export'</span></pre></div></div>

<p>In the main library (<code>vendor/plugins/my_export/lib/my_export.rb</code>), define a module (choose a name, ideally it should match the plugin name):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># MyExport</span>
<span style="color:#9966CC; font-weight:bold;">module</span> MyExport
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>This is all you really need to get it started. Now you have to put your code in the right place so the framework finds it (and creates an entry for you in the <strong>export</strong> menu).</p>
<h3>Hooking into the framework</h3>
<p>At the end of the day an export plugin provides a number of Rails actions. These are methods that will be invoked through the URL, for instance:-</p>
<pre>
/export/to_pdf
/export/to_xml
/export/to_excel
...
</pre>
<p>Each export plugin can define several actions. If more than one action is defined a nested submenu will be appended to the <strong>export</strong> menu with all the defined actions.</p>
<p>In order for the framework to find your actions, they have to be defined in a certain way, they have to be defined inside the <code>Actions</code> module (we are still editing the same file):-</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># MyExport</span>
<span style="color:#9966CC; font-weight:bold;">module</span> MyExport
  <span style="color:#9966CC; font-weight:bold;">module</span> Actions
    <span style="color:#008000; font-style:italic;"># first action</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> to_myformat<span style="color:#006600; font-weight:bold;">&#40;</span>params=<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#008000; font-style:italic;"># your action code goes here</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># second action</span>
    <span style="color:#008000; font-style:italic;"># [...]</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>And that&#8217;s it, nice and easy, you can define as many actions as you like in you <code>Actions</code> module.</p>
<p>Finally, in order to make everything work together you need to include your module in the main repository of export plugins (<code>Plugins::Export</code>):</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
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># MyExport</span>
<span style="color:#9966CC; font-weight:bold;">module</span> MyExport
  <span style="color:#9966CC; font-weight:bold;">module</span> Actions
    <span style="color:#008000; font-style:italic;"># first action</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> to_myformat<span style="color:#006600; font-weight:bold;">&#40;</span>params=<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#008000; font-style:italic;"># your action code goes here</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#008000; font-style:italic;"># [...]</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">module</span> Plugins
  <span style="color:#9966CC; font-weight:bold;">module</span> Export
    <span style="color:#9966CC; font-weight:bold;">include</span> MyExport
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>Remember to restart you <strong>dradis</strong> server. Your <strong>export</strong> menu should have an entry for your newly created plugin. And now is the time to be creative about what you implement!</p>
<img src="http://usefulfor.com/ruby/?ak_action=api_record_view&id=87&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://usefulfor.com/ruby/2009/03/27/how-to-create-a-dradis-export-plugin/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>dradis extensions: how they work and how to write them</title>
		<link>http://usefulfor.com/ruby/2009/02/17/dradis-extensions-how-they-work-and-how-to-write-them/</link>
		<comments>http://usefulfor.com/ruby/2009/02/17/dradis-extensions-how-they-work-and-how-to-write-them/#comments</comments>
		<pubDate>Mon, 16 Feb 2009 23:33:24 +0000</pubDate>
		<dc:creator>siebert</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[dradis]]></category>

		<guid isPermaLink="false">http://usefulfor.com/ruby/?p=84</guid>
		<description><![CDATA[Dradis is a tool used for structured information storage and sharing. Although it is applicable to various environments, it is originally aimed at information security consultants working alone or in a team. One of the great features of the application is that the client side&#8217;s functionality can be extended by what is called (quite creatively) [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://dradis.sourceforge.net">Dradis</a> is a tool used for structured information storage and sharing. Although it is applicable to various environments, it is originally aimed at information security consultants working alone or in a team. One of the great features of the application is that the client side&#8217;s functionality can be extended by what is called (quite creatively) &#8211; <em>extensions</em>.</p>
<p>In this post I&#8217;ll be looking at what an extension is, how it fits into the dradis framework and how to write your own extensions.</p>
<p>You are welcome to jump ahead to the <strong><a href="#how_to">How do I write my own extension?</a></strong> if that is the only part that you are interested in.<br />
<span id="more-84"></span></p>
<p><strong>What is an extension?</strong></p>
<p>In a nutshell &#8211; <em>A dradis extension is an addition to the collection of functions offered by the dradis client side.</em> The possibilities of what an extension can be are almost endless. From a logical perspective it will be a function that enhances the usability of the application within the context of the user.</p>
<p>Currently the functionality that is offered by an extension is triggered from the command line console on the client side. To see what are all the commands offered by your currently installed extensions type <em>help</em> in the command line console of the dradis client. You might see something similar to:</p>
<pre>List of registered commands
---------------------------
help:	shows the help of all the commands available
reload:	reload the modules from the filesystem
quit:	exits the application
add:	add elements to the project
fact:	shows a random Chuck Norris fact
encode:	Encodes a string using various differnet encoding schemes
lookup:	Basically greps a file, useful for lookup tables
decode:	Decodes a string into the specified encoding type
export:	export the knowledge base to a local file
ls:	lists entries under the directory specified as argument
import:	import external resources to dradis
</pre>
<p>Some of those commands are hard coded into the console functionality but the majority are commands offered by your installed extensions. For example the <em>fact</em> command is offered to you by the <em>chucknorris extension</em> and the <em>ls</em> command is offered by the <em>filesystem</em> extension.</p>
<p>Extensions can also communicate to other parts of the application. In the majority of cases this will be communication to the data storage. For example the add command allows you to add data to the data storage and the export command allows you to export the data storage to a local file.</p>
<p><strong>Where do extensions fit into the dradis framework?</strong></p>
<p>Extension fact list:</p>
<ul>
<li>As mentioned previously, extensions are found on the client side of the dradis framework.</li>
<li>When looking at the code they can be found in the <em>client/extensions</em> folder.</li>
<li>An extension provides one or more commands that can be called from the client command line console.</li>
<li>Executing one of these commands in the console triggers a call to a method in the extension code (Executing <em>fact</em> in the console triggers the <em>fact</em> method in the <em>chucknorris.rb</em> file).</li>
<li>The return value of the extension method is printed to the console interface (The return value of the <em>fact</em> method is a Chuck Norris fact that is printed to the console interface).</li>
<li>The extension communicates to the rest of the application through calls to <em>service providers</em> (I&#8217;ll define a service provider shortly).</li>
<li>An extension can be one of two types: <em>simple</em> or <em>namespace</em> (Definition of these will follow).</li>
</ul>
<p><a name="service_provider"></a><br />
<em>What is a service provider?</em><br />
A service provider is an interface to a certain part of the application. It can be seen as a functionality presented through an API.<br />
Lets look at an example: The dradis client side is modeled on a Model-View-Controller architecture. The extension code has access to an instance of the Controller (<em>@controller</em>). The extension does not have direct access to the Model (the Model is the access layer to the data storage). Calls to the Model is made through the data-storage service provider (<em>client/core/service_providers/data_storage.rb</em>. The data-storage service provider has a set of methods (an API) through which you can:</p>
<ul>
<li>add a node &#8211; <em>@controller.request_service(:model_add_node, &#8230;)</em></li>
<li>add a category &#8211; <em>@controller.request_service(:model_add_category, &#8230;)</em></li>
<li>get the contents of a node &#8211; <em>@controller.request_service(:model_find_node, &#8230;)</em></li>
<li>etc.</li>
</ul>
<p>Have a look in the <a href="http://dradis.nomejortu.com/rdoc/classes/Core/Providers.html"><em>client/core/service_providers</em></a> folder for all the currently available service providers.</p>
<p><em>What is a simple extension and a namespace extension?</em><br />
A <strong>simple extension</strong> provides one or more commands that are grouped only by them being members of the extension. A command of a simple extension can be the only command in the current dradis client instance to have the name of that command. It is triggered in the command line console by: <em>command parameters</em>. The <em>chucknorris</em> extension is a simple extension and offers the <em>fact</em> command. No other simple extension can have a command called fact.</p>
<p>A <strong>namespace extension</strong> places its commands in a namespace. One namespace may contain commands with the same name as simple commands or commands in other namespaces. If we want to add a fact command that gives random Bruce Schneier facts then we can create the <em>bruceschneier</em> namespace and place a <em>fact</em> command in it that will not interfere with our Chuck Norris <em>fact</em> command. Namespace commands are called from the commandline in the format: <em>namespace command parameter</em>. The <em>export</em> extension is an example of a namespace extension.</p>
<p><a name="how_to"></a><br />
<strong>How do I write my own extension?</strong></p>
<p>Let&#8217;s have a look at the basic structure of a simple extension. Following is a simplified version of the <em>chucknorris</em> extension:</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
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">module</span> Extensions
  <span style="color:#9966CC; font-weight:bold;">class</span> Chucknorris <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">Extensions::Simple</span>
    <span style="color:#008000; font-style:italic;">#----------------------------------------------------- Dispatcher implementation</span>
    INFO = <span style="color:#006600; font-weight:bold;">&#123;</span>
      <span style="color:#ff3333; font-weight:bold;">:commands</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
        <span style="color:#996600;">'fact'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
          <span style="color:#ff3333; font-weight:bold;">:desc</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'shows a random Chuck Norris fact'</span>,
          <span style="color:#ff3333; font-weight:bold;">:syntax</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span> <span style="color:#006600; font-weight:bold;">&#93;</span>
        <span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
    <span style="color:#008000; font-style:italic;">#----------------------------------------------------- commands implementation</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> fact<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">*</span>args<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#008000; font-style:italic;"># here we implement the magic that gets the new fact and returns it</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<ul>
<li>line 1 &#8211; To implement our extension we need to extend the <em>Extensions</em> module</li>
<li>line 2 &#8211; We define our class to inherit from the <em>Extensions::Simple</em> class</li>
<li>lines 4-11 &#8211; The <em>INFO</em> hash defines all the commands in our extension for the use of the command launcher. In the case of the example above it defines the presence of the <em>fact</em> command with its description and its syntax. In this case there is no syntax defined as the command does not take any parameters.</li>
<li>lines 14-16 &#8211; This is the method implementation of the command that was defined in the <em>INFO</em> hash.</li>
</ul>
<p>Now lets look at a slightly more complex namespace extension. The example is  the <em>add</em> extension that hosts the <em>node</em> and <em>category</em> commands. The syntax for the two command are respectively:</p>
<pre>add node  &lt;parent id&gt; &lt;label&gt;
</pre>
<p>and</p>
<pre>add category &lt;name&gt;
</pre>
<p>This is the code for the extension:</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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">module</span> Extensions
  <span style="color:#9966CC; font-weight:bold;">class</span> Add <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">Extensions::Namespace</span>
    <span style="color:#008000; font-style:italic;">#----------------------------------------------------- private methods</span>
    private
    <span style="color:#008000; font-style:italic;">#----------------------------------------------------- Dispatcher implementation</span>
    INFO = <span style="color:#006600; font-weight:bold;">&#123;</span>
      <span style="color:#ff3333; font-weight:bold;">:namespace</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'add'</span>,
      <span style="color:#ff3333; font-weight:bold;">:description</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'add elements to the project'</span>,
      <span style="color:#ff3333; font-weight:bold;">:commands</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
        <span style="color:#996600;">'node'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
          <span style="color:#ff3333; font-weight:bold;">:desc</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Adds a node to the node tree.'</span>,
          <span style="color:#ff3333; font-weight:bold;">:syntax</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span>
&nbsp;
          <span style="color:#006600; font-weight:bold;">&#123;</span>
            <span style="color:#ff3333; font-weight:bold;">:required</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>,
            <span style="color:#ff3333; font-weight:bold;">:label</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'parent_id'</span>,
            <span style="color:#ff3333; font-weight:bold;">:desc</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'The id of parent to the new node. Use 0 if it is to be a root node.'</span>,
            <span style="color:#ff3333; font-weight:bold;">:regexp</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">/</span>^\d<span style="color:#006600; font-weight:bold;">*</span>$<span style="color:#006600; font-weight:bold;">/</span>
          <span style="color:#006600; font-weight:bold;">&#125;</span>,
          <span style="color:#006600; font-weight:bold;">&#123;</span>
            <span style="color:#ff3333; font-weight:bold;">:required</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>,
            <span style="color:#ff3333; font-weight:bold;">:label</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'label'</span>,
            <span style="color:#ff3333; font-weight:bold;">:desc</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'The label/name of the new node.'</span>,
            <span style="color:#ff3333; font-weight:bold;">:regexp</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">/</span>^\w<span style="color:#006600; font-weight:bold;">&#91;</span>\w\s<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">*</span>$<span style="color:#006600; font-weight:bold;">/</span>
          <span style="color:#006600; font-weight:bold;">&#125;</span>
          <span style="color:#006600; font-weight:bold;">&#93;</span>
        <span style="color:#006600; font-weight:bold;">&#125;</span>,
        <span style="color:#996600;">'category'</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
          <span style="color:#ff3333; font-weight:bold;">:desc</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Adds a note category.'</span>,
          <span style="color:#ff3333; font-weight:bold;">:syntax</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span>
          <span style="color:#006600; font-weight:bold;">&#123;</span>
            <span style="color:#ff3333; font-weight:bold;">:required</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>,
            <span style="color:#ff3333; font-weight:bold;">:label</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'name'</span>,
            <span style="color:#ff3333; font-weight:bold;">:desc</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'name of the new category'</span>,
            <span style="color:#ff3333; font-weight:bold;">:regexp</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">/</span>^\w<span style="color:#006600; font-weight:bold;">&#91;</span>\w\s<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">*</span>$<span style="color:#006600; font-weight:bold;">/</span>
          <span style="color:#006600; font-weight:bold;">&#125;</span>
          <span style="color:#006600; font-weight:bold;">&#93;</span>
        <span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># Implements the add node fucntionality. See the above for allowed parameters</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> node<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">*</span>args<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#008000; font-style:italic;"># the parent_id needs to be an integer or a nil value</span>
      args<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> = args<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span> == <span style="color:#996600;">'0'</span> ? <span style="color:#0000FF; font-weight:bold;">nil</span> : args<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">to_i</span>
      <span style="color:#008000; font-style:italic;"># call the service provider to add a node with the specified parameters</span>
      <span style="color:#0066ff; font-weight:bold;">@controller</span>.<span style="color:#9900CC;">request_service</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:model_add_node</span>, args<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#0000FF; font-weight:bold;">nil</span>, args<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#996600;">&quot;Added node: #{args[2]}&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># Implements the add category fucntionality. See the above for allowed parameters</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> category<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">*</span>args<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#008000; font-style:italic;"># call the service provider to add a node with the specified parameters</span>
      <span style="color:#0066ff; font-weight:bold;">@controller</span>.<span style="color:#9900CC;">request_service</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:model_add_category</span>, args<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#996600;">&quot;Added category: #{args[1]}&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>I&#8217;ll highlight the important and new bits of code:</p>
<ul>
<li>line 2 &#8211; Different that in the previous example we define this extension to inherit from the <em>Extensions::Namespace</em> class</li>
<li>line 7 &#8211; In the <em>INFO</em> hash we define the namespace <em>add</em>. The contents associated with the <em>add</em> hash key defines the commands in the namespace.</li>
<li>lines 9-38 &#8211; Here we define our commads in a very similar fashion as in the previous example. We have added the complexity of each command accepting some parameters. This is defined by the array assigned to the <em>syntax</em> key</li>
<li>line 14 &#8211; States that the parameter is compulsary</li>
<li>line 15 &#8211; This is the displayed name of the parameter</li>
<li>line 16 &#8211; Defines the description of the command that will be printed in the help display of the command</li>
<li>line 17 &#8211; Specifies the regular expression by which the parameter will be validated by the command launcher</li>
<li>lines 42-55 &#8211; This is the implementation of the commands as defined in the <em>INFO</em> hash</li>
<li>line 44 &#8211; The args array contains the parameters that was passed. args[0] is the command, <em>node</em> in this case. args[1] contains the <em>parent_id</em> and args[2] contains the <em>label</em></li>
<li>line 46 &#8211; This is an example of a call to a service provider in this case it calls a method in the data-storage service provider. (See the <a href="#service_provider">architecture section</a> for a full discussion on this)</li>
<li>line 47 &#8211; The return value will be displayed in the command line console.</li>
</ul>
<p>As a last bit of advice:</p>
<ul>
<li>Name your extension file, class and if applicable namespace the same name</li>
<li>If you add something new to the data storage you might find that you can not reference the newly added record immediately. The reason is that you have to wait for the local cache of the data storage to be refreshed. You can force a refresh with a <em>@controller.request_service(:model_knowledge_refresh)</em> call.</li>
</ul>
<p>That should leave you with a good understanding of dradis extensions.</p>
<p>As always &#8211; Happy dradis coding!</p>
<img src="http://usefulfor.com/ruby/?ak_action=api_record_view&id=84&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://usefulfor.com/ruby/2009/02/17/dradis-extensions-how-they-work-and-how-to-write-them/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>dradis reporting: quick &amp; neat word export</title>
		<link>http://usefulfor.com/ruby/2009/02/15/dradis-reporting-quick-neat-word-export/</link>
		<comments>http://usefulfor.com/ruby/2009/02/15/dradis-reporting-quick-neat-word-export/#comments</comments>
		<pubDate>Sun, 15 Feb 2009 15:55:43 +0000</pubDate>
		<dc:creator>etd</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[dradis]]></category>

		<guid isPermaLink="false">http://usefulfor.com/ruby/?p=83</guid>
		<description><![CDATA[With over 800 downloads in the first two weeks of dradis v2.0, there is lots of interest on what is going to be next. We are working on solutions for importing and exporting data to and from the repository, but for those of you that can&#8217;t wait, we have put together a plug-in for the [...]]]></description>
			<content:encoded><![CDATA[<p>With over 800 downloads in the first two weeks of <a href="http://dradis.sourceforge.net/">dradis v2.0</a>, there is lots of interest on what is going to be next. We are working on solutions for importing and exporting data to and from the repository, but for those of you that can&#8217;t wait, we have put together a plug-in for the server that exports your notes to a Word file.</p>
<p>It is not the final solution, and it is not integrated with the web interface, but hopefully it will give you an idea of how easy is to get your own exporting modules for dradis.<br />
<span id="more-83"></span></p>
<h3>The Template</h3>
<p>So the first step was to use Word to generate a template we could use for our export plug-in. I just created a simple empty document that looked like this:-</p>
<p><img src="http://usefulfor.com/ruby/files/2009/02/word-template.png" alt="" width="500" height="242" class="aligncenter size-full wp-image-109" /></p>
<p>Save your template as an XML document (you can get mine here: <a href="http://usefulfor.com/ruby/files/2009/02/template.xml">template.xml</a>). The template contains these sections:-</p>
<ul>
<li>Issue title</li>
<li>Date of discovery</li>
<li>Issue description</li>
<li>Mitigation recommendations</li>
<li>Additional information</li>
</ul>
<p>What our plug-in is going to do is to walk through the notes in the repository and repeat this template for each one. In order for the code to find the different sections, you have to edit the XML file an add some <code>id</code> attributes to the tags associated with the sections. For instance:</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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
</pre></td><td class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">&lt;!-- Note Section --&gt;</span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;wx:sub-section<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;w:p</span> <span style="color: #000066;">wsp:rsidR</span>=<span style="color: #ff0000;">&quot;005F557A&quot;</span> <span style="color: #000066;">wsp:rsidRDefault</span>=<span style="color: #ff0000;">&quot;00C27C1C&quot;</span> <span style="color: #000066;">wsp:rsidP</span>=<span style="color: #ff0000;">&quot;00C27C1C&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;w:pPr<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;w:pStyle</span> <span style="color: #000066;">w:val</span>=<span style="color: #ff0000;">&quot;Heading1&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/w:pPr<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;w:r<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;w:t</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;vulntitle&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>Directory Listings<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/w:t<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/w:r<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/w:p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;w:p</span> <span style="color: #000066;">wsp:rsidR</span>=<span style="color: #ff0000;">&quot;00C27C1C&quot;</span> <span style="color: #000066;">wsp:rsidRPr</span>=<span style="color: #ff0000;">&quot;00C27C1C&quot;</span> <span style="color: #000066;">wsp:rsidRDefault</span>=<span style="color: #ff0000;">&quot;00C27C1C&quot;</span> <span style="color: #000066;">wsp:rsidP</span>=<span style="color: #ff0000;">&quot;00C27C1C&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;w:pPr<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;w:jc</span> <span style="color: #000066;">w:val</span>=<span style="color: #ff0000;">&quot;right&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;w:rPr<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;w:rFonts</span> <span style="color: #000066;">w:ascii</span>=<span style="color: #ff0000;">&quot;Arial&quot;</span> <span style="color: #000066;">w:h-ansi</span>=<span style="color: #ff0000;">&quot;Arial&quot;</span> <span style="color: #000066;">w:cs</span>=<span style="color: #ff0000;">&quot;Arial&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;wx:font</span> <span style="color: #000066;">wx:val</span>=<span style="color: #ff0000;">&quot;Arial&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;w:sz</span> <span style="color: #000066;">w:val</span>=<span style="color: #ff0000;">&quot;16&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;w:sz-cs</span> <span style="color: #000066;">w:val</span>=<span style="color: #ff0000;">&quot;16&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/w:rPr<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/w:pPr<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;w:r</span> <span style="color: #000066;">wsp:rsidRPr</span>=<span style="color: #ff0000;">&quot;00C27C1C&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;w:rPr<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;w:rFonts</span> <span style="color: #000066;">w:ascii</span>=<span style="color: #ff0000;">&quot;Arial&quot;</span> <span style="color: #000066;">w:h-ansi</span>=<span style="color: #ff0000;">&quot;Arial&quot;</span> <span style="color: #000066;">w:cs</span>=<span style="color: #ff0000;">&quot;Arial&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span><span style="color: #000000; font-weight: bold;">&lt;wx:font</span> <span style="color: #000066;">wx:val</span>=<span style="color: #ff0000;">&quot;Arial&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span><span style="color: #000000; font-weight: bold;">&lt;w:sz</span> <span style="color: #000066;">w:val</span>=<span style="color: #ff0000;">&quot;16&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span><span style="color: #000000; font-weight: bold;">&lt;w:sz-cs</span> <span style="color: #000066;">w:val</span>=<span style="color: #ff0000;">&quot;16&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/w:rPr<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;w:t</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;vulncreated&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>2009-02-10 00:07 GMT<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/w:t<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/w:r<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/w:p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;wx:sub-section</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;vulndesc&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;w:p</span> <span style="color: #000066;">wsp:rsidR</span>=<span style="color: #ff0000;">&quot;00C27C1C&quot;</span> <span style="color: #000066;">wsp:rsidRDefault</span>=<span style="color: #ff0000;">&quot;00C27C1C&quot;</span> <span style="color: #000066;">wsp:rsidP</span>=<span style="color: #ff0000;">&quot;00C27C1C&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;w:pPr<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;w:pStyle</span> <span style="color: #000066;">w:val</span>=<span style="color: #ff0000;">&quot;Heading2&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/w:pPr<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;w:r<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;w:t<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Description<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/w:t<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/w:r<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/w:p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wx:sub-section<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;wx:sub-section</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;vulnrec&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;w:p</span> <span style="color: #000066;">wsp:rsidR</span>=<span style="color: #ff0000;">&quot;00C27C1C&quot;</span> <span style="color: #000066;">wsp:rsidRDefault</span>=<span style="color: #ff0000;">&quot;00C27C1C&quot;</span> <span style="color: #000066;">wsp:rsidP</span>=<span style="color: #ff0000;">&quot;00C27C1C&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;w:pPr<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;w:pStyle</span> <span style="color: #000066;">w:val</span>=<span style="color: #ff0000;">&quot;Heading2&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/w:pPr<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;w:r<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;w:t<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Recommendation<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/w:t<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/w:r<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/w:p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wx:sub-section<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;wx:sub-section</span> <span style="color: #000066;">id</span>=<span style="color: #ff0000;">&quot;vulnextra&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;w:p</span> <span style="color: #000066;">wsp:rsidR</span>=<span style="color: #ff0000;">&quot;00C27C1C&quot;</span> <span style="color: #000066;">wsp:rsidRDefault</span>=<span style="color: #ff0000;">&quot;00C27C1C&quot;</span> <span style="color: #000066;">wsp:rsidP</span>=<span style="color: #ff0000;">&quot;00C27C1C&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;w:pPr<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;w:pStyle</span> <span style="color: #000066;">w:val</span>=<span style="color: #ff0000;">&quot;Heading2&quot;</span><span style="color: #000000; font-weight: bold;">/&gt;</span><span style="color: #000000; font-weight: bold;">&lt;/w:pPr<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;w:r<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;w:t<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Additional Information<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/w:t<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/w:r<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/w:p<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wx:sub-section<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/wx:sub-section<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #808080; font-style: italic;">&lt;!-- /Note Section --&gt;</span></pre></td></tr></table></div>

<ul>
<li>Issue title: <code>&lt;w:t id="vulntitle"&gt;</code> (line 7)</li>
<li>Date of discovery: <code>&lt;w:t id="vulncreated"&gt;</code> (line 21)</li>
<li>Issue description: <code>&lt;wx:sub-section id="vulndesc"&gt;</code> (line 25)</li>
<li>Mitigation recommendations: <code>&lt;wx:sub-section id="vulnrec"&gt;</code> (line 32)</li>
<li>Additional information: <code>&lt;wx:sub-section id="vulnextra"&gt;</code> (line 39)</li>
</ul>
<p>For the issue title and the date of discovery we will be modifying the <code>text</code> of the XML node. For the description, recommendation and additional information we will be attaching child nodes to the one tagged.</p>
<h3>The Code-fu</h3>
<p>We are already thinking on ways of mapping your template sections with you repository fields, but for the time being most of the information is extracted from the the Note text. So the structure of our notes would be:-</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre>Title:
Whatever is the title of the issue

Descripton:
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
commodo consequat.

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Recommendation:
Sed ut perspiciatis unde omnis iste natus error sit voluptatem
accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab
illo inventore veritatis et quasi architecto beatae vitae dicta sunt
explicabo.

Additional stuff:
- this and that
- blah blah</pre></div></div>
<p>The code will take the Note text, then apply a regular expression to find the different sections and extract the fields used in the template:-</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="ruby" style="font-family:monospace;">  Note.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>n<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#008000; font-style:italic;">#... more stuff here</span>
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;processing Note #{n.id}&quot;</span>
    fields = n.<span style="color:#9900CC;">text</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span>.<span style="color:#006600; font-weight:bold;">+</span>?:\n.<span style="color:#006600; font-weight:bold;">*</span>?<span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">collect</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>field<span style="color:#006600; font-weight:bold;">|</span> field.<span style="color:#9900CC;">strip</span> <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#008000; font-style:italic;">#... more stuff here</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>The code will be smart enough to detect if the <em>Additional stuff</em> section is present or not, this is done by simply counting the number of extracted fields.</p>
<h4>The XML Documents</h4>
<p>For To process XML we will be using <a href="http://www.germane-software.com/software/rexml/">REXML</a>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">begin</span>
  doc = <span style="color:#6666ff; font-weight:bold;">REXML::Document</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'./vendor/plugins/word_export/template.xml'</span>,<span style="color:#996600;">'r'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#6666ff; font-weight:bold;">REXML::ParseException</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> e <span style="color:#008000; font-style:italic;"># re-raise exception</span>
  <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#CC00FF; font-weight:bold;">Exception</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>e<span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
vulns = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
body = <span style="color:#6666ff; font-weight:bold;">REXML::XPath</span>.<span style="color:#9900CC;">first</span><span style="color:#006600; font-weight:bold;">&#40;</span>doc, <span style="color:#996600;">'//w:body'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
vuln_template = <span style="color:#6666ff; font-weight:bold;">REXML::Document</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span> doc.<span style="color:#9900CC;">root</span>.<span style="color:#9900CC;">clone</span>.<span style="color:#9900CC;">to_s</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
vuln_template.<span style="color:#9900CC;">root</span>.<span style="color:#9900CC;">add</span> body.<span style="color:#9900CC;">children</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">3</span><span style="color:#006600; font-weight:bold;">&#93;</span></pre></td></tr></table></div>

<p>First we need to load the template, then in lines 8-10 we locate the section of the code we will be repeating for each Note. and store a copy of the full section in <code>vuln_template</code>. </p>
<p>Using <code>REXML</code> there are two ways of copying an XML node, one is with <code>element.clone()</code> (that will create a copy of the node, but not of its children) and the other is creating a new document: <code>Document.new( element.to_s )</code> (that will create a swallow copy). Ideally I would have created a new Document with the subsection that contains the template for the Note, however, Word defines a number of XML namespaces at the begining of the document, and REXML complains if we try to create a document without the right namespaces (this would be a simple: <code>Document.new(body.children[3].to_s)</code>).</p>
<p>So instead we need to create a new document that contains the Word namespaces, and then include the Note template we want to use. We do this by cloning the root node of the original document and then attaching the desired structure of the Note.</p>
<p>Also note in line 7 we are initialising an array of vulnerabilities. We will be looping through our notes and filling in the template with the information contained in the Note text and storing the vulnerability in this array. Afterwards, we will attach all the vulnerabilities to the <code>w:body</code> of our document.</p>
<h4>Filling in the template</h4>
<p>So for each Note we need to create a new XML section that will be stored in the <code>vulns</code> array. This is done by duplicating the <code>vuln_template</code> and filling it with content from the Note.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">v = <span style="color:#6666ff; font-weight:bold;">REXML::Document</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>vuln_template.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>The rest of the code is standard XML processing. For the Title and Date fields, just assign the text of the node:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;">#title</span>
title = <span style="color:#6666ff; font-weight:bold;">REXML::XPath</span>.<span style="color:#9900CC;">first</span><span style="color:#006600; font-weight:bold;">&#40;</span>v, <span style="color:#996600;">&quot;//w:t[@id='vulntitle']&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> 
title.<span style="color:#9900CC;">delete_attribute</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'id'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
title.<span style="color:#9900CC;">text</span> = fields<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span></pre></td></tr></table></div>

<p>For the Description, Recommendation and Additional information sections, we create a new XML paragraph for each paragraph in the original text:</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
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">description = <span style="color:#6666ff; font-weight:bold;">REXML::XPath</span>.<span style="color:#9900CC;">first</span><span style="color:#006600; font-weight:bold;">&#40;</span>v, <span style="color:#996600;">&quot;//wx:sub-section[@id='vulndesc']&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
description.<span style="color:#9900CC;">delete_attribute</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'id'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
fields<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;<span style="color:#000099;">\n</span><span style="color:#000099;">\n</span>&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>paragraph<span style="color:#006600; font-weight:bold;">|</span>
  par = <span style="color:#6666ff; font-weight:bold;">REXML::Element</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'w:t'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  par.<span style="color:#9900CC;">text</span> = paragraph
  r = <span style="color:#6666ff; font-weight:bold;">REXML::Element</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'w:r'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  r.<span style="color:#9900CC;">elements</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> par
  chunk = <span style="color:#6666ff; font-weight:bold;">REXML::Element</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'w:p'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  chunk.<span style="color:#9900CC;">attributes</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'wsp:rsidR'</span><span style="color:#006600; font-weight:bold;">&#93;</span>=<span style="color:#996600;">'00C27C1C'</span> 
  chunk.<span style="color:#9900CC;">attributes</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'wsp:rsidRDefault'</span><span style="color:#006600; font-weight:bold;">&#93;</span>=<span style="color:#996600;">'00C27C1C'</span>
  chunk.<span style="color:#9900CC;">attributes</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'wsp:rsidP'</span><span style="color:#006600; font-weight:bold;">&#93;</span>=<span style="color:#996600;">'00C27C1C'</span>
  chunk.<span style="color:#9900CC;">elements</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> r
  description.<span style="color:#9900CC;">elements</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> chunk 
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<h4>Attaching the Vulnerabilities to the Document</h4>
<p>Finally we need to attach all the vulnerabilities to the body of the main document. This is done with the following code:-</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">vulns.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>v<span style="color:#006600; font-weight:bold;">|</span>
  body.<span style="color:#9900CC;">insert_before</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'//w:sectPr'</span>, v.<span style="color:#9900CC;">root</span>.<span style="color:#9900CC;">children</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>  
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Note that we are not adding the root element, but its first child. This is because the root element is <code>w:wordDocument</code> tag that contains the namespace declarations as already discussed.</p>
<p>And the last thing that is left is to write the document in our output <code>report.xml</code> file:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">doc.<span style="color:#9900CC;">write</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'report.xml'</span>,<span style="color:#996600;">'w'</span><span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span>, <span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<h3>Get the Plug-in</h3>
<p>The plugin is already in the repository (in <a href="http://dradis.svn.sourceforge.net/viewvc/dradis/server/trunk/vendor/plugins/">server/trunk/vendor/plugins/</a>), but if you have dradis already in your box you can get it by going to the <strong>server</strong> folder and executing:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">ruby script\plugin <span style="color: #c20cb9; font-weight: bold;">install</span> http:<span style="color: #000000; font-weight: bold;">//</span>dradis.svn.sourceforge.net<span style="color: #000000; font-weight: bold;">/</span>svnroot<span style="color: #000000; font-weight: bold;">/</span>dradis<span style="color: #000000; font-weight: bold;">/</span>server<span style="color: #000000; font-weight: bold;">/</span>trunk<span style="color: #000000; font-weight: bold;">/</span>vendor<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>word_export<span style="color: #000000; font-weight: bold;">/</span></pre></div></div>

<p>And to run it:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">rake <span style="color: #7a0874; font-weight: bold;">export</span>:word</pre></div></div>

<p>Just remember that you need your notes to formatted as the plugin expects. You can download a sample <a href="http://usefulfor.com/ruby/files/2009/02/development.sqlite3">development.sqlite3</a>. </p>
<img src="http://usefulfor.com/ruby/?ak_action=api_record_view&id=83&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://usefulfor.com/ruby/2009/02/15/dradis-reporting-quick-neat-word-export/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Use Rails to Create a Static Site</title>
		<link>http://usefulfor.com/ruby/2009/02/04/use-rails-to-create-a-static-site/</link>
		<comments>http://usefulfor.com/ruby/2009/02/04/use-rails-to-create-a-static-site/#comments</comments>
		<pubDate>Wed, 04 Feb 2009 12:00:16 +0000</pubDate>
		<dc:creator>etd</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[dradis]]></category>
		<category><![CDATA[Add new tag]]></category>

		<guid isPermaLink="false">http://usefulfor.com/ruby/?p=75</guid>
		<description><![CDATA[One of the new things we released last week with dradis v2.0 was a new web site for the project (dradis.sourceforge.net).
The old site consisted of 20 static pages or so, which was nice and easy but a real pain to maintain or restructure. So we thought that letting Rails do the heavy lifting for us [...]]]></description>
			<content:encoded><![CDATA[<p>One of the new things we released last week with <a href="/security/2009/01/30/dradis-v2/">dradis v2.0</a> was a new web site for the project (<a href="http://dradis.sourceforge.net/">dradis.sourceforge.net</a>).</p>
<p>The old site consisted of 20 static pages or so, which was nice and easy but a real pain to maintain or restructure. So we thought that letting Rails do the heavy lifting for us would be a good idea, but we did not want to set up a Rail environment in the server&#8230;</p>
<p>What we finally did is use Rails as a tool to create a static site that we could <em>.tar.gz</em> and upload to the server. As a starting point we used a post in <a href="http://www.chuckvose.com/articles/2006/04/20/monkey">www.chuckvose.com</a> and this is how we completed it to fit our needs.</p>
<p><strong>Follow up</strong> (2009-03-23): do not miss how to integrate your rails-static site with Rake and Subversion in the second article of this series: <a href="http://usefulfor.com/ruby/2009/03/23/use-rails-to-create-a-static-site-rake-and-subversion/">Use Rails to Create a Static Site: Rake and Subversion</a>.</p>
<p><span id="more-75"></span><br />
<a name="thecontroller"></a></p>
<h3>The Controller</h3>
<p>We just need one action in our main controller (<code>PagesController</code>):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> PagesController <span style="color:#006600; font-weight:bold;">&lt;</span> ApplicationController
  layout <span style="color:#996600;">'main'</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> index
    <span style="color:#0066ff; font-weight:bold;">@page</span> = params.<span style="color:#9900CC;">fetch</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:id</span>, <span style="color:#996600;">'index'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    expanded_page = <span style="color:#996600;">&quot;#{RAILS_ROOT}/app/views/pages/#{@page}.html.erb&quot;</span>
    exists = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">expand_path</span><span style="color:#006600; font-weight:bold;">&#40;</span>expanded_page<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> exists
      render <span style="color:#ff3333; font-weight:bold;">:action</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@page</span>
    <span style="color:#9966CC; font-weight:bold;">else</span>
      render <span style="color:#ff3333; font-weight:bold;">:text</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;#{expanded_page} doesn't exist&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>We <code>fetch</code> the <strong>:id</strong> parameter from the request that contains the name of the requested page (or <code>index</code> by default), then we try to locate the corresponding file (in <code>/app/views/pages/</code>) and if found we render the action. Rendering the action with no action code in the controller will just render it&#8217;s <a href="http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/classes/ERB.html">ERB</a> template which is exactly what we want.</p>
<p>We also added a couple of routes in <code>/config/routes.rb</code> so every time a something<strong>.html</strong> was requested, the <code>PagesController</code> would be invoked:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">map.<span style="color:#9900CC;">root</span> <span style="color:#ff3333; font-weight:bold;">:controller</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'pages'</span>
map.<span style="color:#9900CC;">connect</span> <span style="color:#996600;">':id.html'</span>, <span style="color:#ff3333; font-weight:bold;">:controller</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'pages'</span>, <span style="color:#ff3333; font-weight:bold;">:action</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'index'</span></pre></div></div>

<h3>The Layout and the Pages</h3>
<p>The layout we used was quite simple. The most interesting bits follow.</p>
<p>First, we want each page to be able to set their own HTML title. This is accomplished by including the following code in the  layout:-</p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;">&lt;head&gt;
  &lt;title&gt;<span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#9966CC; font-weight:bold;">yield</span> <span style="color:#ff3333; font-weight:bold;">:title</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>&lt;/title&gt;
&lt;/head&gt;</pre></div></div>

<p>Then pages must include this line to set the contents of the <strong>:title</strong> variable:-</p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#5A0A0A; font-weight:bold;">content_for</span> <span style="color:#ff3333; font-weight:bold;">:title</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>Announcements - dradis<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">%&gt;</span></pre></div></div>

<p>Other than that, we used the standard <code>@content_for_layout</code> in the main section of the page. However, the site has two menus, one in the top and one in the right hand side. This exposes a new challenge because we need to create the structure of the page in a way that is simple enough to maintain and add new content in the future. We had to code some Rails helpers to aid us in this.</p>
<h3>The Helpers</h3>
<h4>The Top Menu</h4>
<p><img src="http://usefulfor.com/ruby/files/2009/02/dradis2_topmenu.png" alt="" width="409" height="35" class="aligncenter size-full wp-image-79" /></p>
<p>The Top menu bar consists only of the main sections of the site. In the layout we call the Helper straight away passing the current page (see <a href="#thecontroller">The Controller</a> above):</p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;">&lt;div class=&quot;bar&quot;&gt;
&lt;ul&gt;
  <span style="color:#006600; font-weight:bold;">&lt;%</span>= barmenu<span style="color:#006600; font-weight:bold;">&#40;</span>@page<span style="color:#006600; font-weight:bold;">&#41;</span>; <span style="color:#006600; font-weight:bold;">%&gt;</span>
&lt;/ul&gt;
&lt;/div&gt;</pre></div></div>

<p>The code of the helper in this instance is quite simple. The only intelligence we are adding is a check to see if the current page is one of the items in the menu, if it is, we add the CSS <strong>active</strong> class to the list item.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> barmenu<span style="color:#006600; font-weight:bold;">&#40;</span>page<span style="color:#006600; font-weight:bold;">&#41;</span>
    items = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'download'</span>, <span style="color:#996600;">'demo'</span>, <span style="color:#996600;">'screenshots'</span>, <span style="color:#996600;">'documentation'</span> <span style="color:#006600; font-weight:bold;">&#93;</span>
    items.<span style="color:#9900CC;">collect</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>i<span style="color:#006600; font-weight:bold;">|</span>
      active = <span style="color:#996600;">''</span>
      label = i.<span style="color:#9900CC;">capitalize</span>
      <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>page == i<span style="color:#006600; font-weight:bold;">&#41;</span>
        active = <span style="color:#996600;">' class=&quot;active&quot;'</span>
      <span style="color:#9966CC; font-weight:bold;">else</span>
        label = <span style="color:#996600;">&quot;&lt;a href=<span style="color:#000099;">\&quot;</span>#{i}.html<span style="color:#000099;">\&quot;</span>&gt;#{i.capitalize}&lt;/a&gt;&quot;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
      <span style="color:#996600;">&quot;&lt;li#{active}&gt;#{label}&lt;/li&gt;&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<h4>Right Hand Side Navigation</h4>
<p><img src="http://usefulfor.com/ruby/files/2009/02/dradis2_navigation.png" alt="" width="275" height="253" class="alignright size-full wp-image-80" /><br />
The navigation menu in the right side was a bit trickier. We had our pages organised in three different sections: <em>using dradis</em>, <em>developing dradis</em> and <em>support from</em>. </p>
<p>Each section contains a number of items, some of the items have our content, some are links to external sites. In addition to this it would be useful if we could nest subsections as shown in the screenshot of the right.</p>
<p>So we had to figure out a way of representing the structure of the menu. Probably the neatest solution would have been to create an HTML page that contained a series of nested <code>ul</code> and <code>li</code> elements and then make the helper parse that structure assign the <strong>active</strong> CSS class to the right element and display it. Or maybe using a fancy JavaScript trick to locate the active item and assign the CSS class. However, as often happens we needed a solution, and it had to be fast, so we opted for having the structure loaded in a ruby array with one <code>Hash</code> per section:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#ff6633; font-weight:bold;">$sections</span> = <span style="color:#006600; font-weight:bold;">&#91;</span>
  <span style="color:#006600; font-weight:bold;">&#123;</span> ... <span style="color:#006600; font-weight:bold;">&#125;</span>, <span style="color:#008000; font-style:italic;"># using dradis</span>
  <span style="color:#006600; font-weight:bold;">&#123;</span>
    <span style="color:#ff3333; font-weight:bold;">:title</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'developing dradis'</span>,
    <span style="color:#ff3333; font-weight:bold;">:pages</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span>
      <span style="color:#006600; font-weight:bold;">&#123;</span>
        <span style="color:#ff3333; font-weight:bold;">:title</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'info. for developers'</span>,
        <span style="color:#ff3333; font-weight:bold;">:url</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'developers.html'</span>,
        <span style="color:#ff3333; font-weight:bold;">:pages</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span> <span style="color:#ff3333; font-weight:bold;">:extensions</span> <span style="color:#006600; font-weight:bold;">&#93;</span>
      <span style="color:#006600; font-weight:bold;">&#125;</span>,
      <span style="color:#ff3333; font-weight:bold;">:roadmap</span>,
      <span style="color:#006600; font-weight:bold;">&#123;</span>
        <span style="color:#ff3333; font-weight:bold;">:title</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:bug_tracker</span>,
        <span style="color:#ff3333; font-weight:bold;">:url</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'http://sourceforge.net/tracker/?atid=1010917&amp;group_id=209736&amp;func=browse'</span>
      <span style="color:#006600; font-weight:bold;">&#125;</span>,
      <span style="color:#006600; font-weight:bold;">&#123;</span>
        <span style="color:#ff3333; font-weight:bold;">:title</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:feature_requests</span>,
        <span style="color:#ff3333; font-weight:bold;">:url</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'http://sourceforge.net/tracker/?atid=1010920&amp;group_id=209736&amp;func=browse'</span>
      <span style="color:#006600; font-weight:bold;">&#125;</span>,
      <span style="color:#006600; font-weight:bold;">&#123;</span>
        <span style="color:#ff3333; font-weight:bold;">:title</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:subversion</span>,
        <span style="color:#ff3333; font-weight:bold;">:url</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'http://sourceforge.net/svn/?group_id=209736'</span>
      <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#006600; font-weight:bold;">&#125;</span>,
  <span style="color:#006600; font-weight:bold;">&#123;</span> ... <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#008000; font-style:italic;"># support from</span>
<span style="color:#006600; font-weight:bold;">&#93;</span></pre></div></div>

<p>Each of the three section <code>Hash</code>es has a <code>:title</code> and a <code>:pages</code> attribute. The latter is an array containing the information of the pages associated with the parent section. The elements of the array can be either <code>Symbol</code>s or new <code>Hash</code>es that describe the different pages.</p>
<p>We use a <code>Symbol</code> if the content of the page is provided by the site such as in the <strong>:roadmap</strong> case whose contents are in <code>/app/views/pages/roadmap.html.erb</code> and the link displayed in the menu would be &#8220;roadmap&#8221;. In more complex cases (i.e. we want a custom title for the link or a section that contains subsections) we use a <code>Hash</code>.</p>
<p>When a <code>Hash</code> is used at least a <strong>:title</strong> and a <strong>:url</strong> elements must be provided. Optionally a <strong>:pages</strong> element can be used to nest sections inside sections. The format of this <strong>:pages</strong> value is again an array as the one used in the top level section. So there you have your recursion!</p>
<p>The helper in this case is a bit more complex. First, the call in the layout, nothing fancy here:</p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;">&lt;div&gt;
  <span style="color:#006600; font-weight:bold;">&lt;%</span>= rightmenu<span style="color:#006600; font-weight:bold;">&#40;</span>@page<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
&lt;/div&gt;</pre></div></div>

<p>The <code>rightmenu()</code> helper code:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> rightmenu<span style="color:#006600; font-weight:bold;">&#40;</span>page<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#ff6633; font-weight:bold;">$sections</span>.<span style="color:#9900CC;">collect</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>section<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#996600;">&quot;&lt;h3&gt;#{section[:title]}:&lt;/h3&gt;&quot;</span> <span style="color:#006600; font-weight:bold;">+</span> sectionmenu<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:page</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> page, <span style="color:#ff3333; font-weight:bold;">:section</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> section<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Each main section is enclosed in <code>h3</code> tags and then <code>sectionmenu</code> (a helper-to-the-helper method <img src='http://usefulfor.com/ruby/wp-includes/images/smilies/icon_rolleyes.gif' alt=':roll:' class='wp-smiley' />  ) is invoked for each section. There are some tricks going on in the following piece of code, have a look and we will nail it down later:</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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> sectionmenu<span style="color:#006600; font-weight:bold;">&#40;</span>options = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    current_page = options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:page</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    section = options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:section</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    level = options.<span style="color:#9900CC;">fetch</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:level</span>, <span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    css = options.<span style="color:#9900CC;">fetch</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:css</span>, <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'right_articles'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    css <span style="color:#006600; font-weight:bold;">|</span>= <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;submenu#{level}&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>level <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    section<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:pages</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">collect</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>page<span style="color:#006600; font-weight:bold;">|</span>
      <span style="color:#008000; font-style:italic;"># If the last item was the active one, clear the flag</span>
      css.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'active'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> css.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'active'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      title = <span style="color:#996600;">''</span>
      url = <span style="color:#996600;">''</span>
      complex = <span style="color:#0000FF; font-weight:bold;">false</span>
&nbsp;
      <span style="color:#008000; font-style:italic;"># simple page (Symbol) vs. complex page (Hash)</span>
      <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>page.<span style="color:#9966CC; font-weight:bold;">class</span> == <span style="color:#CC00FF; font-weight:bold;">Hash</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        complex = <span style="color:#0000FF; font-weight:bold;">true</span>
        title = page<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:title</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">to_s</span>.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span>_<span style="color:#006600; font-weight:bold;">/</span>,<span style="color:#996600;">' '</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        url = page<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:url</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      <span style="color:#9966CC; font-weight:bold;">else</span>
        title = page.<span style="color:#9900CC;">to_s</span>.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span>_<span style="color:#006600; font-weight:bold;">/</span>,<span style="color:#996600;">' '</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        url = page.<span style="color:#9900CC;">to_s</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">'.html'</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      <span style="color:#008000; font-style:italic;"># active vs. inactive</span>
      <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>current_page <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">'.html'</span> == url<span style="color:#006600; font-weight:bold;">&#41;</span>
        css <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">'active'</span>
      <span style="color:#9966CC; font-weight:bold;">else</span>
        title = <span style="color:#996600;">&quot;&lt;a href=<span style="color:#000099;">\&quot;</span>#{url}<span style="color:#000099;">\&quot;</span>&gt;#{title}&lt;/a&gt;&quot;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      <span style="color:#008000; font-style:italic;"># subsections</span>
      <span style="color:#008000; font-style:italic;"># tradeoff: calculate the sub section,</span>
      <span style="color:#008000; font-style:italic;"># if it doesn't contain the &quot;active&quot; page, don't use it</span>
      subsection = <span style="color:#996600;">''</span>
      <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>complex <span style="color:#006600; font-weight:bold;">&amp;&amp;</span> page.<span style="color:#9900CC;">key</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:pages</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        subsection =  sectionmenu<span style="color:#006600; font-weight:bold;">&#40;</span>
            <span style="color:#ff3333; font-weight:bold;">:page</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> current_page,
            <span style="color:#ff3333; font-weight:bold;">:section</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> page,
            <span style="color:#ff3333; font-weight:bold;">:level</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> level <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">1</span>
        <span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
        found = !<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span>active<span style="color:#006600; font-weight:bold;">/</span> =~ subsection<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>?
        <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span> !found <span style="color:#006600; font-weight:bold;">&amp;&amp;</span> !css.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'active'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
          subsection = <span style="color:#996600;">''</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      <span style="color:#996600;">&quot;&lt;div class=<span style="color:#000099;">\&quot;</span>#{css.join(' ')}<span style="color:#000099;">\&quot;</span>&gt;#{title}&lt;/div&gt;&quot;</span> <span style="color:#006600; font-weight:bold;">+</span> subsection
    <span style="color:#9966CC; font-weight:bold;">end</span>.<span style="color:#9900CC;">join</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

<p>In lines 2 to 6 we initialise the properties for this section. Then for each page in the section we apply the loop in 8 to 51. Due to the way the data is structured in the <code>$sections</code> variable, this code can be used to recursively crawl the tree of sections and subsections.</p>
<p>For each page in the section:</p>
<ul>
<li>we initialise the internal variables (9 to 13). If the page is a <code>Hash</code> we extract the title and URL for the link from it&#8217;s elements, if it is a <code>Symbol</code> we <em>infer</em> the title and link from the symbol name.</li>
<li>Then we check if the current page in the iteration is the active one (26 to 30). If it is, we add a CSS attribute to the item, if it is not, then we add a hyper-link to it (it would not make sense to have a link to the page if you are already in it).</li>
<li>Finally in 36 to 47 we check if there is a <strong>:pages</strong> element in the <code>Hash</code> and if there is one, we make a recursive call to render the subsection.</li>
</ul>
<p>Two things need to be said about the above piece of code. First, each subsection will be assigned a CSS class in accordance to it&#8217;s level: <code>submenu1</code>, <code>submenu2</code>, etc. This will allow us to style the different subsections appropriately. And second, because there is no easy way of knowing if the active belongs to one of the sub sections of the current section we make the recursive call, and then see if we have found the active page. If we have not, we discard the subsection altogether. We want this behaviour of not displaying a subsection in the menu unless the user is already in that section and this was the easiest way of implementing it. </p>
<h4>The Bread Crumbs</h4>
<p><img src="http://usefulfor.com/ruby/files/2009/02/dradis2_breadcrums.png" alt="" width="295" height="94" class="alignright size-full wp-image-81" /></p>
<p>The bread crumbs help our users to know where they are in the site (see picture in the right sid). We need to have a flexible helper that would display the path the user has followed to get into the page they are at the moment. Below is the code of the layout, just above the main content and with a check to verify that we are not in the main page:</p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;">&lt;div class=&quot;left&quot;&gt;
  <span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@page</span> != <span style="color:#996600;">'index'</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  &lt;div id=&quot;breadcrums&quot;&gt;
    &lt;ul&gt;
      <span style="color:#006600; font-weight:bold;">&lt;%</span>= breadcrumsmenu<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:page</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@page</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
    &lt;/ul&gt;
  &lt;/div&gt;
  <span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
  <span style="color:#006600; font-weight:bold;">&lt;%</span>= <span style="color:#0066ff; font-weight:bold;">@content_for_layout</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
&lt;/div&gt;</pre></div></div>

<p>And again, this helper will use the <code>$sections</code> as discussed above.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> breadcrumsmenu<span style="color:#006600; font-weight:bold;">&#40;</span>options=<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    crums = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#ff6633; font-weight:bold;">$sections</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>section<span style="color:#006600; font-weight:bold;">|</span>
      options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:section</span><span style="color:#006600; font-weight:bold;">&#93;</span> = section
      crums = breadcrums<span style="color:#006600; font-weight:bold;">&#40;</span>options<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">break</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>crums.<span style="color:#9900CC;">size</span> <span style="color:#006600; font-weight:bold;">&gt;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    this_page = crums.<span style="color:#9900CC;">pop</span>
    <span style="color:#006600; font-weight:bold;">&#40;</span>crums.<span style="color:#9900CC;">collect</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>c<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#996600;">&quot;&lt;li&gt;&lt;a href=<span style="color:#000099;">\&quot;</span>#{c[:url]}<span style="color:#000099;">\&quot;</span>&gt;#{c[:title]}&lt;/a&gt;&amp;lt/li&amp;gt&quot;</span>  <span style="color:#9966CC; font-weight:bold;">end</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">join</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">&quot;&lt;li&gt;#{this_page[:title]}&lt;/li&gt;&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Again a similar tradeoff here, we cycle through all the sections trying to find the <strong>active</strong> page. We use the <code>breadcrums</code> helper-to-the-helper function to find out if the page is in the given section and then we render the bread crumbs. I realise that the two helper-to-the-helper functions are quite similar (cycle through a section trying to locate the active page), and possibly we could refactor both into a single function that does thing. But then again, once it worked, we did not have too much spare time to look into it, so we may improve it in the future, but this is the solution we came up with at that point. The code of <code>breadcrums()</code> is very similar in structure to the code in <code>sectionmenu()</code> but this time, it returns an array of pages that will lead us to the active one:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">def</span> breadcrums<span style="color:#006600; font-weight:bold;">&#40;</span>options=<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    current_page = options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:page</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    section = options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:section</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    crums = options.<span style="color:#9900CC;">fetch</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#ff3333; font-weight:bold;">:crums</span>, <span style="color:#006600; font-weight:bold;">&#91;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:title <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'home'</span>, <span style="color:#ff3333; font-weight:bold;">:url</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'/'</span><span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    section<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:pages</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>page<span style="color:#006600; font-weight:bold;">|</span>
      title = <span style="color:#996600;">''</span>
      url = <span style="color:#996600;">''</span>
      complex = <span style="color:#0000FF; font-weight:bold;">false</span>
      found = <span style="color:#0000FF; font-weight:bold;">false</span>
&nbsp;
      <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>page.<span style="color:#9966CC; font-weight:bold;">class</span> == <span style="color:#CC00FF; font-weight:bold;">Hash</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        complex = <span style="color:#0000FF; font-weight:bold;">true</span>
        title = page<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:title</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">to_s</span>.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span>_<span style="color:#006600; font-weight:bold;">/</span>,<span style="color:#996600;">' '</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        url = page<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:url</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      <span style="color:#9966CC; font-weight:bold;">else</span>
        title = page.<span style="color:#9900CC;">to_s</span>.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span>_<span style="color:#006600; font-weight:bold;">/</span>,<span style="color:#996600;">' '</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        url = page.<span style="color:#9900CC;">to_s</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">'.html'</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>current_page <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">'.html'</span> == url<span style="color:#006600; font-weight:bold;">&#41;</span>
        found = <span style="color:#0000FF; font-weight:bold;">true</span>
        crums <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:title</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> title, <span style="color:#ff3333; font-weight:bold;">:url</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> url <span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>!found <span style="color:#006600; font-weight:bold;">&amp;&amp;</span> complex <span style="color:#006600; font-weight:bold;">&amp;&amp;</span> page.<span style="color:#9900CC;">key</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:pages</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        subsectioncrums = breadcrums<span style="color:#006600; font-weight:bold;">&#40;</span>
          <span style="color:#ff3333; font-weight:bold;">:page</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> current_page,
          <span style="color:#ff3333; font-weight:bold;">:section</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> page,
          <span style="color:#ff3333; font-weight:bold;">:crums</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#123;</span>:title <span style="color:#006600; font-weight:bold;">=&gt;</span> title, <span style="color:#ff3333; font-weight:bold;">:url</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> url<span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
        <span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>subsectioncrums.<span style="color:#9900CC;">size</span> <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>
          crums <span style="color:#006600; font-weight:bold;">+</span>= subsectioncrums
        <span style="color:#9966CC; font-weight:bold;">end</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      <span style="color:#9966CC; font-weight:bold;">break</span> <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span>crums.<span style="color:#9900CC;">size</span> <span style="color:#006600; font-weight:bold;">&gt;</span> <span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#0000FF; font-weight:bold;">return</span> crums
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<h3>Finishing Touch</h3>
<p>Finally, to generate the static pages that we could compress and upload to the server, some good old <a href="http://www.gnu.org/software/wget/">wget</a> magic was used:</p>
<div class="hl-surround" ><div class="hl-main"><pre>&lt;br /&gt;
wget -m -nH http://localhost:3000/&lt;br /&gt;</pre></div></div></p>
<img src="http://usefulfor.com/ruby/?ak_action=api_record_view&id=75&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://usefulfor.com/ruby/2009/02/04/use-rails-to-create-a-static-site/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>
