api_taster 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +11 -0
- data/.rspec +1 -0
- data/.travis.yml +3 -0
- data/Gemfile +6 -0
- data/README.md +68 -0
- data/Rakefile +40 -0
- data/api_taster.gemspec +27 -0
- data/app/assets/images/api_taster/.gitkeep +0 -0
- data/app/assets/javascripts/api_taster/01-prettify.js +28 -0
- data/app/assets/javascripts/api_taster/02-jquery.form.js +1076 -0
- data/app/assets/javascripts/api_taster/app.js +88 -0
- data/app/assets/javascripts/api_taster/application.js +16 -0
- data/app/assets/stylesheets/api_taster/01-prettify.css +1 -0
- data/app/assets/stylesheets/api_taster/02-prettify-sunburst.css +51 -0
- data/app/assets/stylesheets/api_taster/application.css +13 -0
- data/app/assets/stylesheets/api_taster/layout.css.scss +51 -0
- data/app/controllers/api_taster/application_controller.rb +5 -0
- data/app/controllers/api_taster/routes_controller.rb +12 -0
- data/app/helpers/api_taster/application_helper.rb +4 -0
- data/app/views/api_taster/routes/_param_form_element.html.erb +6 -0
- data/app/views/api_taster/routes/_param_form_legend.html.erb +1 -0
- data/app/views/api_taster/routes/_undefined_route.html.erb +7 -0
- data/app/views/api_taster/routes/index.html.erb +24 -0
- data/app/views/api_taster/routes/show.html.erb +55 -0
- data/app/views/layouts/api_taster/application.html.erb +29 -0
- data/config/routes.rb +5 -0
- data/lib/api_taster.rb +13 -0
- data/lib/api_taster/engine.rb +17 -0
- data/lib/api_taster/form_builder.rb +49 -0
- data/lib/api_taster/mapper.rb +30 -0
- data/lib/api_taster/route.rb +63 -0
- data/lib/api_taster/version.rb +3 -0
- data/lib/tasks/api_taster_tasks.rake +0 -0
- data/script/rails +8 -0
- data/spec/controllers/api_taster/routes_controller_spec.rb +21 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +4 -0
- data/spec/dummy/app/controllers/users_controller.rb +21 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +67 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +67 -0
- data/spec/dummy/config/environments/test.rb +37 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +33 -0
- data/spec/dummy/lib/assets/.gitkeep +0 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/form_builder_spec.rb +29 -0
- data/spec/mapper_spec.rb +41 -0
- data/spec/route_spec.rb +71 -0
- data/spec/spec_helper.rb +12 -0
- metadata +503 -0
@@ -0,0 +1,88 @@
|
|
1
|
+
var ApiTaster = {
|
2
|
+
formAction: '',
|
3
|
+
disableUrlParams: function() {
|
4
|
+
$("#url-params input").prop("disabled", true);
|
5
|
+
},
|
6
|
+
enableUrlParams: function() {
|
7
|
+
$("#url-params input").prop("disabled", false);
|
8
|
+
},
|
9
|
+
storeFormActionFor: function(form) {
|
10
|
+
ApiTaster.formAction = form.attr("action")
|
11
|
+
},
|
12
|
+
restoreFormActionFor: function(form) {
|
13
|
+
$(form).attr("action", ApiTaster.formAction);
|
14
|
+
}
|
15
|
+
};
|
16
|
+
|
17
|
+
$.fn.extend({
|
18
|
+
replaceUrlParams: function(params) {
|
19
|
+
var form = this;
|
20
|
+
|
21
|
+
$.each(params, function(i, param) {
|
22
|
+
var matches = param["name"].match(/\[api_taster_url_params\](.*)/)
|
23
|
+
if (matches) {
|
24
|
+
var paramKey = matches[1];
|
25
|
+
var paramValue = param["value"];
|
26
|
+
|
27
|
+
ApiTaster.storeFormActionFor(form);
|
28
|
+
|
29
|
+
var regex = new RegExp(":" + paramKey);
|
30
|
+
var replacedAction = ApiTaster.formAction.replace(regex, paramValue);
|
31
|
+
|
32
|
+
form.attr("action", replacedAction);
|
33
|
+
}
|
34
|
+
});
|
35
|
+
}
|
36
|
+
});
|
37
|
+
|
38
|
+
jQuery(function($) {
|
39
|
+
$("a.show-api").click(function(e) {
|
40
|
+
e.preventDefault();
|
41
|
+
|
42
|
+
$("a.show-api").parent().removeClass("active");
|
43
|
+
$(this).parent().addClass("active");
|
44
|
+
|
45
|
+
$("#show-api-div").load(this.href, function() {
|
46
|
+
prettyPrint();
|
47
|
+
});
|
48
|
+
});
|
49
|
+
|
50
|
+
$("#show-api-div").on("click", "#submit-api", function() {
|
51
|
+
$(this).parents("form").submit(function() {
|
52
|
+
$(this).unbind("submit").ajaxSubmit({
|
53
|
+
beforeSubmit: function(arr, $form, options) {
|
54
|
+
$form.replaceUrlParams(arr);
|
55
|
+
ApiTaster.disableUrlParams();
|
56
|
+
return false;
|
57
|
+
}
|
58
|
+
});
|
59
|
+
});
|
60
|
+
|
61
|
+
$("form").bind("ajax:complete", function(e, xhr, status) {
|
62
|
+
ApiTaster.enableUrlParams();
|
63
|
+
ApiTaster.restoreFormActionFor(this);
|
64
|
+
|
65
|
+
if ($("#show-api-response-div:visible").length == 0) {
|
66
|
+
$("#show-api-response-div").slideDown(100);
|
67
|
+
}
|
68
|
+
|
69
|
+
$("#show-api-response-div pre[ref=response-raw]").text(xhr.responseText);
|
70
|
+
$("#show-api-response-div pre[ref=response-json]").text(
|
71
|
+
JSON.stringify(JSON.parse(xhr.responseText), null, 2)
|
72
|
+
);
|
73
|
+
|
74
|
+
prettyPrint();
|
75
|
+
});
|
76
|
+
|
77
|
+
$("#show-api-response-div ul.nav-tabs a").click(function(e) {
|
78
|
+
e.preventDefault();
|
79
|
+
|
80
|
+
$(this).parent().siblings().removeClass("active");
|
81
|
+
$(this).parent().addClass("active");
|
82
|
+
|
83
|
+
$("pre", "#show-api-response-div").hide();
|
84
|
+
$("pre[ref=" + $(this).attr("id") + "]", "#show-api-response-div").show();
|
85
|
+
});
|
86
|
+
});
|
87
|
+
});
|
88
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// the compiled file.
|
9
|
+
//
|
10
|
+
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
11
|
+
// GO AFTER THE REQUIRES BELOW.
|
12
|
+
//
|
13
|
+
//= require jquery
|
14
|
+
//= require jquery_ujs
|
15
|
+
//= require bootstrap
|
16
|
+
//= require_tree .
|
@@ -0,0 +1 @@
|
|
1
|
+
.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee}
|
@@ -0,0 +1,51 @@
|
|
1
|
+
/* Pretty printing styles. Used with prettify.js. */
|
2
|
+
/* Vim sunburst theme by David Leibovic */
|
3
|
+
|
4
|
+
pre .str, code .str { color: #65B042; } /* string - green */
|
5
|
+
pre .kwd, code .kwd { color: #E28964; } /* keyword - dark pink */
|
6
|
+
pre .com, code .com { color: #AEAEAE; font-style: italic; } /* comment - gray */
|
7
|
+
pre .typ, code .typ { color: #89bdff; } /* type - light blue */
|
8
|
+
pre .lit, code .lit { color: #3387CC; } /* literal - blue */
|
9
|
+
pre .pun, code .pun { color: #fff; } /* punctuation - white */
|
10
|
+
pre .pln, code .pln { color: #fff; } /* plaintext - white */
|
11
|
+
pre .tag, code .tag { color: #89bdff; } /* html/xml tag - light blue */
|
12
|
+
pre .atn, code .atn { color: #bdb76b; } /* html/xml attribute name - khaki */
|
13
|
+
pre .atv, code .atv { color: #65B042; } /* html/xml attribute value - green */
|
14
|
+
pre .dec, code .dec { color: #3387CC; } /* decimal - blue */
|
15
|
+
|
16
|
+
pre.prettyprint, code.prettyprint {
|
17
|
+
background-color: #000;
|
18
|
+
-moz-border-radius: 8px;
|
19
|
+
-webkit-border-radius: 8px;
|
20
|
+
-o-border-radius: 8px;
|
21
|
+
-ms-border-radius: 8px;
|
22
|
+
-khtml-border-radius: 8px;
|
23
|
+
border-radius: 8px;
|
24
|
+
}
|
25
|
+
|
26
|
+
pre.prettyprint {
|
27
|
+
width: 95%;
|
28
|
+
margin: 1em auto;
|
29
|
+
padding: 1em;
|
30
|
+
white-space: pre-wrap;
|
31
|
+
}
|
32
|
+
|
33
|
+
|
34
|
+
/* Specify class=linenums on a pre to get line numbering */
|
35
|
+
ol.linenums { margin-top: 0; margin-bottom: 0; color: #AEAEAE; } /* IE indents via margin-left */
|
36
|
+
li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8 { list-style-type: none }
|
37
|
+
/* Alternate shading for lines */
|
38
|
+
li.L1,li.L3,li.L5,li.L7,li.L9 { }
|
39
|
+
|
40
|
+
@media print {
|
41
|
+
pre .str, code .str { color: #060; }
|
42
|
+
pre .kwd, code .kwd { color: #006; font-weight: bold; }
|
43
|
+
pre .com, code .com { color: #600; font-style: italic; }
|
44
|
+
pre .typ, code .typ { color: #404; font-weight: bold; }
|
45
|
+
pre .lit, code .lit { color: #044; }
|
46
|
+
pre .pun, code .pun { color: #440; }
|
47
|
+
pre .pln, code .pln { color: #000; }
|
48
|
+
pre .tag, code .tag { color: #006; font-weight: bold; }
|
49
|
+
pre .atn, code .atn { color: #404; }
|
50
|
+
pre .atv, code .atv { color: #060; }
|
51
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
9
|
+
* compiled file, but it's generally better to create a new file per style scope.
|
10
|
+
*
|
11
|
+
*= require_self
|
12
|
+
*= require_tree .
|
13
|
+
*/
|
@@ -0,0 +1,51 @@
|
|
1
|
+
@import "bootstrap";
|
2
|
+
|
3
|
+
$colour_text: #333;
|
4
|
+
$colour_grey: #999;
|
5
|
+
|
6
|
+
body {
|
7
|
+
padding-top: 50px;
|
8
|
+
padding-bottom: 50px;
|
9
|
+
}
|
10
|
+
|
11
|
+
.hidden {
|
12
|
+
display: none;
|
13
|
+
}
|
14
|
+
|
15
|
+
.form-actions {
|
16
|
+
padding-bottom: 0;
|
17
|
+
margin-bottom: 0;
|
18
|
+
}
|
19
|
+
|
20
|
+
legend {
|
21
|
+
font-size: 14px;
|
22
|
+
font-weight: bold;
|
23
|
+
color: $colour_grey;
|
24
|
+
|
25
|
+
&.super-legend {
|
26
|
+
color: $colour_text;
|
27
|
+
}
|
28
|
+
}
|
29
|
+
|
30
|
+
.label-api {
|
31
|
+
display: inline-block;
|
32
|
+
padding-right: 5px;
|
33
|
+
}
|
34
|
+
|
35
|
+
.label-api-full {
|
36
|
+
width: 50px;
|
37
|
+
text-align: right;
|
38
|
+
}
|
39
|
+
|
40
|
+
.breadcrumb-controller {
|
41
|
+
font-weight: bold;
|
42
|
+
color: $colour_grey;
|
43
|
+
}
|
44
|
+
|
45
|
+
#show-api-response-div {
|
46
|
+
pre.nowrap {
|
47
|
+
overflow-x: auto;
|
48
|
+
white-space: pre;
|
49
|
+
word-wrap: normal;
|
50
|
+
}
|
51
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
<legend><%= label %></legend>
|
@@ -0,0 +1,7 @@
|
|
1
|
+
<div class="alert alert-error">
|
2
|
+
<p><strong><%= "Route '#{route[:verb]} #{route[:path]}' is undefined." %></strong></p>
|
3
|
+
<p>Please define this route in <code>routes.rb</code>:</p>
|
4
|
+
<pre class="prettyprint lang-rb">ApiTaster.routes do
|
5
|
+
<%= route[:verb].downcase %> '<%= route[:path] %>', {}
|
6
|
+
end</pre>
|
7
|
+
</div>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<div class="row">
|
2
|
+
<div class="span5">
|
3
|
+
<ul class="well nav nav-list">
|
4
|
+
<% @routes.each do |controller, routes| %>
|
5
|
+
<li class="nav-header"><%= controller %></li>
|
6
|
+
<% routes.each do |route| %>
|
7
|
+
<li>
|
8
|
+
<a class="show-api" href="<%= route_path(route[:id]) %>">
|
9
|
+
<div class="label-api label-api-full">
|
10
|
+
<span class="label label-important"><%= route[:verb] %></span>
|
11
|
+
</div>
|
12
|
+
<strong><%= route[:path] %></strong>
|
13
|
+
</a>
|
14
|
+
</li>
|
15
|
+
<% end %>
|
16
|
+
<% end %>
|
17
|
+
</ul>
|
18
|
+
</div>
|
19
|
+
<div id="show-api-div" class="span7">
|
20
|
+
<div class="alert alert-block alert-info">
|
21
|
+
<h3>Select an API endpoint on the left to get started. :)</h3>
|
22
|
+
</div>
|
23
|
+
</div>
|
24
|
+
</div>
|
@@ -0,0 +1,55 @@
|
|
1
|
+
<ul class="breadcrumb">
|
2
|
+
<li class="breadcrumb-controller"><%= @route[:reqs][:controller].humanize %><span class="divider">/</span></li>
|
3
|
+
<li>
|
4
|
+
<div class="label-api">
|
5
|
+
<span class="label label-important"><%= @route[:verb] %></span>
|
6
|
+
</div>
|
7
|
+
<strong><%= @route[:path] %></strong>
|
8
|
+
</li>
|
9
|
+
</ul>
|
10
|
+
|
11
|
+
<% if @inputs.is_a?(Hash) && @inputs.has_key?(:undefined) %>
|
12
|
+
<%= render 'undefined_route', :route => @inputs[:undefined] %>
|
13
|
+
<% else %>
|
14
|
+
<% @inputs.each do |input| %>
|
15
|
+
<%= form_tag @route[:path], :method => @route[:verb], :class => 'well form-horizontal', :remote => true do %>
|
16
|
+
|
17
|
+
<% if input[:url_params].empty? && input[:post_params].empty? %>
|
18
|
+
<div class="alert alert-info">
|
19
|
+
No params specified.
|
20
|
+
</div>
|
21
|
+
<% end %>
|
22
|
+
|
23
|
+
<% if input[:url_params].present? %>
|
24
|
+
<fieldset id="url-params">
|
25
|
+
<legend class="super-legend">URL Params</legend>
|
26
|
+
<% input[:url_params].each do |label, value| %>
|
27
|
+
<%= render 'param_form_element', :label => "[api_taster_url_params]#{label}", :value => value, :label_text => label %>
|
28
|
+
<% end %>
|
29
|
+
</fieldset>
|
30
|
+
<% end %>
|
31
|
+
|
32
|
+
<% if input[:post_params].present? %>
|
33
|
+
<fieldset>
|
34
|
+
<legend class="super-legend">Post Params</legend>
|
35
|
+
<%= ApiTaster::FormBuilder.new(input[:post_params]).html.html_safe %>
|
36
|
+
</fieldset>
|
37
|
+
<% end %>
|
38
|
+
|
39
|
+
<div class="form-actions">
|
40
|
+
<input id="submit-api" type="submit" class="btn btn-primary pull-right"></input>
|
41
|
+
</div>
|
42
|
+
|
43
|
+
<% end %>
|
44
|
+
<% end %>
|
45
|
+
<% end %>
|
46
|
+
|
47
|
+
<div id="show-api-response-div" class="well hidden">
|
48
|
+
<legend class="super-legend">Response</legend>
|
49
|
+
<ul class="nav nav-tabs">
|
50
|
+
<li class="active"><a href="#" id="response-json">JSON</a></li>
|
51
|
+
<li><a href="#" id="response-raw">Raw</a></li>
|
52
|
+
</ul>
|
53
|
+
<pre class="prettyprint nowrap" ref="response-json"></pre>
|
54
|
+
<pre class="prettyprint hidden" ref="response-raw"></pre>
|
55
|
+
</div>
|
@@ -0,0 +1,29 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>API Taster</title>
|
5
|
+
<%= stylesheet_link_tag "api_taster/application", :media => "all" %>
|
6
|
+
<%= javascript_include_tag "api_taster/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
<div class="navbar navbar-fixed-top">
|
11
|
+
<div class="navbar-inner">
|
12
|
+
<div class="container">
|
13
|
+
<h1><a class="brand" href="<%= root_path %>">API Taster</a></h1>
|
14
|
+
<div class="nav-collapse collapse">
|
15
|
+
<ul class="nav pull-right">
|
16
|
+
<li>
|
17
|
+
<a href="/" target="_blank"><%= Rails.application.class.name %> <i class="icon-share-alt icon-white"></i></a>
|
18
|
+
</li>
|
19
|
+
</ul>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
</div>
|
23
|
+
</div>
|
24
|
+
|
25
|
+
<div class="container">
|
26
|
+
<%= yield %>
|
27
|
+
</div>
|
28
|
+
</body>
|
29
|
+
</html>
|
data/config/routes.rb
ADDED
data/lib/api_taster.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'active_support/dependencies'
|
2
|
+
require 'api_taster/engine'
|
3
|
+
require 'api_taster/route'
|
4
|
+
require 'api_taster/mapper'
|
5
|
+
require 'api_taster/form_builder'
|
6
|
+
|
7
|
+
module ApiTaster
|
8
|
+
def self.routes(&block)
|
9
|
+
Route.route_set = Rails.application.routes
|
10
|
+
Route.inputs = {}
|
11
|
+
Mapper.instance_eval(&block)
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module ApiTaster
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace ApiTaster
|
4
|
+
|
5
|
+
config.generators do |g|
|
6
|
+
g.test_framework :rspec, :view_specs => false
|
7
|
+
end
|
8
|
+
|
9
|
+
silence_warnings do
|
10
|
+
begin
|
11
|
+
require 'pry'
|
12
|
+
IRB = Pry
|
13
|
+
rescue LoadError
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module ApiTaster
|
2
|
+
class FormBuilder < AbstractController::Base
|
3
|
+
include AbstractController::Rendering
|
4
|
+
include ActionView::Context
|
5
|
+
include ActionView::Helpers::CaptureHelper
|
6
|
+
|
7
|
+
self.view_paths = ApiTaster::Engine.root.join('app/views')
|
8
|
+
|
9
|
+
def initialize(params)
|
10
|
+
flush_output_buffer
|
11
|
+
@_buffer = ''
|
12
|
+
add_to_buffer(params)
|
13
|
+
end
|
14
|
+
|
15
|
+
def html
|
16
|
+
@_buffer
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def add_to_buffer(params, parent_labels = [])
|
22
|
+
params.each do |label, value|
|
23
|
+
if value.is_a?(String)
|
24
|
+
@_buffer += render(
|
25
|
+
:partial => 'api_taster/routes/param_form_element',
|
26
|
+
:locals => {
|
27
|
+
:label => "#{print_labels(parent_labels)}#{label}",
|
28
|
+
:label_text => label,
|
29
|
+
:value => value
|
30
|
+
}
|
31
|
+
)
|
32
|
+
else
|
33
|
+
parent_labels << label
|
34
|
+
|
35
|
+
@_buffer += render(
|
36
|
+
:partial => 'api_taster/routes/param_form_legend',
|
37
|
+
:locals => { :label => print_labels(parent_labels) }
|
38
|
+
)
|
39
|
+
|
40
|
+
add_to_buffer(value, parent_labels)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def print_labels(parent_labels)
|
46
|
+
"[#{parent_labels * ']['}]"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|