<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>dynamic_reports-0.0.0.gem</filename>
    </added>
    <added>
      <filename>examples/rails/all_visitors_report.rb</filename>
    </added>
    <added>
      <filename>examples/rails/sales_report.rb.rb</filename>
    </added>
    <added>
      <filename>examples/rails/sample_controller.rb.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -22,7 +22,14 @@ require &quot;dynamic_reports/vendor/google_chart&quot;
 # require &quot;dynamic_reports/rails&quot;
 # For now placing the code right here:
 if defined?(Rails)
-  # Load all defined reports. 
+  # ath_to_lib = File.join(Rails.root, &quot;app&quot;)    #adjust if necessary
+  #   path_to_tree = &quot;#{path_to_lib}/reports&quot;
+  #   Dir[&quot;#{path_to_tree}/**/*.rb&quot;].each { |fn|
+  #     fn =~ /^#{Regexp.escape(path_to_lib)}\/(.*)\.rb$/
+  #     require $1
+  #   }
+
+  # Load all defined reports.
   # Question: How to get Rails to reload files other than ones matching the requested constant...
   #Dir.glob(&quot;#{File.join(Rails.root, &quot;app&quot;, &quot;reports&quot;)}/*.rb&quot;).each { |file| require file }
   ActiveSupport::Dependencies.load_paths &lt;&lt; File.join(Rails.root, &quot;app&quot;, &quot;reports&quot;)
@@ -44,4 +51,3 @@ if defined?(Rails)
 
   # TODO: Generator
 end
-</diff>
      <filename>lib/dynamic_reports.rb</filename>
    </modified>
    <modified>
      <diff>@@ -8,7 +8,7 @@ module DynamicReports
   class Report
     @@default_engine = &quot;erb&quot;
 
-    attr_accessor :name, :title, :sub_title, :columns, :charts, :records, :template, :class_name, :styles
+    attr_accessor :name, :title, :sub_title, :columns, :charts, :records, :template, :class_name, :styles, :links
 
     # views accessor, array of view paths.
     def views
@@ -160,6 +160,29 @@ module DynamicReports
         chart_options = chart_options.shift || {}
         charts(Chart.configure(name, chart_options, &amp;block))
       end
+      
+      # Return an array of links defined for the report.
+      def links(object=nil)
+        options[:links] ||= []
+        options[:links] &lt;&lt; object if object
+        options[:links]
+      end
+      
+      # Define a link for the report
+      #
+      # Pass parameters within {}.  Parameters are replaced with the row values 
+      # from passed records.  You do NOT need to include a parameter value as a 
+      # report column for it to be used in a link. For example, you might 
+      # want to generate a link with an ID field in it but not display that id 
+      # in the actual report.  Just include {id} to do this.
+      #
+      # Example:
+      #
+      # link :visits, '/reports/{visit}/details?date={recorded_at}'
+      #
+      def link(column, url, link_options=nil)
+        links({:column =&gt; column, :url =&gt; url, :link_options =&gt; link_options})
+      end
 
       # Method for instanciating a report instance on a set of given records.
       #</diff>
      <filename>lib/dynamic_reports/reports.rb</filename>
    </modified>
    <modified>
      <diff>@@ -32,7 +32,7 @@ module DynamicReports
 
     # TODO: Add Report Helpers for injection
     def titleize(object)
-      object.to_s.split('_').each{ |word| word.capitalize! }.join(' ') 
+      object.to_s.split('_').each{ |word| word.capitalize! }.join(' ')
     end
 
     def commify(object)
@@ -43,9 +43,49 @@ module DynamicReports
       end
     end
 
