jekyll-theme-alta-docs 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +16 -98
- data/_includes/feature_meta.html +50 -23
- data/_includes/features/rails/rails_resource_controller.md +167 -0
- data/_includes/features/rails/rails_resource_development.md +50 -0
- data/_includes/features/rails/rails_resource_model.md +57 -0
- data/_includes/features/rails/rails_resource_query.md +43 -0
- data/_includes/features/rails/rails_resource_routes.md +13 -0
- data/_includes/features/rails/rails_resource_serializer.md +26 -0
- data/_includes/features/react/api_service.md +131 -0
- data/_includes/features/react/app_init.md +103 -0
- data/_includes/guidelines/rails/api_only_psql_no_admin_setup_instructions.md +14 -0
- data/_includes/instructions/how_to_share_documentation.md +91 -0
- data/_includes/nav.html +15 -3
- data/_includes/project_overview.html +1 -1
- data/_includes/requirements_list.html +35 -0
- data/_includes/system_components_overview.html +1 -1
- data/_sass/jekyll-theme-alta-docs.scss +34 -0
- metadata +13 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cfe209fc6b38de2a86aa011b9b6c4ca07563e9da0f92fb0a0a0940d1bb2135f0
|
4
|
+
data.tar.gz: 52ef29832776dc1a37f4eb2692a1d0d83ea996c6cbfc91cfa65aaa9fca400558
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 63ad959b450234ac1911d30e5004acf5ec0b66b3ccf9e527897bbbf137fcdf876510fb1526fd98d0b37eecd9fa82124d0fe4d4152cf14f4aac362b79263133ad
|
7
|
+
data.tar.gz: aa20a00e02103dffe3ba40d0b16a548e3b733228fd1d8976853dad8eb15a011cf2aa2ccd324f35043c2923c2c2dd89ea1d9a172391e2514a8c0fd8aa18559c4f
|
data/README.md
CHANGED
@@ -79,114 +79,27 @@ The Jekyll theme for documenting software development projects.
|
|
79
79
|
|
80
80
|
This is my home page
|
81
81
|
|
82
|
-
|
83
|
-
|
84
|
-
bundle exec jekyll serve
|
85
|
-
|
86
|
-
### What's next?
|
87
|
-
|
88
|
-
Add more documents in *_docs* folder and see [advanced options](#advanced-options).
|
89
|
-
|
90
|
-
|
91
|
-
## Advanced options
|
92
|
-
|
93
|
-
### Common _config.yml options
|
94
|
-
|
95
|
-
title : "Project title"
|
96
|
-
|
97
|
-
getting_started : >- # Used in the Project overview component
|
98
|
-
Take a look on the useful materials below.
|
99
|
-
Start by checking "the System Overview" to get a big picture of the project.
|
100
|
-
Don't forget to check "Development Guidelines".
|
101
|
-
Find more by exploring navigation on the left.
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
### Links
|
106
|
-
|
107
|
-
Links to the repositories can be added in *_config.yml*:
|
108
|
-
|
109
|
-
links:
|
110
|
-
repos:
|
111
|
-
- name : Web app repository
|
112
|
-
icon : "fab fa-github" # Use fontawesome v6
|
113
|
-
url : https://bitbucket.org/
|
114
|
-
- name : Backend repository
|
115
|
-
icon : "fab fa-bitbucket" # Use fontawesome v6
|
116
|
-
url : https://bitbucket.org/
|
117
|
-
- name : Docs repository
|
118
|
-
icon : "fab fa-gitlab" # Use fontawesome v6
|
119
|
-
url : https://bitbucket.org/
|
120
|
-
useful:
|
121
|
-
- name : System overview
|
122
|
-
icon : "fas fa-project-diagram"
|
123
|
-
url : /architecture/
|
124
|
-
- name : Architecture
|
125
|
-
icon : "fas fa-clipboard-list"
|
126
|
-
url : /architecture/
|
127
|
-
- name : Development Guidelines
|
128
|
-
icon : "fas fa-pencil-alt"
|
129
|
-
url : /architecture/
|
130
|
-
|
131
|
-
Repositories links are displayed in website footer.
|
132
|
-
|
133
|
-
|
134
|
-
### System components
|
135
|
-
|
136
|
-
You can define the system components like Backend, Frontend etc. in *_config.yml*:
|
82
|
+
... or:
|
137
83
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
- name: React.js
|
142
|
-
- name: Redux
|
143
|
-
- name : Backend
|
144
|
-
techs :
|
145
|
-
- name: Ruby on Rails
|
146
|
-
- name : Database
|
147
|
-
techs :
|
148
|
-
- name: PostgreSQL
|
149
|
-
- name : Service provider
|
150
|
-
techs :
|
151
|
-
- name: AWS
|
152
|
-
|
153
|
-
The "System components" are used in two components:
|
154
|
-
|
155
|
-
* `project_overview.html` > `{% include project_overview.html %}`
|
156
|
-
* `system_components_overview.html` > `{% include project_overview.html %}`
|
157
|
-
|
158
|
-
|
159
|
-
### Versioning
|
160
|
-
|
161
|
-
The documentation version is displayed in the footer.
|
162
|
-
|
163
|
-
doc_version : 1.0.0
|
164
|
-
|
165
|
-
|
166
|
-
## Components (includes)
|
84
|
+
---
|
85
|
+
layout: page
|
86
|
+
---
|
167
87
|
|
168
|
-
|
88
|
+
{% include project_overview.html next_button="/docs/development/" %}
|
169
89
|
|
170
|
-
The "Project overview" component renders:
|
171
90
|
|
172
|
-
|
173
|
-
* `doc_version`
|
174
|
-
* `description`
|
175
|
-
* `getting_started`
|
176
|
-
* `system_components`
|
177
|
-
* `links`
|
91
|
+
7. Run:
|
178
92
|
|
179
|
-
|
93
|
+
bundle exec jekyll serve
|
180
94
|
|
181
|
-
|
95
|
+
### What's next?
|
182
96
|
|
183
|
-
|
97
|
+
Add more documents in *_docs* folder and see [advanced options](docs/01_advanced_options.md).
|
184
98
|
|
185
|
-
{% include project_overview.html next_button="/docs/development/" %}
|
186
99
|
|
187
|
-
|
100
|
+
## Advanced options
|
188
101
|
|
189
|
-
|
102
|
+
See more: [advanced options](docs/01_advanced_options.md)
|
190
103
|
|
191
104
|
|
192
105
|
## Development
|
@@ -196,6 +109,11 @@ To set up your environment to develop this theme, run `bundle install`.
|
|
196
109
|
To test theme, run: `bundle exec rake preview` or `bundle exec rake preview host=xxx.xx.xxx.xx`
|
197
110
|
|
198
111
|
|
112
|
+
## Development todo's
|
113
|
+
|
114
|
+
Add more templates, integrations with *the source code*, setup scripts.
|
115
|
+
|
116
|
+
|
199
117
|
## License
|
200
118
|
|
201
119
|
The theme is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/_includes/feature_meta.html
CHANGED
@@ -1,30 +1,57 @@
|
|
1
|
-
{% if page.status
|
1
|
+
{% if page.status or page.prio or page.system_components or page.version or page.vtags or page.vtag %}
|
2
2
|
<div class='feature-meta'>
|
3
|
-
|
4
|
-
<
|
5
|
-
|
6
|
-
<
|
3
|
+
{% if page.vtags or page.vtag %}
|
4
|
+
<div class='feature-meta__version'>
|
5
|
+
<label>Tags:</label>
|
6
|
+
<div>
|
7
|
+
{% if page.vtag %}
|
8
|
+
<span class='tag tag--{{ page.vtag | replace: " ", "-" }} feature-meta__status--{{ page.vtag | replace: " ", "-" }}'>{{ page.vtag }}</span>
|
9
|
+
{% endif %}
|
10
|
+
{% if page.vtags %}
|
11
|
+
{% for vtag in page.vtags %}
|
12
|
+
<span class='tag tag--{{ vtag | replace: " ", "-" }} feature-meta__status--{{ vtag | replace: " ", "-" }}'>{{ vtag }}</span>
|
13
|
+
{% endfor %}
|
14
|
+
{% endif %}
|
15
|
+
</div>
|
7
16
|
</div>
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
<div>
|
12
|
-
<
|
17
|
+
{% endif %}
|
18
|
+
|
19
|
+
{% if page.status %}
|
20
|
+
<div class='feature-meta__status'>
|
21
|
+
<label>Status:</label>
|
22
|
+
<div>
|
23
|
+
<span class='tag tag--{{ page.status }} feature-meta__status--{{ page.status }}'>{{ page.status }}</span>
|
24
|
+
</div>
|
13
25
|
</div>
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
<div>
|
18
|
-
|
19
|
-
|
20
|
-
|
26
|
+
{% endif %}
|
27
|
+
|
28
|
+
{% if page.prio %}
|
29
|
+
<div class='feature-meta__prio'>
|
30
|
+
<label>Priority:</label>
|
31
|
+
<div>
|
32
|
+
<span class='tag tag--{{ page.prio }} feature-meta__prio--{{ page.prio }}'>{{ page.prio }}</span>
|
33
|
+
</div>
|
21
34
|
</div>
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
<div>
|
26
|
-
<
|
35
|
+
{% endif %}
|
36
|
+
|
37
|
+
{% if page.system_components %}
|
38
|
+
<div class='feature-meta__system_components'>
|
39
|
+
<label>System components:</label>
|
40
|
+
<div>
|
41
|
+
{% for component in page.system_components %}
|
42
|
+
<span class='tag'>{{ component }}</span>
|
43
|
+
{% endfor %}
|
44
|
+
</div>
|
27
45
|
</div>
|
28
|
-
|
46
|
+
{% endif %}
|
47
|
+
|
48
|
+
{% if page.version %}
|
49
|
+
<div class='feature-meta__version'>
|
50
|
+
<label>Version:</label>
|
51
|
+
<div>
|
52
|
+
<span class='feature-meta__version'>{{ page.version }}</span>
|
53
|
+
</div>
|
54
|
+
</div>
|
55
|
+
{% endif %}
|
29
56
|
</div>
|
30
57
|
{% endif %}
|
@@ -0,0 +1,167 @@
|
|
1
|
+
{% assign model = include.model %}
|
2
|
+
{% assign namespace = include.namespace %}
|
3
|
+
|
4
|
+
{% assign tab = 0 %}
|
5
|
+
{% capture namespace_modules %}{% for n in namespace %}
|
6
|
+
{{ tab | indent }}module {{ n | camelcase }}{% assign tab = tab | plus:1 %}{% endfor %}{% endcapture %}
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
# frozen_string_literal: true
|
10
|
+
|
11
|
+
{{ namespace_modules }}{% capture _ %}{% increment tab %}{% endcapture %}
|
12
|
+
{{ tab | indent }}# {{ model.db_name | capitalize }} controller{% assign tab = tab + ' ' %}
|
13
|
+
{{ tab | indent }}class {{ model.db_name | camelcase }}Controller < BaseController
|
14
|
+
resource_description do
|
15
|
+
short '{{ model.db_name | capitalize }}'
|
16
|
+
deprecated false
|
17
|
+
description <<-DES
|
18
|
+
{{ model.db_name | capitalize }} resource.
|
19
|
+
DES
|
20
|
+
end
|
21
|
+
|
22
|
+
before_action :set_{{ model.name}}, except: [:index, :create]
|
23
|
+
|
24
|
+
api :GET, '/{{ model.db_name }}', 'See {{ model.db_name }}'
|
25
|
+
returns code: 200, desc: '{{ model.name | capitalize }} details' do
|
26
|
+
property :status, String, desc: '200'
|
27
|
+
property :message, String, desc: '{{ model.db_name | capitalize }} details'
|
28
|
+
property :data, Hash, desc: '{{ model.db_name | capitalize }} data' do
|
29
|
+
property :page, Integer
|
30
|
+
property :total, Integer
|
31
|
+
property :{{ model.db_name }}, Array do{% for field in model.fields %}
|
32
|
+
property :{{ field.name }}, {{ field.type | camelcase }}{% endfor %}
|
33
|
+
property :created_at, DateTime
|
34
|
+
property :updated_at, DateTime
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
example <<-DES
|
39
|
+
# Request:
|
40
|
+
[GET] /{{ model.db_name }}/{:id}
|
41
|
+
DES
|
42
|
+
def index
|
43
|
+
# TODO: Pagination and filters
|
44
|
+
@{{ model.db_name }} = {{ model.name | camelcase }}.all
|
45
|
+
send_response(200, 'List of {{ model.db_name | capitalize }}', nil, ActiveModel::Serializer::CollectionSerializer.new(@{{ model.db_name }}, serializer: {{ model.name | camelcase }}Serializer))
|
46
|
+
end
|
47
|
+
|
48
|
+
api :GET, '/{{ model.db_name }}/:id', 'See {{ model.name }} details'
|
49
|
+
param :id, String, desc: 'ID of the invitation', required: true
|
50
|
+
error code: 404, desc: 'NOT_FOUND'
|
51
|
+
returns code: 200, desc: '{{ model.name | capitalize }} details' do
|
52
|
+
property :status, String, desc: '200'
|
53
|
+
property :message, String, desc: '{{ model.name | capitalize }} details'
|
54
|
+
property :data, Hash, desc: '{{ model.name | capitalize }} data' do{% for field in model.fields %}
|
55
|
+
property :{{ field.name }}, {{ field.type | camelcase }}{% endfor %}
|
56
|
+
property :created_at, DateTime
|
57
|
+
property :updated_at, DateTime
|
58
|
+
end
|
59
|
+
end
|
60
|
+
example <<-DES
|
61
|
+
# Request:
|
62
|
+
[GET] /{{ model.db_name }}/{:id}
|
63
|
+
DES
|
64
|
+
def show
|
65
|
+
send_response(200, '{{ model.name | capitalize }} details', nil, {{ model.name | camelcase }}Serializer.new(@{{ model.name }}))
|
66
|
+
end
|
67
|
+
|
68
|
+
api :POST, '/{{ model.db_name }}', 'Create {{ model.name }}'
|
69
|
+
error code: 422, desc: 'RESOURCE_NOT_VALID'
|
70
|
+
returns code: 200, desc: '{{ model.name | capitalize }} details' do
|
71
|
+
property :status, String, desc: '200'
|
72
|
+
property :message, String, desc: '{{ model.name | capitalize }} details'
|
73
|
+
property :data, Hash, desc: '{{ model.name | capitalize }} data' do{% for field in model.fields %}
|
74
|
+
property :{{ field.name }}, {{ field.type | camelcase }}{% endfor %}
|
75
|
+
property :created_at, DateTime
|
76
|
+
property :updated_at, DateTime
|
77
|
+
end
|
78
|
+
end
|
79
|
+
example <<-DES
|
80
|
+
# Request:
|
81
|
+
[GET] /{{ model.db_name }}/{:id}
|
82
|
+
DES
|
83
|
+
def create
|
84
|
+
# Add strong params
|
85
|
+
@{{ model.name }} = {{ model.name | camelcase }}.new({{ model.name }}_params)
|
86
|
+
if @{{ model.name }}.save
|
87
|
+
send_response(200, '{{ model.name | capitalize }} details', nil, {{ model.name | camelcase }}Serializer.new(@{{ model.name }}))
|
88
|
+
else
|
89
|
+
send_response(422, '{{ model.name | capitalize }} error', 'RESOURCE_NOT_VALID', @{{ model.name }}.errors))
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
api :PUT, '/{{ model.db_name }}/:id', 'Update {{ model.name }}'
|
94
|
+
param :id, String, desc: 'ID of the invitation', required: true
|
95
|
+
error code: 403, desc: 'RESOURCE_NOT_VALID'
|
96
|
+
error code: 404, desc: 'NOT_FOUND'
|
97
|
+
returns code: 200, desc: '{{ model.name | capitalize }} details' do
|
98
|
+
property :status, String, desc: '200'
|
99
|
+
property :message, String, desc: '{{ model.name | capitalize }} details'
|
100
|
+
property :data, Hash, desc: '{{ model.name | capitalize }} data' do{% for field in model.fields %}
|
101
|
+
property :{{ field.name }}, {{ field.type | camelcase }}{% endfor %}
|
102
|
+
property :created_at, DateTime
|
103
|
+
property :updated_at, DateTime
|
104
|
+
end
|
105
|
+
end
|
106
|
+
example <<-DES
|
107
|
+
# Request:
|
108
|
+
[GET] /{{ model.db_name }}/{:id}
|
109
|
+
DES
|
110
|
+
def update
|
111
|
+
# Add strong params
|
112
|
+
@{{ model.name }} = {{ model.name | camelcase }}.assign_attributes({{ model.name }}_params)
|
113
|
+
if @{{ model.name }}
|
114
|
+
if @{{ model.name }}.save
|
115
|
+
send_response(200, '{{ model.name | capitalize }} updated', nil, {{ model.name | camelcase }}Serializer.new(@{{ model.name }}))
|
116
|
+
else
|
117
|
+
send_response(403, '{{ model.name | capitalize }} error', 'RESOURCE_NOT_VALID', @{{ model.name }}))
|
118
|
+
end
|
119
|
+
else
|
120
|
+
send_response(404, '{{ model.name | capitalize }} not found', 'NOT_FOUND', nil))
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
api :DELETE, '/{{ model.db_name }}/:id', 'Delete {{ model.name }}'
|
125
|
+
param :id, String, desc: 'ID of the invitation', required: true
|
126
|
+
error code: 403, desc: 'RESOURCE_NOT_VALID'
|
127
|
+
error code: 404, desc: 'NOT_FOUND'
|
128
|
+
returns code: 200, desc: '{{ model.name | capitalize }} details' do
|
129
|
+
property :status, String, desc: '200'
|
130
|
+
property :message, String, desc: '{{ model.name | capitalize }} details'
|
131
|
+
property :data, Hash, desc: '{{ model.name | capitalize }} data' do{% for field in model.fields %}
|
132
|
+
property :{{ field.name }}, {{ field.type | camelcase }}{% endfor %}
|
133
|
+
property :created_at, DateTime
|
134
|
+
property :updated_at, DateTime
|
135
|
+
end
|
136
|
+
end
|
137
|
+
example <<-DES
|
138
|
+
# Request:
|
139
|
+
[GET] /{{ model.db_name }}/{:id}
|
140
|
+
DES
|
141
|
+
def destroy
|
142
|
+
if @{{ model.name }}
|
143
|
+
if @{{ model.name }}.destroy
|
144
|
+
send_response(200, '{{ model.name | capitalize }} deleted', nil, {{ model.name | camelcase }}Serializer.new(@{{ model.name }}))
|
145
|
+
else
|
146
|
+
send_response(403, '{{ model.name | capitalize }} error', 'RESOURCE_NOT_VALID', @{{ model.name }}.errors))
|
147
|
+
end
|
148
|
+
else
|
149
|
+
send_response(404, '{{ model.name | capitalize }} not found', 'NOT_FOUND', nil))
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
private
|
154
|
+
|
155
|
+
def set_{{ model.name }}
|
156
|
+
@{{ model.name }} = {{ model.name | camelcase }}.find(params['id'])
|
157
|
+
end
|
158
|
+
|
159
|
+
def {{ model.name }}_params
|
160
|
+
params.require(:{{model.name}}).permit({% for f in model.fields %}:{{f.name}},{% endfor %})
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
```
|
@@ -0,0 +1,50 @@
|
|
1
|
+
|
2
|
+
{% assign model_name = include.model_name %}
|
3
|
+
{% assign model = null %}
|
4
|
+
|
5
|
+
{% if include.model %}
|
6
|
+
{% assign model = include.model %}
|
7
|
+
{% else %}
|
8
|
+
{% for m in site.data.models %}
|
9
|
+
{% if m.name == model_name %}
|
10
|
+
{% assign model = m %}
|
11
|
+
{% break %}
|
12
|
+
{% endif %}
|
13
|
+
{% endfor %}
|
14
|
+
{% endif %}
|
15
|
+
|
16
|
+
{% assign namespace = null %}
|
17
|
+
|
18
|
+
{% if include.namespace %}
|
19
|
+
{% assign namespace = include.namespace %}
|
20
|
+
{% endif %}
|
21
|
+
|
22
|
+
|
23
|
+
### Model
|
24
|
+
|
25
|
+
{% include features/rails/rails_resource_model.md model=model %}
|
26
|
+
|
27
|
+
|
28
|
+
### Controller
|
29
|
+
|
30
|
+
{% include features/rails/rails_resource_controller.md model=model namespace=namespace %}
|
31
|
+
|
32
|
+
|
33
|
+
### Routes
|
34
|
+
|
35
|
+
{% include features/rails/rails_resource_routes.md model_name=model.db_name namespace=namespace %}
|
36
|
+
|
37
|
+
|
38
|
+
### Queries
|
39
|
+
|
40
|
+
{% include features/rails/rails_resource_query.md model=model %}
|
41
|
+
|
42
|
+
|
43
|
+
### Serializer
|
44
|
+
|
45
|
+
{% include features/rails/rails_resource_serializer.md model=model %}
|
46
|
+
|
47
|
+
|
48
|
+
### Tests
|
49
|
+
|
50
|
+
TODO
|
@@ -0,0 +1,57 @@
|
|
1
|
+
|
2
|
+
{% assign model=include.model %}
|
3
|
+
|
4
|
+
{% include models/_model.html model=model %}
|
5
|
+
|
6
|
+
### Generate model
|
7
|
+
|
8
|
+
{% capture model_fields_cmd %}{% for field in model.fields %}{% if field.name != "id" %}{% if field.references %}{{ field.name | remove: '_id' }}:references {% else %}{{ field.name }}:{{ field.type }} {% endif %}{% endif %}{% endfor %}{% endcapture %}
|
9
|
+
|
10
|
+
```bash
|
11
|
+
$ rails g model {{ model.name | capitalize }} {{ model_fields_cmd }}
|
12
|
+
```
|
13
|
+
|
14
|
+
Migration:
|
15
|
+
|
16
|
+
{% capture model_migration_file %}{% for field in model.fields %}
|
17
|
+
{% if field.references %}t.references :{{ field.name }}, foreign_key: true, type: :uuid{% if !field.references_optional %}, null: true{% endif %}{% else %}{% if field.name != "id" %}t.{{ field.type }} :{{ field.name }}{% endif %}{% if field.default %}, default: {{ field.default}}{% endif %}{% endif %}{% endfor %}{% endcapture %}
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
# frozen_string_literal: true
|
21
|
+
|
22
|
+
# Creates User Identities
|
23
|
+
class Create{{ model.db_name | capitalize }} < ActiveRecord::Migration[6.0]
|
24
|
+
def change
|
25
|
+
create_table :{{ model.db_name }}, id: :uuid do |t|
|
26
|
+
{{ model_migration_file }}
|
27
|
+
|
28
|
+
t.timestamps
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
```
|
33
|
+
|
34
|
+
### models/{{ model.name | capitalize }}.rb
|
35
|
+
|
36
|
+
{% capture model_relations %}{% for r in model.relations %}
|
37
|
+
{{ r.type }}: {{ r.resource }}{% if r.optional %}, optional: true{% endif %}{% endfor %}{% endcapture %}
|
38
|
+
|
39
|
+
{% capture model_validations %}{% for r in model.validations %}
|
40
|
+
validates :{{ r.field }}{% if r.presence %}, presence: true{% endif%}{% endfor %}{% endcapture %}
|
41
|
+
|
42
|
+
{% capture model_enums %}{% for r in model.fields %}{% if r.enum %}
|
43
|
+
enum {{ r.name }}: { {% for e in r.enum_values %}
|
44
|
+
{{ e.val }}: {{e.key}},{% endfor %}
|
45
|
+
}{% endif %}{% endfor %}{% endcapture %}
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
# frozen_string_literal: true
|
49
|
+
|
50
|
+
# {{ model.name | capitalize }} model
|
51
|
+
class {{ model.name | capitalize }} < ApplicationRecord
|
52
|
+
{{ model_validations }}
|
53
|
+
{{ model_relations }}
|
54
|
+
{{ model_enums }}
|
55
|
+
|
56
|
+
end
|
57
|
+
```
|
@@ -0,0 +1,43 @@
|
|
1
|
+
{% assign model = include.model %}
|
2
|
+
|
3
|
+
`app/queries/{{ model.name }}_query.rb`
|
4
|
+
|
5
|
+
```ruby
|
6
|
+
# frozen_string_literal: true
|
7
|
+
|
8
|
+
# {{ model.name | camelcase }} search query
|
9
|
+
class {{ model.name | camelcase }}Query
|
10
|
+
# def initialize(params = {}, relation = {{ model.name | camelcase }}.left_outer_joins(
|
11
|
+
# :subscriptions
|
12
|
+
# ).preload(:acm_commodities, :acm_company, :acm_dot_numbers)
|
13
|
+
# )
|
14
|
+
def initialize(params = {}, relation = {})
|
15
|
+
@relation = relation
|
16
|
+
@params = params
|
17
|
+
end
|
18
|
+
|
19
|
+
def all
|
20
|
+
@relation
|
21
|
+
end
|
22
|
+
|
23
|
+
def search_{{ model.db_name }}
|
24
|
+
# by_city
|
25
|
+
# by_name(@params[:search])
|
26
|
+
@relation
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
# def by_city
|
32
|
+
# if @params[:city]
|
33
|
+
# @relation = @relation.where('{{ model.db_name}}.city ILIKE ?', "%#{@params[:city]}%")
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# def by_name(name)
|
38
|
+
# if name
|
39
|
+
# @relation = @relation.where('{{ model.db_name}}.name ILIKE ?', "%#{@params[:name]}%")
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
end
|
43
|
+
```
|
@@ -0,0 +1,13 @@
|
|
1
|
+
{% assign model_name = include.model_name %}
|
2
|
+
{% assign namespace = include.namespace %}
|
3
|
+
|
4
|
+
{% assign tab = 0 %}
|
5
|
+
{% capture namespace_modules %}{% for n in namespace %}
|
6
|
+
{{ tab | indent }}namespace :{{ n }} do{% assign tab = tab | plus:1 %}{% endfor %}{% endcapture %}
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
{{ namespace_modules }}
|
10
|
+
resources :{{ model_name}}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
```
|
@@ -0,0 +1,26 @@
|
|
1
|
+
{% assign model = include.model %}
|
2
|
+
|
3
|
+
|
4
|
+
`app/serializers/{{model.name}}_serializer.rb`
|
5
|
+
|
6
|
+
```ruby
|
7
|
+
# frozen_string_literal: true
|
8
|
+
|
9
|
+
# {{ model.name | camelcase }} serializer
|
10
|
+
class {{ model.name | camelcase }}Serializer < ActiveModel::Serializer
|
11
|
+
attributes {% for f in model.fields %}:{{ f.name}},{% endfor %}
|
12
|
+
|
13
|
+
|
14
|
+
# belongs_to :resource
|
15
|
+
# has_many :resource
|
16
|
+
|
17
|
+
# def lat
|
18
|
+
# object.latlng.lat || nil
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# def lng
|
22
|
+
# object.latlng.lon || nil
|
23
|
+
# end
|
24
|
+
end
|
25
|
+
|
26
|
+
```
|
@@ -0,0 +1,131 @@
|
|
1
|
+
Network and API Services norms the way how the application sends HTTP requests.
|
2
|
+
The API Service overrides the Network service by setting the host URL and adding necessary headers.
|
3
|
+
|
4
|
+
### Network Service
|
5
|
+
|
6
|
+
Create file `src/services/NetworkService.js`:
|
7
|
+
|
8
|
+
```javascript
|
9
|
+
import axios from 'axios'
|
10
|
+
|
11
|
+
class NetworkService {
|
12
|
+
static async get(path, query, options) {
|
13
|
+
options = {
|
14
|
+
response: true,
|
15
|
+
queryStringParameters: {},
|
16
|
+
...options
|
17
|
+
}
|
18
|
+
return await axios({
|
19
|
+
url: query ? `${path}?${query}` : path,
|
20
|
+
method: 'get',
|
21
|
+
...options
|
22
|
+
})
|
23
|
+
}
|
24
|
+
|
25
|
+
static async post(path, query, data, options) {
|
26
|
+
options = {
|
27
|
+
response: true,
|
28
|
+
queryStringParameters: {},
|
29
|
+
...options
|
30
|
+
}
|
31
|
+
return await axios({
|
32
|
+
url: query ? `${path}?${query}` : path,
|
33
|
+
data,
|
34
|
+
method: 'post',
|
35
|
+
...options
|
36
|
+
})
|
37
|
+
}
|
38
|
+
|
39
|
+
static async put(path, query, data, options) {
|
40
|
+
options = {
|
41
|
+
response: true,
|
42
|
+
queryStringParameters: {},
|
43
|
+
...options
|
44
|
+
}
|
45
|
+
return await axios({
|
46
|
+
url: query ? `${path}?${query}` : path,
|
47
|
+
data,
|
48
|
+
method: 'put'
|
49
|
+
})
|
50
|
+
}
|
51
|
+
|
52
|
+
static async delete(path, query) {
|
53
|
+
return await axios({
|
54
|
+
url: query ? `${path}?${query}` : path,
|
55
|
+
method: 'delete'
|
56
|
+
})
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
export default NetworkService
|
61
|
+
|
62
|
+
```
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
### API Service
|
67
|
+
|
68
|
+
Add API URL to the config file `src/config/config.js`:
|
69
|
+
|
70
|
+
```
|
71
|
+
const prod = {
|
72
|
+
API_URL: 'https://domain.com/api/v1/',
|
73
|
+
}
|
74
|
+
|
75
|
+
const dev = {
|
76
|
+
API_URL: 'http://xxx.xxx.xx.xx:4000/api/v1/',
|
77
|
+
}
|
78
|
+
```
|
79
|
+
|
80
|
+
Create file `src/services/APIService.js`:
|
81
|
+
|
82
|
+
```javascript
|
83
|
+
import config from '../config/config'
|
84
|
+
import NetworkService from './NetworkService'
|
85
|
+
// import AuthService from './AuthService' // Use to get Auth token to get an access to API
|
86
|
+
|
87
|
+
class APIService {
|
88
|
+
static async get(path, query, options = {}) {
|
89
|
+
/* const header = await AuthService.getAuthToken()
|
90
|
+
const options = Object.assign(options, {
|
91
|
+
headers: header
|
92
|
+
}) */
|
93
|
+
const opts = Object.assign(options, {})
|
94
|
+
const response = await NetworkService.get(config.BACKEND_URL + path, query, opts)
|
95
|
+
return response
|
96
|
+
}
|
97
|
+
|
98
|
+
static async post(path, query, data, options = {}) {
|
99
|
+
/* const header = await AuthService.getAuthToken()
|
100
|
+
const options = Object.assign(options, {
|
101
|
+
headers: header
|
102
|
+
}) */
|
103
|
+
const opts = Object.assign(options, {})
|
104
|
+
const response = await NetworkService.post(config.BACKEND_URL + path, query, data, opts)
|
105
|
+
return response
|
106
|
+
}
|
107
|
+
|
108
|
+
static async put(path, query, data, options = {}) {
|
109
|
+
/* const header = await AuthService.getAuthToken()
|
110
|
+
const options = Object.assign(options, {
|
111
|
+
headers: header
|
112
|
+
}) */
|
113
|
+
const opts = Object.assign(options, {})
|
114
|
+
const response = await NetworkService.put(config.BACKEND_URL + path, query, data, opts)
|
115
|
+
return response
|
116
|
+
}
|
117
|
+
|
118
|
+
static async delete(path, options = {}) {
|
119
|
+
/* const header = await AuthService.getAuthToken()
|
120
|
+
const options = Object.assign(options, {
|
121
|
+
headers: header
|
122
|
+
}) */
|
123
|
+
const opts = Object.assign(opt, {})
|
124
|
+
const response = await NetworkService.delete(config.BACKEND_URL + path, opts)
|
125
|
+
return response
|
126
|
+
}
|
127
|
+
}
|
128
|
+
|
129
|
+
export default APIService
|
130
|
+
|
131
|
+
```
|
@@ -0,0 +1,103 @@
|
|
1
|
+
|
2
|
+
The application should perform initialization on start.
|
3
|
+
|
4
|
+
The default strategy is to execute successive functions sequentially.
|
5
|
+
Each function is a step that performs one and specific action.
|
6
|
+
If the result is as expected, trigger next function. If the result is not as expected, stop the chain and return the response.
|
7
|
+
|
8
|
+
Responses:
|
9
|
+
|
10
|
+
```javascript
|
11
|
+
// SUCCESS
|
12
|
+
// Everything went OK. Handle the returned data, i.e. store the data in Redux with actions.
|
13
|
+
{
|
14
|
+
status: 0,
|
15
|
+
data: { ... }
|
16
|
+
}
|
17
|
+
|
18
|
+
// ERROR
|
19
|
+
// Something went wrong and application cannot be loaded
|
20
|
+
{
|
21
|
+
status: 1,
|
22
|
+
error: 'API_UNREACHABLE', // The error code
|
23
|
+
data: { ... } // optional
|
24
|
+
}
|
25
|
+
|
26
|
+
// REDIRECT
|
27
|
+
// The application should redirect the user
|
28
|
+
{
|
29
|
+
status: 2,
|
30
|
+
url: '/sign-in', // User has to be redirected
|
31
|
+
message: 'MESSAGE_CODE' // i.e. message to display to the user
|
32
|
+
}
|
33
|
+
```
|
34
|
+
|
35
|
+
### Plan
|
36
|
+
|
37
|
+
#### 1. Add initialization script
|
38
|
+
|
39
|
+
```javascript
|
40
|
+
// src/Init.js
|
41
|
+
/**
|
42
|
+
* Initialization script loading functions in a sequence.
|
43
|
+
*
|
44
|
+
* Statuses:
|
45
|
+
* 0 - sequence has been halted. It may mean that there was an error during initialization
|
46
|
+
* 1 - initialized with success.
|
47
|
+
* 2 - redirection
|
48
|
+
*
|
49
|
+
* @returns
|
50
|
+
*/
|
51
|
+
class Init {
|
52
|
+
static init() {
|
53
|
+
return this.firstFunction()
|
54
|
+
}
|
55
|
+
|
56
|
+
static async firstFunction() {
|
57
|
+
if (true) {
|
58
|
+
return this.secondFunction()
|
59
|
+
}
|
60
|
+
return {
|
61
|
+
status: 0,
|
62
|
+
message: 'APP_INITIALIZATION_FAILED',
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
static async secondFunction() {
|
67
|
+
return {
|
68
|
+
status: 0,
|
69
|
+
message: 'SUCCESS',
|
70
|
+
data: { a: 1, b: 2 }
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
export default Init
|
76
|
+
```
|
77
|
+
|
78
|
+
#### 2. Execute initialization script:
|
79
|
+
|
80
|
+
```
|
81
|
+
// src/App.jsx
|
82
|
+
import Init from './Init.js'
|
83
|
+
|
84
|
+
function App() {
|
85
|
+
const [initPerformed, setInitPerformed] = useState(false)
|
86
|
+
useEffect(() => {
|
87
|
+
if (!initPerformed) {
|
88
|
+
initializeApp()
|
89
|
+
}
|
90
|
+
}, [initPerformed])
|
91
|
+
|
92
|
+
async function initializeApp() {
|
93
|
+
await Init.init()
|
94
|
+
// OR:
|
95
|
+
// const response = await Init.init()
|
96
|
+
// Do something with response.. (i.e. Set Redux), check status (0,1,2), etc.
|
97
|
+
setInitPerformed(true)
|
98
|
+
}
|
99
|
+
|
100
|
+
(...)
|
101
|
+
}
|
102
|
+
|
103
|
+
```
|
@@ -189,6 +189,20 @@ Rails.application.config.generators do |g|
|
|
189
189
|
end
|
190
190
|
```
|
191
191
|
|
192
|
+
Generate migration:
|
193
|
+
|
194
|
+
```bash
|
195
|
+
$ rails g migration enable_uuid
|
196
|
+
```
|
197
|
+
|
198
|
+
```ruby
|
199
|
+
class EnableUUID < ActiveRecord::Migration
|
200
|
+
def change
|
201
|
+
enable_extension 'pgcrypto'
|
202
|
+
end
|
203
|
+
end
|
204
|
+
```
|
205
|
+
|
192
206
|
|
193
207
|
#### Apipie
|
194
208
|
|
@@ -0,0 +1,91 @@
|
|
1
|
+
## How to share documentation
|
2
|
+
|
3
|
+
|
4
|
+
### 1. Build project
|
5
|
+
|
6
|
+
1. Build Jekyll project:
|
7
|
+
|
8
|
+
```
|
9
|
+
$ bundle exec jekyll build
|
10
|
+
```
|
11
|
+
|
12
|
+
2. Copy/download the content of the `_site` folder.
|
13
|
+
|
14
|
+
3. You can also zip the content of `_site` folder before download:
|
15
|
+
|
16
|
+
```
|
17
|
+
$ zip -r docs.zip _site/
|
18
|
+
```
|
19
|
+
|
20
|
+
|
21
|
+
### 2. Share
|
22
|
+
|
23
|
+
The built project (the `_site` folder) is a static website.
|
24
|
+
|
25
|
+
|
26
|
+
#### 2.1 Open on the computer
|
27
|
+
|
28
|
+
Download the project on local computer, navigate to the folder and open the `index.html`.
|
29
|
+
|
30
|
+
|
31
|
+
#### 2.2 Host on VPS
|
32
|
+
|
33
|
+
1. Copy files to the `/var/www/{project-name}` folder
|
34
|
+
2. Create a new file in `/etc/nginx/sites-available/{project-name}.conf`
|
35
|
+
3. Paste following configuration and adjust: port number, path to the `/var/www/{project-name}`
|
36
|
+
|
37
|
+
server {
|
38
|
+
listen 4004 default_server;
|
39
|
+
listen [::]:4004 default_server;
|
40
|
+
|
41
|
+
root /var/www/{project-name};
|
42
|
+
|
43
|
+
server_name _;
|
44
|
+
|
45
|
+
location / {
|
46
|
+
# First attempt to serve request as file, then as directory, then fall back to displaying a 404.
|
47
|
+
try_files $uri $uri/ =404;
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
4. Add symlink
|
52
|
+
|
53
|
+
$ ln -s /etc/nginx/sites-available/{project-name}.conf /etc/nginx/sites-enabled/
|
54
|
+
|
55
|
+
|
56
|
+
5. Test configuration
|
57
|
+
|
58
|
+
$ nginx -t
|
59
|
+
|
60
|
+
6. Reload NGINX
|
61
|
+
|
62
|
+
$ systemctl reload nginx
|
63
|
+
|
64
|
+
|
65
|
+
##### 2.2.1 Add basic auth
|
66
|
+
|
67
|
+
1. Verify that apache2-utils (Debian, Ubuntu) or httpd-tools (RHEL/CentOS/Oracle Linux) is installed.
|
68
|
+
|
69
|
+
2. Create credentials
|
70
|
+
|
71
|
+
$ sudo htpasswd -c /etc/nginx/.htpasswd user1
|
72
|
+
|
73
|
+
3. Edit `/etc/nginx/sites-available/{project-name}.conf`
|
74
|
+
|
75
|
+
location / {
|
76
|
+
auth_basic "Private Property";
|
77
|
+
auth_basic_user_file /etc/nginx/.htpasswd;
|
78
|
+
}
|
79
|
+
|
80
|
+
4. Test configuration and reload nginx
|
81
|
+
|
82
|
+
$ nginx -t
|
83
|
+
$ systemctl reload nginx
|
84
|
+
|
85
|
+
|
86
|
+
#### 2.3 Host on the AWS S3
|
87
|
+
|
88
|
+
1. Create new bucket
|
89
|
+
2. Upload files
|
90
|
+
3. Set up ACL, permissions, CORS
|
91
|
+
4. Set up S3 bucket as hosting
|
data/_includes/nav.html
CHANGED
@@ -38,10 +38,22 @@
|
|
38
38
|
<li{{ current }}>
|
39
39
|
<a href="{{ site.baseurl }}{{ doc.url }}" class='ad-nav-link'>
|
40
40
|
<span class='title'>{{ doc.title }}</span>
|
41
|
-
{% if doc.status
|
41
|
+
{% if doc.status or doc.prio or doc.version or doc.vtags or doc.vtag %}
|
42
42
|
<div class='doc-meta-nav'>
|
43
|
-
|
44
|
-
|
43
|
+
{% if doc.status %}
|
44
|
+
<span class='tag tag--{{ doc.status }} feature-meta__status--{{ doc.status }}'>{{ doc.status }}</span>
|
45
|
+
{% endif %}
|
46
|
+
{% if doc.prio %}
|
47
|
+
<span class='tag tag--{{ doc.prio }} feature-meta__status--{{ doc.prio }}'>{{ doc.prio }}</span>
|
48
|
+
{% endif %}
|
49
|
+
{% if doc.vtag %}
|
50
|
+
<span class='tag tag--{{ doc.vtag | replace: " ", "-" }} feature-meta__status--{{ doc.vtag | replace: " ", "-" }}'>{{ doc.vtag }}</span>
|
51
|
+
{% endif %}
|
52
|
+
{% if doc.vtags %}
|
53
|
+
{% for vtag in doc.vtags %}
|
54
|
+
<span class='tag tag--{{ vtag | replace: " ", "-" }} feature-meta__status--{{ vtag | replace: " ", "-" }}'>{{ vtag }}</span>
|
55
|
+
{% endfor %}
|
56
|
+
{% endif %}
|
45
57
|
<span class='version'>{{ doc.version }}</span>
|
46
58
|
</div>
|
47
59
|
{% endif %}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
{% assign rlist = include.list %}
|
2
|
+
{% assign rtitle = include.title %}
|
3
|
+
{% if rtitle %}
|
4
|
+
<h2>{{ rtitle | upcase }}</h2>
|
5
|
+
{% endif %}
|
6
|
+
|
7
|
+
<div class="requirements-list">
|
8
|
+
{% for r in rlist %}
|
9
|
+
<div class="requirements-list__item">
|
10
|
+
{% if r.status %}
|
11
|
+
<span class="requirements-list__status tag">{{ r.status }}</span>
|
12
|
+
{% endif %}
|
13
|
+
|
14
|
+
<h3><span class="requirements-list__id">{{ r.id }}</span> {{ r.title }}</h3>
|
15
|
+
|
16
|
+
{% if r.description %}
|
17
|
+
<p>{{ r.description }}</p>
|
18
|
+
{% endif %}
|
19
|
+
|
20
|
+
{% if r.links %}
|
21
|
+
<ul class="links">
|
22
|
+
{% for l in r.links %}
|
23
|
+
{% assign link_name = l.source %}
|
24
|
+
{% if l.name %}
|
25
|
+
{% assign link_name = l.name %}
|
26
|
+
{% endif %}
|
27
|
+
<li>
|
28
|
+
<a href="{{ l.source }}">{{ link_name }}</a>
|
29
|
+
</li>
|
30
|
+
{% endfor %}
|
31
|
+
</ul>
|
32
|
+
{% endif %}
|
33
|
+
</div>
|
34
|
+
{% endfor %}
|
35
|
+
</div>
|
@@ -354,6 +354,7 @@ button.ad-collapsible, .ad-collapsible {
|
|
354
354
|
|
355
355
|
.ad-doc__content {
|
356
356
|
padding: 15px;
|
357
|
+
max-width: 800px;
|
357
358
|
|
358
359
|
img {
|
359
360
|
max-width: 100%;
|
@@ -510,6 +511,13 @@ button.ad-collapsible, .ad-collapsible {
|
|
510
511
|
&.tag--high {
|
511
512
|
background: #F20455;
|
512
513
|
}
|
514
|
+
|
515
|
+
&.tag--epic {
|
516
|
+
background: #0392CC;
|
517
|
+
}
|
518
|
+
&.tag--user-story {
|
519
|
+
background: #ABC9B8;
|
520
|
+
}
|
513
521
|
}
|
514
522
|
|
515
523
|
.ad-nav-link {
|
@@ -576,6 +584,31 @@ button.ad-collapsible, .ad-collapsible {
|
|
576
584
|
}
|
577
585
|
}
|
578
586
|
|
587
|
+
.requirements-list {
|
588
|
+
padding-top: 40px;
|
589
|
+
padding-bottom: 40px;
|
590
|
+
.requirements-list__item {
|
591
|
+
border-bottom: 1px solid $gray-200;
|
592
|
+
padding-top: 20px;
|
593
|
+
padding-bottom: 20px;
|
594
|
+
h4 {
|
595
|
+
margin-top: 0px;
|
596
|
+
}
|
597
|
+
.requirements-list__id {
|
598
|
+
font-size: 10px;
|
599
|
+
color: $primary-color;
|
600
|
+
}
|
601
|
+
ul.links {
|
602
|
+
margin-top: 20px;
|
603
|
+
list-style: none;
|
604
|
+
padding-left: 0;
|
605
|
+
margin-top: 3px;
|
606
|
+
margin-bottom: 3px;
|
607
|
+
font-size: 14px;
|
608
|
+
}
|
609
|
+
}
|
610
|
+
}
|
611
|
+
|
579
612
|
code.highlighter-rouge {
|
580
613
|
background: $code-bg;
|
581
614
|
padding: 1px 3px;
|
@@ -588,6 +621,7 @@ pre.highlight {
|
|
588
621
|
background: $code-bg;
|
589
622
|
border: 1px solid $gray-400;
|
590
623
|
border-radius: 3px;
|
624
|
+
overflow-x: auto;
|
591
625
|
.k {
|
592
626
|
color: #e00bbc;
|
593
627
|
font-weight: bold;
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll-theme-alta-docs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Antas
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jekyll
|
@@ -90,6 +90,14 @@ files:
|
|
90
90
|
- LICENSE.txt
|
91
91
|
- README.md
|
92
92
|
- _includes/feature_meta.html
|
93
|
+
- _includes/features/rails/rails_resource_controller.md
|
94
|
+
- _includes/features/rails/rails_resource_development.md
|
95
|
+
- _includes/features/rails/rails_resource_model.md
|
96
|
+
- _includes/features/rails/rails_resource_query.md
|
97
|
+
- _includes/features/rails/rails_resource_routes.md
|
98
|
+
- _includes/features/rails/rails_resource_serializer.md
|
99
|
+
- _includes/features/react/api_service.md
|
100
|
+
- _includes/features/react/app_init.md
|
93
101
|
- _includes/footer.html
|
94
102
|
- _includes/guidelines/rails/api_only_project_tree.md
|
95
103
|
- _includes/guidelines/rails/api_only_project_tree_with_files.md
|
@@ -100,11 +108,13 @@ files:
|
|
100
108
|
- _includes/guidelines/react/react_project_tree.md
|
101
109
|
- _includes/head.html
|
102
110
|
- _includes/head_scripts.html
|
111
|
+
- _includes/instructions/how_to_share_documentation.md
|
103
112
|
- _includes/models/_model.html
|
104
113
|
- _includes/models/_models_list.html
|
105
114
|
- _includes/nav.html
|
106
115
|
- _includes/navbar.html
|
107
116
|
- _includes/project_overview.html
|
117
|
+
- _includes/requirements_list.html
|
108
118
|
- _includes/scripts.html
|
109
119
|
- _includes/sidebar.html
|
110
120
|
- _includes/system_components_overview.html
|
@@ -139,5 +149,5 @@ requirements: []
|
|
139
149
|
rubygems_version: 3.0.3
|
140
150
|
signing_key:
|
141
151
|
specification_version: 4
|
142
|
-
summary: The Jekyll theme for documenting software development projects
|
152
|
+
summary: The Jekyll theme for documenting software development projects.
|
143
153
|
test_files: []
|