apipie-rails 0.1.3 → 0.2.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/.travis.yml +1 -2
- data/CHANGELOG.md +26 -0
- data/README.rst +94 -3
- data/app/controllers/apipie/apipies_controller.rb +28 -10
- data/app/views/apipie/apipies/_disqus.html.erb +4 -2
- data/app/views/apipie/apipies/_languages.erb +6 -0
- data/app/views/apipie/apipies/_method_detail.erb +7 -7
- data/app/views/apipie/apipies/_params.html.erb +2 -2
- data/app/views/apipie/apipies/_params_plain.html.erb +2 -2
- data/app/views/apipie/apipies/apipie_404.html.erb +7 -4
- data/app/views/apipie/apipies/getting_started.html.erb +5 -3
- data/app/views/apipie/apipies/index.html.erb +7 -6
- data/app/views/apipie/apipies/method.html.erb +4 -2
- data/app/views/apipie/apipies/plain.html.erb +3 -3
- data/app/views/apipie/apipies/resource.html.erb +3 -2
- data/app/views/apipie/apipies/static.html.erb +7 -7
- data/app/views/layouts/apipie/apipie.html.erb +1 -1
- data/config/locales/en.yml +27 -0
- data/lib/apipie-rails.rb +7 -0
- data/lib/apipie/apipie_module.rb +5 -2
- data/lib/apipie/application.rb +27 -16
- data/lib/apipie/configuration.rb +6 -1
- data/lib/apipie/extractor.rb +35 -26
- data/lib/apipie/extractor/recorder.rb +9 -5
- data/lib/apipie/extractor/writer.rb +36 -7
- data/lib/apipie/method_description.rb +6 -6
- data/lib/apipie/param_description.rb +9 -4
- data/lib/apipie/resource_description.rb +5 -5
- data/lib/apipie/routing.rb +1 -1
- data/lib/apipie/version.rb +1 -1
- data/lib/generators/apipie/install/templates/initializer.rb.erb +1 -1
- data/lib/tasks/apipie.rake +89 -47
- data/spec/dummy/doc/apipie_examples.json +1 -0
- data/spec/lib/extractor/middleware_spec.rb +21 -0
- data/spec/lib/extractor/writer_spec.rb +76 -0
- metadata +10 -5
- data/Gemfile.rails30 +0 -5
- data/spec/dummy/doc/apipie_examples.yml +0 -28
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,30 @@
|
|
2
2
|
Changelog
|
3
3
|
===========
|
4
4
|
|
5
|
+
v0.2.0
|
6
|
+
------
|
7
|
+
|
8
|
+
This is not full backward compatible release, as the format of storing
|
9
|
+
examples changed from YAML to JSON: the default location is at
|
10
|
+
`doc/apipie_examples.json`. The migration should be as easy as
|
11
|
+
running:
|
12
|
+
|
13
|
+
```
|
14
|
+
rake apipie:convert_examples
|
15
|
+
```
|
16
|
+
|
17
|
+
Also please not Rails 3.0 support was deprecated and the compatibility
|
18
|
+
wont be tracked anymore in next releases.
|
19
|
+
|
20
|
+
* dump examples as json
|
21
|
+
[#125](https://github.com/Apipie/apipie-rails/pull/125) [@johanneswuerbach][]
|
22
|
+
* support for localized API documentation
|
23
|
+
[#232](https://github.com/Apipie/apipie-rails/pull/232) [@mbacovsky][]
|
24
|
+
* configuration option to always record examples
|
25
|
+
[#239](https://github.com/Apipie/apipie-rails/pull/239) [@arathunku][]
|
26
|
+
* deprecate Rails 3.0
|
27
|
+
[#241](https://github.com/Apipie/apipie-rails/pull/241) [@iNecas][]
|
28
|
+
|
5
29
|
v0.1.3
|
6
30
|
------
|
7
31
|
|
@@ -119,3 +143,5 @@ v0.0.15
|
|
119
143
|
[@mkrajewski]: https://github.com/mkrajewski
|
120
144
|
[@iNecas]: https://github.com/iNecas
|
121
145
|
[@clamoris]: https://github.com/clamoris
|
146
|
+
[@arathunku]: https://github.com/arathunku
|
147
|
+
[@johanneswuerbach]: https://github.com/johanneswuerbach
|
data/README.rst
CHANGED
@@ -554,7 +554,25 @@ show_all_examples
|
|
554
554
|
|
555
555
|
link_extension
|
556
556
|
The extension to use for API pages ('.html' by default). Link extensions
|
557
|
-
in static API docs cannot be changed from '.html'.
|
557
|
+
in static API docs cannot be changed from '.html'.
|
558
|
+
|
559
|
+
languages
|
560
|
+
List of languages API documentation should be translated into. Empty list by default.
|
561
|
+
|
562
|
+
default_locale
|
563
|
+
Locale used for generating documentation when no specific locale is set.
|
564
|
+
Set to 'en' by default.
|
565
|
+
|
566
|
+
locale
|
567
|
+
Pass locale setter/getter
|
568
|
+
|
569
|
+
.. code:: ruby
|
570
|
+
|
571
|
+
config.locale = lambda { |loc| loc ? FastGettext.set_locale(loc) : FastGettext.locale }
|
572
|
+
|
573
|
+
translate
|
574
|
+
Pass proc to translate strings using localization library your project uses.
|
575
|
+
For example see `Localization`_
|
558
576
|
|
559
577
|
Example:
|
560
578
|
|
@@ -863,6 +881,79 @@ For inspiration this is how Textile markup usage looks like:
|
|
863
881
|
end
|
864
882
|
end
|
865
883
|
|
884
|
+
============
|
885
|
+
Localization
|
886
|
+
============
|
887
|
+
|
888
|
+
Apipie has support for localized API documentation in both formats (JSON and HTML).
|
889
|
+
Apipie uses the library I18n for localization of itself.
|
890
|
+
Check ``config/locales`` directory for available translation.
|
891
|
+
|
892
|
+
Major part of strings in the documentation comes from the API.
|
893
|
+
As prefferences about localization libraries differs among project, Apipie needs to know how to set locale for your project
|
894
|
+
and how to translate a string using library your project use. That can be done using lambdas in configuration.
|
895
|
+
|
896
|
+
Sample configuration when your project use FastGettext
|
897
|
+
|
898
|
+
|
899
|
+
.. code:: ruby
|
900
|
+
|
901
|
+
Apipie.configure do |config|
|
902
|
+
...
|
903
|
+
config.languages = ['en', 'cs']
|
904
|
+
config.default_locale = 'en'
|
905
|
+
config.locale = lambda { |loc| loc ? FastGettext.set_locale(loc) : FastGettext.locale }
|
906
|
+
config.translate = lambda do |str, loc|
|
907
|
+
old_loc = FastGettext.locale
|
908
|
+
FastGettext.set_locale(loc)
|
909
|
+
trans = _(str)
|
910
|
+
FastGettext.set_locale(old_loc)
|
911
|
+
trans
|
912
|
+
end
|
913
|
+
end
|
914
|
+
|
915
|
+
And the strings in API documentation needs to be marked with the ``N_()`` function
|
916
|
+
|
917
|
+
.. code:: ruby
|
918
|
+
|
919
|
+
api :GET, "/users/:id", N_("Show user profile")
|
920
|
+
param :session, String, :desc => N_("user is logged in"), :required => true
|
921
|
+
|
922
|
+
|
923
|
+
|
924
|
+
When your project use I18n, localization related configuration could look like as follows
|
925
|
+
|
926
|
+
.. code:: ruby
|
927
|
+
|
928
|
+
Apipie.configure do |config|
|
929
|
+
...
|
930
|
+
config.languages = ['en', 'cs']
|
931
|
+
config.default_locale = 'en'
|
932
|
+
config.locale = lambda { |loc| loc ? I18n.locale = loc : I18n.locale }
|
933
|
+
config.translate = lambda do |str, loc|
|
934
|
+
old_loc = I18n.locale
|
935
|
+
I18n.locale = loc
|
936
|
+
trans = I18n.t(str)
|
937
|
+
I18n.locale = old_loc
|
938
|
+
trans
|
939
|
+
end
|
940
|
+
end
|
941
|
+
|
942
|
+
And the strings in API documentation needs to be in the form of translation keys
|
943
|
+
|
944
|
+
.. code:: ruby
|
945
|
+
|
946
|
+
api :GET, "/users/:id", "show_user_profile"
|
947
|
+
param :session, String, :desc => "user_is_logged_in", :required => true
|
948
|
+
|
949
|
+
|
950
|
+
The localized versions of the documentation are distinguished by languge in the filename.
|
951
|
+
E.g. ``doc/apidoc/apidoc.cs.html`` is static documentation in the Czech language.
|
952
|
+
If the language is missing, e.g. ``doc/apidoc/apidoc.html``,
|
953
|
+
the documentation is localized with the ``default_locale``.
|
954
|
+
|
955
|
+
The dynamic documentation follows the same schema. The ``http://localhost:3000/apidoc/v1.cs.html`` is documentation for version '1' of the API in the Czech language. For JSON description of the API applies the same: ``http://localhost:3000/apidoc/v1.cs.json``
|
956
|
+
|
866
957
|
|
867
958
|
================
|
868
959
|
Modifying Views
|
@@ -940,7 +1031,7 @@ of information is already included in this tests, it just needs to be
|
|
940
1031
|
extracted somehow. Luckily, Apipie provides such a feature.
|
941
1032
|
|
942
1033
|
When running the tests, set the ``APIPIE_RECORD=params`` environment
|
943
|
-
variable. You can either use it with functional tests
|
1034
|
+
variable or call ``Apipie.record('params')`` from specs starter. You can either use it with functional tests
|
944
1035
|
|
945
1036
|
.. code::
|
946
1037
|
|
@@ -962,7 +1053,7 @@ Examples Recording
|
|
962
1053
|
|
963
1054
|
You can also use the tests to generate up-to-date examples for your
|
964
1055
|
code. Similarly to the bootstrapping, you can use it with functional
|
965
|
-
tests or a running server, setting ``APIPIE_RECORD=examples``
|
1056
|
+
tests or a running server, setting ``APIPIE_RECORD=examples`` or by calling ``Apipie.record('examples')`` in your specs starter.
|
966
1057
|
|
967
1058
|
.. code::
|
968
1059
|
|
@@ -24,8 +24,11 @@ module Apipie
|
|
24
24
|
return
|
25
25
|
end
|
26
26
|
|
27
|
+
@language = get_language
|
28
|
+
|
27
29
|
Apipie.reload_documentation if Apipie.configuration.reload_controllers?
|
28
|
-
|
30
|
+
I18n.locale = @language
|
31
|
+
@doc = Apipie.to_json(params[:version], params[:resource], params[:method], @language)
|
29
32
|
|
30
33
|
format.json do
|
31
34
|
if @doc
|
@@ -43,12 +46,13 @@ module Apipie
|
|
43
46
|
|
44
47
|
@versions = Apipie.available_versions
|
45
48
|
@doc = @doc[:docs]
|
46
|
-
@doc[:link_extension] = Apipie.configuration.link_extension
|
49
|
+
@doc[:link_extension] = (@language ? ".#{@language}" : '')+Apipie.configuration.link_extension
|
47
50
|
if @doc[:resources].blank?
|
48
51
|
render "getting_started" and return
|
49
52
|
end
|
50
53
|
@resource = @doc[:resources].first if params[:resource].present?
|
51
54
|
@method = @resource[:methods].first if params[:method].present?
|
55
|
+
@languages = Apipie.configuration.languages
|
52
56
|
|
53
57
|
if @resource && @method
|
54
58
|
render 'method'
|
@@ -68,20 +72,34 @@ module Apipie
|
|
68
72
|
|
69
73
|
private
|
70
74
|
|
75
|
+
def get_language
|
76
|
+
lang = nil
|
77
|
+
[:resource, :method, :version].each do |par|
|
78
|
+
if params[par]
|
79
|
+
splitted = params[par].split('.')
|
80
|
+
if splitted.length > 1 && Apipie.configuration.languages.include?(splitted.last)
|
81
|
+
lang = splitted.last
|
82
|
+
params[par].sub!(".#{lang}", '')
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
lang
|
87
|
+
end
|
88
|
+
|
71
89
|
def get_format
|
72
|
-
|
73
|
-
|
90
|
+
[:resource, :method, :version].each do |par|
|
91
|
+
if params[par]
|
92
|
+
params[:format] = :html unless params[par].sub!('.html', '').nil?
|
93
|
+
params[:format] = :json unless params[par].sub!('.json', '').nil?
|
94
|
+
end
|
95
|
+
end
|
74
96
|
request.format = params[:format] if params[:format]
|
75
97
|
end
|
76
98
|
|
77
99
|
def render_from_cache
|
78
100
|
path = Apipie.configuration.doc_base_url.dup
|
79
|
-
|
80
|
-
|
81
|
-
end
|
82
|
-
# version can contain dot, but only one in row
|
83
|
-
if params[:version].to_s.gsub(".", "") =~ /\W/ ||
|
84
|
-
params[:version].to_s =~ /\.\./
|
101
|
+
# some params can contain dot, but only one in row
|
102
|
+
if [:resource, :method, :format, :version].any? { |p| params[p].to_s.gsub(".", "") =~ /\W/ || params[p].to_s =~ /\.\./ }
|
85
103
|
head :bad_request and return
|
86
104
|
end
|
87
105
|
|
@@ -7,5 +7,7 @@
|
|
7
7
|
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
|
8
8
|
})();
|
9
9
|
</script>
|
10
|
-
<noscript
|
11
|
-
|
10
|
+
<noscript><%= t('apipie.enable_javascript_html', :comments_href => link_to(
|
11
|
+
t('apipie.comments_powered_by_disqus', :disqus => 'Disqus'),
|
12
|
+
"http://disqus.com/?ref_noscript")) %></noscript>
|
13
|
+
<a href="http://disqus.com" class="dsq-brlink"><%= t('apipie.comments_powered_by_disqus', :disqus => "<span class="logo-disqus">Disqus</span>") %></a>
|
@@ -1,12 +1,12 @@
|
|
1
1
|
<%= raw method[:full_description] %>
|
2
2
|
|
3
3
|
<% unless method[:formats].blank? %>
|
4
|
-
<%= heading('
|
4
|
+
<%= heading(t('apipie.supported_formats'), h_level) %>
|
5
5
|
<%= method[:formats].join(', ') %>
|
6
6
|
<% end %>
|
7
7
|
|
8
8
|
<% unless method[:errors].blank? %>
|
9
|
-
<%= heading('
|
9
|
+
<%= heading(t('apipie.errors'), h_level) %>
|
10
10
|
<% method[:errors].each do |err| %>
|
11
11
|
<%= err[:code] %>
|
12
12
|
<%= err[:description] %>
|
@@ -19,24 +19,24 @@
|
|
19
19
|
<% end %>
|
20
20
|
|
21
21
|
<% unless method[:metadata].blank? %>
|
22
|
-
<%= heading('
|
22
|
+
<%= heading(t('apipie.metadata'), h_level) %>
|
23
23
|
<%= render(:partial => "metadata", :locals => {:meta => method[:metadata]}) %>
|
24
24
|
<% end %>
|
25
25
|
|
26
26
|
<% unless method[:examples].blank? %>
|
27
|
-
<%= heading('
|
27
|
+
<%= heading(t('apipie.examples'), h_level) %>
|
28
28
|
<% method[:examples].each do |example| %>
|
29
29
|
<pre class="prettyprint"><%= example %></pre>
|
30
30
|
<% end %>
|
31
31
|
<% end %>
|
32
32
|
|
33
33
|
<% unless method[:params].blank? %>
|
34
|
-
<%= heading('
|
34
|
+
<%= heading(t('apipie.params'), h_level) %>
|
35
35
|
<table class='table'>
|
36
36
|
<thead>
|
37
37
|
<tr>
|
38
|
-
<th
|
39
|
-
<th
|
38
|
+
<th><%= t('aapipie.param_name') %></th>
|
39
|
+
<th><%= t('apipie.description') %></th>
|
40
40
|
</tr>
|
41
41
|
</thead>
|
42
42
|
<tbody>
|
@@ -9,8 +9,8 @@
|
|
9
9
|
<td>
|
10
10
|
<strong><%= param[:full_name] %> </strong><br>
|
11
11
|
<small>
|
12
|
-
<%= param[:required] ? 'required' : 'optional' %>
|
13
|
-
<%= param[:allow_nil] ? ',
|
12
|
+
<%= param[:required] ? t('apipie.required') : t('apipie.optional') %>
|
13
|
+
<%= param[:allow_nil] ? ', '+t('apipie.nil_allowed') : '' %>
|
14
14
|
</small>
|
15
15
|
</td>
|
16
16
|
<td>
|
@@ -7,8 +7,8 @@
|
|
7
7
|
<li>
|
8
8
|
<strong><%= param[:name] %> </strong>:
|
9
9
|
<small>
|
10
|
-
<%= param[:required] ? 'required' : 'optional' %>
|
11
|
-
<%= param[:allow_nil] ? ',
|
10
|
+
<%= param[:required] ? t('apipie.required') : t('apipie.optional') %>
|
11
|
+
<%= param[:allow_nil] ? ', '+t('apipie.nil_allowed') : '' %>
|
12
12
|
<% if param[:validator] %>
|
13
13
|
[ <%= param[:validator] %> ]
|
14
14
|
<% end %>
|
@@ -1,14 +1,17 @@
|
|
1
1
|
<h1 class='page-header'>
|
2
|
-
|
2
|
+
<%= t('apipie.oops') %>
|
3
3
|
<small>
|
4
4
|
<% if @resource == 'null' %>
|
5
|
-
|
5
|
+
<%= t('apipie.resource_not_found_html', :resource => "<code>#{params[:resource]}</code>") %>
|
6
6
|
<% else %>
|
7
|
-
|
7
|
+
<%= t('apipie.method_not_found_html', :resource => "<code>#{params[:resource]}</code>",
|
8
|
+
:method => "<code>#{params[:resource]}</code>" %>
|
8
9
|
<% end %>
|
9
10
|
</small>
|
10
11
|
</h1>
|
11
12
|
|
12
13
|
<% if @doc %>
|
13
|
-
|
14
|
+
<%= t('apipie.goto_homepage_html', :href = link_to(
|
15
|
+
t('apipie.goto_homepage_href', :app_name => @doc[:name]),
|
16
|
+
File.join(@doc[:doc_url], @doc[:link_extension]))) %>
|
14
17
|
<% end %>
|
@@ -1,4 +1,6 @@
|
|
1
|
-
<h1 class='page-header'
|
2
|
-
<p
|
3
|
-
<p
|
1
|
+
<h1 class='page-header'><%= t('apipie.no_doc_found') %></h1>
|
2
|
+
<p><%= t('apipie.no_docs_found_descr') %></p>
|
3
|
+
<p><%= t('apipie.follow_instructions_html',
|
4
|
+
:href => link_to(t('apipie.follow_instructions_href'),
|
5
|
+
"https://github.com/Pajk/apipie-rails#getting-started", :target => "_blank")) %></p>
|
4
6
|
|
@@ -1,15 +1,16 @@
|
|
1
1
|
<ul class='breadcrumb'>
|
2
2
|
<li class='active'><a href='<%= @doc[:doc_url] %><%= @doc[:link_extension] %>'><%= @doc[:name] %> <%= @doc[:resources].values.first[:version] %></a></li>
|
3
|
+
<%= render(:partial => "languages", :locals => {:doc_url => @doc[:doc_url]}) %>
|
3
4
|
<% if @versions && @versions.size > 1 %>
|
4
5
|
<li class='pull-right'>
|
5
|
-
<%= @versions.collect { |v| link_to v, Apipie.full_url(v) }.join(' / ').html_safe %>
|
6
|
+
<%= @versions.collect { |v| link_to v, Apipie.full_url(v+@doc[:link_extension]) }.join(' / ').html_safe %>
|
6
7
|
</li>
|
7
8
|
<% end %>
|
8
9
|
</ul>
|
9
10
|
|
10
11
|
<div><%= raw @doc[:info] %></div>
|
11
12
|
|
12
|
-
<h1 class='page-header'
|
13
|
+
<h1 class='page-header'><%= t('apipie.resources') %></h1>
|
13
14
|
|
14
15
|
<% @doc[:resources].sort_by(&:first).each do |key, api| %>
|
15
16
|
<h2>
|
@@ -21,8 +22,8 @@
|
|
21
22
|
<table class='table'>
|
22
23
|
<thead>
|
23
24
|
<tr>
|
24
|
-
<th
|
25
|
-
<th
|
25
|
+
<th><%= t('apipie.resource') %></th>
|
26
|
+
<th><%= t('apipie.description') %></th>
|
26
27
|
</tr>
|
27
28
|
</thead>
|
28
29
|
<tbody>
|
@@ -38,6 +39,6 @@
|
|
38
39
|
</table>
|
39
40
|
<% end %>
|
40
41
|
|
41
|
-
<% content_for
|
42
|
-
<%= raw
|
42
|
+
<% unless content_for(:apipie_footer) == @doc[:copyright] %>
|
43
|
+
<%= content_for :apipie_footer, raw(@doc[:copyright]) %>
|
43
44
|
<% end %>
|
@@ -11,6 +11,8 @@
|
|
11
11
|
<span class='divider'>/</span>
|
12
12
|
</li>
|
13
13
|
<li class='active'><%= @method[:name] %></li>
|
14
|
+
<%= render(:partial => "languages", :locals => {:doc_url => @method[:doc_url]}) %>
|
15
|
+
|
14
16
|
</ul>
|
15
17
|
|
16
18
|
<% @method[:apis].each do |api| %>
|
@@ -30,6 +32,6 @@
|
|
30
32
|
<%= render(:partial => "method_detail", :locals => {:method => @method, :h_level => 2}) %>
|
31
33
|
</div>
|
32
34
|
|
33
|
-
<% content_for
|
34
|
-
<%= raw
|
35
|
+
<% unless content_for(:apipie_footer) == @doc[:copyright] %>
|
36
|
+
<%= content_for :apipie_footer, raw(@doc[:copyright]) %>
|
35
37
|
<% end %>
|
@@ -45,14 +45,14 @@
|
|
45
45
|
<div>
|
46
46
|
<%= raw method[:full_description] %>
|
47
47
|
<% unless method[:examples].blank? %>
|
48
|
-
<h4
|
48
|
+
<h4><%= t('apipie.examples') %></h4>
|
49
49
|
<% method[:examples].each do |example| %>
|
50
50
|
<pre class="wiki"><%= example %></pre>
|
51
51
|
<% end %>
|
52
52
|
<% end %>
|
53
53
|
|
54
54
|
<% unless method[:errors].blank? %>
|
55
|
-
<h4
|
55
|
+
<h4><%= t('apipie.errors') %></h4>
|
56
56
|
<% method[:errors].each do |err| %>
|
57
57
|
<%= err[:code] %>
|
58
58
|
<%= err[:description] %>
|
@@ -62,7 +62,7 @@
|
|
62
62
|
<% end %>
|
63
63
|
|
64
64
|
<% unless method[:params].blank? %>
|
65
|
-
<h4
|
65
|
+
<h4><%= t('apipie.params') %></h4>
|
66
66
|
<%= render(:partial => "params_plain", :locals => {:params => method[:params]}) %>
|
67
67
|
<% end %>
|
68
68
|
</div>
|