+    def linkcheck(record, column_object)
+      val = ''
+
+      if column_object.is_a?(Hash)
+        column = column_object[:column]
+      else
+        column = column_object
+      end
+
+      report.links.each do |link|
+        if link[:column] == column
+          url = link[:url]
+          url.scan(/\{(\w+)\}/).each do |parameter|
+            parameter = parameter.to_s
+            url = url.gsub(&quot;{#{parameter}}&quot;, CGI::escape(get_record_value(record, parameter.to_sym).to_s))
+          end
+
+          url_attribute_str = []
+          link[:link_options].keys.each do |key|
+            url_attribute_str &lt;&lt; &quot;#{key}='#{link[:link_options][key]}'&quot;
+          end if link[:link_options]
+          
+          val = &quot;&lt;a href='#{url}' #{url_attribute_str.join(' ')}&gt;#{get_record_value(record,column)}&lt;/a&gt;&quot;
+          break
+        end if link[:column]
+      end if report.links
+
+      val.blank? ? get_record_value(record,column) : val
+    end
+
+    def get_record_value(record, column)
+      if record.is_a?(Hash)
+        record[column]
+      elsif record.respond_to?(column.to_sym)
+        record.send(column.to_sym)
+      else
+        column
+      end
+    end
+
     def chart_url(chart,report)
       columns = chart.columns ? chart.columns : report.columns
-      chart_type = chart.type.nil? ?  :line : chart.type.to_sym 
+      chart_type = chart.type.nil? ?  :line : chart.type.to_sym
       case chart_type
       when :line
         Charts.line_chart(chart,columns,report)
@@ -62,7 +102,7 @@ module DynamicReports
     end
 
     private
-    
+
     def render(engine, template, options={}, locals={})
       # merge app-level options
       options = self.class.send(engine).merge(options) if self.class.respond_to?(engine)
@@ -74,7 +114,7 @@ module DynamicReports
       content_type = options.delete(:content_type)
       locals = options.delete(:locals) || locals || {}
       locals.merge!(:report =&gt; @report, :options =&gt; options || {})
-      
+
       # render template
       data, options[:filename], options[:line] = lookup_template(engine, template, views, content_type)
       output = __send__(&quot;render_#{engine}&quot;, template, data, options, locals)
@@ -101,7 +141,7 @@ module DynamicReports
           lookup_template(engine, cached[:template], views, content_type, cached[:filename], cached[:line])
         else
           filename = &quot;#{template}.#{content_type}.#{engine}&quot;
-          dir = views.to_a.detect do |view| 
+          dir = views.to_a.detect do |view|
             ::File.exists?(::File.join(view, filename))
           end
           if dir
@@ -172,7 +212,7 @@ module DynamicReports
       require engine.downcase
     end
 
- 
-    
+
+
   end
 end</diff>
      <filename>lib/dynamic_reports/templates.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,73 +1,91 @@
 &lt;% if report.class_name.nil? %&gt;
-  &lt;style type=&quot;text/css&quot;&gt;
-    .dynamic_report .report_title {
-      font-size:16pt;
-      font-weight:bold;
-      margin:10px 0px;
-    }
-    .dynamic_report .report_subtitle {
-      font-size:14pt;
-      color:black;
-      margin:10px 0px;
-    }
-    .dynamic_report table tr th {
-      color: white;
-      background: gray;
-      padding:5px;
-    }
-    .dynamic_report table tr td {
-      border: 1px solid black;
-      padding:3px 15px;
-    }
-    .dynamic_report .report_charts {
-      width:100%;
-    }
+&lt;style type=&quot;text/css&quot;&gt;
+.dynamic_report .report_title {
+  font-size:16pt;
+  font-weight:bold;
+  margin:10px 0px;
+}
+.dynamic_report .report_subtitle {
+  font-size:14pt;
+  color:black;
+  margin:10px 0px;
+}
+.dynamic_report table tr th {
+  color: white;
+  background: gray;
+  padding:5px;
+}
+.dynamic_report table tr td {
+  border: 1px solid black;
+  padding:3px 15px;
+}
+.dynamic_report .report_charts {
+  width: 100%;
+}
 
-    .dynamic_report .report_chart {
-      margin:15px;
-    }
-  &lt;/style&gt;
+.dynamic_report .report_chart {
+  margin:15px;
+}
+
+.dynamic_report .subreport_row td {
+  padding: 10px 10px 10px 20px;
+  background-color: #FFFFCC;
+  font-size: 95%;
+}
+.dynamic_report .subreport table tr td {
+  border: 1px dotted #CCCC99;
+  padding:3px 5px;
+  background-color: white;
+}
+.dynamic_report .subreport table tr th {
+  color: black;
+  background: #CCCCCC;
+  padding:3px;
+}
+
+&lt;/style&gt;
 &lt;% end %&gt;
 
 &lt;div id=&quot;&lt;%= report.class_name %&gt;&quot; class=&quot;dynamic_report&quot;&gt;
-  &lt;%= &quot;&lt;div class='report_title'&gt;#{report.title}&lt;/div&gt;&quot; if report.title %&gt;
-  &lt;%= &quot;&lt;div class='report_subtitle'&gt;#{report.sub_title}&lt;/div&gt;&quot; if report.sub_title %&gt;
-  &lt;table class=&quot;report&quot; border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;
-    &lt;thead class=&quot;report_header&quot;&gt;
-      &lt;tr class=&quot;report_header_row&quot;&gt;
-        &lt;% report.columns.each do |column| %&gt;
-          &lt;th&gt;
-            &lt;%= options[:titleize] ? titleize(column) : column %&gt;
-          &lt;/th&gt;
-        &lt;% end %&gt;
+&lt;%= &quot;&lt;div class='report_title'&gt;#{report.title}&lt;/div&gt;&quot; if report.title %&gt;
+&lt;%= &quot;&lt;div class='report_subtitle'&gt;#{report.sub_title}&lt;/div&gt;&quot; if report.sub_title %&gt;
+&lt;table class=&quot;report&quot; border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot;&gt;
+&lt;thead class=&quot;report_header&quot;&gt;
+&lt;tr class=&quot;report_header_row&quot;&gt;
+&lt;% report.columns.each do |column| %&gt;
+  &lt;th&gt;
+  &lt;% if column.is_a?(Hash) %&gt;
+  &lt;% if column.keys.include?(:heading) %&gt;
+  &lt;%= options[:titleize] ? titleize(column[:heading]) : column[:heading] %&gt;
+  &lt;% else %&gt;
+  &lt;%= options[:titleize] ? titleize(column[:column]) : column[:column] %&gt;
+  &lt;% end %&gt;
+  &lt;% else %&gt;
+  &lt;%= options[:titleize] ? titleize(column) : column %&gt;
+  &lt;% end %&gt;
+  &lt;/th&gt;
+  &lt;% end %&gt;
+  &lt;/tr&gt;
+  &lt;/thead&gt;
+  &lt;tbody class=&quot;report_body&quot;&gt;
+  &lt;% report.records.each do |record| %&gt;
+    &lt;tr class=&quot;report_row&quot;&gt;
+    &lt;% report.columns.each do |column| %&gt;
+      &lt;td&gt;
+      &lt;%= (options[:commas] == true) ? commify(linkcheck(record,column)) : linkcheck(record,column) %&gt;
+      &lt;/td&gt;
+      &lt;% end %&gt;
       &lt;/tr&gt;
-    &lt;/thead&gt;
-    &lt;tbody class=&quot;report_body&quot;&gt;
-      &lt;% report.records.each do |record| %&gt;
-        &lt;tr class=&quot;report_row&quot;&gt;
-          &lt;% report.columns.each do |column| %&gt;
-            &lt;td&gt;
-              &lt;% if record.is_a?(Hash) %&gt;
-                &lt;%= (options[:commas] == true) ? commify(record[column]) : record[column] %&gt;
-              &lt;% elsif record.respond_to?(column.to_sym) %&gt;
-                &lt;%= (options[:commas] == true) ? commify(record.send(column.to_sym)) : record.send(column.to_sym) %&gt;
-              &lt;% else %&gt;
-                &lt;%= column %&gt;
-              &lt;% end %&gt;
-            &lt;/td&gt;
-          &lt;% end %&gt;
-        &lt;/tr&gt;
       &lt;% end %&gt;
-    &lt;/tbody&gt;
-  &lt;/table&gt;
+      &lt;/tbody&gt;
+      &lt;/table&gt;
 
-  &lt;div class=&quot;report_charts&quot;&gt;
-    &lt;% report.charts.to_a.each do |chart| %&gt;
-      &lt;span class=&quot;report_chart&quot;&gt;
+      &lt;div class=&quot;report_charts&quot;&gt;
+      &lt;% report.charts.to_a.each do |chart| %&gt;
+        &lt;span class=&quot;report_chart&quot;&gt;
         &lt;%=  &quot;&lt;img src='#{chart_url(chart,report)}' alt='#{chart.name}'&gt;&quot; %&gt;
-      &lt;/span&gt;
-    &lt;% end %&gt;
-  &lt;/div&gt;
-
-&lt;/div&gt;
+        &lt;/span&gt;
+        &lt;% end %&gt;
+        &lt;/div&gt;
 
+        &lt;/div&gt;</diff>
      <filename>lib/dynamic_reports/views/default_report.html.erb</filename>
    </modified>
    <modified>
      <diff>@@ -12,11 +12,11 @@
     }
     \.dynamic_report table tr th {
     color: white;
-    background: gray;
+    background: #666666;
     padding:5px;
     }
     \.dynamic_report table tr td {
-    border: 1px solid black;
+    border: 1px solid #333333;
     padding:3px 15px;
     }
     \.dynamic_report .report_charts {
@@ -25,6 +25,21 @@
     \.dynamic_report .report_chart {
     margin:15px;
     }
+    \.dynamic_report .subreport_row td {
+    padding: 10px 10px 10px 20px;
+    background-color: #FFFFCC;
+    font-size: 95%;
+    }
+    \.dynamic_report .subreport table tr td {
+    border: 1px dotted #CCCC99;
+    padding:3px 5px;
+    background-color: white;
+    }    
+    \.dynamic_report .subreport table tr th {
+    color: black;
+    background: #CCCCCC;
+    padding:3px;
+    }
 
 .dynamic_report{ :id =&gt; report.class_name }
   - if report.title
@@ -40,18 +55,20 @@
       %tr.report_header_row
         - report.columns.each do |column|
           %th
-            = options[:titleize] ? titleize(column) : column
+            - if column.is_a?(Hash) 
+              - if column.keys.include?(:heading)            
+                = options[:titleize] ? titleize(column[:heading]) : column[:heading]
+              -else
+                = options[:titleize] ? titleize(column[:column]) : column[:column]                
+            -else
+              = options[:titleize] ? titleize(column) : column
     %tbody.report_body
       - report.records.each do |record|
         %tr.report_row
           - report.columns.each do |column|
             %td
-              - if record.is_a?(Hash)
-                = (options[:commas] == true) ? commify(record[column]) : record[column]
-              - elsif record.respond_to?(column.to_sym)
-                = (options[:commas] == true) ? commify(record.send(column.to_sym)) : record.send(column.to_sym)
-              - else
-                = column
+              = (options[:commas] == true) ? commify(linkcheck(record,column)) : linkcheck(record,column)
+      
 
   - if report.charts &amp;&amp; report.charts.class === Hash
     - report.charts.each_pair do |name, chart|</diff>
      <filename>lib/dynamic_reports/views/default_report.html.haml</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>e5602c948098300993aed787da791a616541e750</id>
    </parent>
    <parent>
      <id>e5c369457c621911c717f12fdc4d984ca174b9a8</id>
    </parent>
  </parents>
  <author>
    <name>Wayne E. Seguin</name>
    <email>wayneeseguin@gmail.com</email>
  </author>
  <url>http://github.com/wayneeseguin/dynamic_reports/commit/1b4cf33adf3bac68919c76b9cbb4961b681941a7</url>
  <id>1b4cf33adf3bac68919c76b9cbb4961b681941a7</id>
  <committed-date>2009-07-16T07:33:35-07:00</committed-date>
  <authored-date>2009-07-16T07:33:35-07:00</authored-date>
  <message>Merge conflict resolution.</message>
  <tree>881f536e367ab1ad7043dce470a90fc60e1aebdf</tree>
  <committer>
    <name>Wayne E. Seguin</name>
    <email>wayneeseguin@gmail.com</email>
  </committer>
</commit>
