markdown_record 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +225 -0
- data/Rakefile +9 -0
- data/app/assets/config/markdown_cms_manifest.js +1 -0
- data/app/assets/stylesheets/markdown_cms/application.css +15 -0
- data/app/controllers/markdown_record/application_controller.rb +11 -0
- data/app/controllers/markdown_record/content_controller.rb +19 -0
- data/app/controllers/markdown_record/html_controller.rb +11 -0
- data/app/controllers/markdown_record/json_controller.rb +11 -0
- data/app/helpers/markdown_record/application_helper.rb +4 -0
- data/app/helpers/markdown_record/controller_helpers.rb +39 -0
- data/app/helpers/markdown_record/view_helpers.rb +84 -0
- data/app/models/markdown_record/demo/dsl_command.rb +10 -0
- data/app/models/markdown_record/demo/section.rb +9 -0
- data/app/models/markdown_record/tests/child_model.rb +15 -0
- data/app/models/markdown_record/tests/fake_active_record_model.rb +13 -0
- data/app/models/markdown_record/tests/model.rb +15 -0
- data/app/models/markdown_record/tests/other_child_model.rb +15 -0
- data/config/routes.rb +13 -0
- data/lib/generators/markdown_record_generator.rb +44 -0
- data/lib/markdown_record/association.rb +131 -0
- data/lib/markdown_record/associations.rb +106 -0
- data/lib/markdown_record/base.rb +25 -0
- data/lib/markdown_record/cli.rb +54 -0
- data/lib/markdown_record/configuration.rb +66 -0
- data/lib/markdown_record/content_associations.rb +46 -0
- data/lib/markdown_record/content_dsl/attribute.rb +22 -0
- data/lib/markdown_record/content_dsl/directory_fragment.rb +22 -0
- data/lib/markdown_record/content_dsl/disable.rb +22 -0
- data/lib/markdown_record/content_dsl/enable.rb +22 -0
- data/lib/markdown_record/content_dsl/end_attribute.rb +22 -0
- data/lib/markdown_record/content_dsl/end_model.rb +22 -0
- data/lib/markdown_record/content_dsl/fragment.rb +22 -0
- data/lib/markdown_record/content_dsl/model.rb +23 -0
- data/lib/markdown_record/content_dsl/render_format.rb +22 -0
- data/lib/markdown_record/content_dsl/render_strategy.rb +22 -0
- data/lib/markdown_record/content_dsl/use_layout.rb +22 -0
- data/lib/markdown_record/content_dsl.rb +37 -0
- data/lib/markdown_record/content_fragment.rb +123 -0
- data/lib/markdown_record/engine.rb +13 -0
- data/lib/markdown_record/errors/base.rb +6 -0
- data/lib/markdown_record/errors/duplicate_filename_error.rb +21 -0
- data/lib/markdown_record/errors/duplicate_id_error.rb +11 -0
- data/lib/markdown_record/errors/missing_parent_error.rb +11 -0
- data/lib/markdown_record/file_saver.rb +39 -0
- data/lib/markdown_record/html_renderer.rb +194 -0
- data/lib/markdown_record/indexer.rb +34 -0
- data/lib/markdown_record/json_renderer.rb +270 -0
- data/lib/markdown_record/model_inflator.rb +107 -0
- data/lib/markdown_record/path_utilities.rb +86 -0
- data/lib/markdown_record/rendering.rb +57 -0
- data/lib/markdown_record/routes_renderer.rb +0 -0
- data/lib/markdown_record/validator.rb +59 -0
- data/lib/markdown_record/version.rb +3 -0
- data/lib/markdown_record.rb +28 -0
- data/templates/Thorfile +3 -0
- data/templates/base/content/example_content.md +3 -0
- data/templates/base/layouts/_concatenated_layout.html.erb +8 -0
- data/templates/base/layouts/_custom_layout.html.erb +7 -0
- data/templates/base/layouts/_file_layout.html.erb +8 -0
- data/templates/base/layouts/_global_layout.html.erb +8 -0
- data/templates/demo/assets/images/ruby-logo.png +0 -0
- data/templates/demo/content/10_custom_models_and_associations.md.erb +78 -0
- data/templates/demo/content/11_controller_helpers.md.erb +20 -0
- data/templates/demo/content/12_configuration.md.erb +26 -0
- data/templates/demo/content/13_sandbox/1_foo.md +12 -0
- data/templates/demo/content/13_sandbox/2_sandbox_nested/1_bar.md +18 -0
- data/templates/demo/content/1_home.md.erb +40 -0
- data/templates/demo/content/2_installation.md.erb +129 -0
- data/templates/demo/content/3_rendering_basics.md.erb +71 -0
- data/templates/demo/content/4_content_dsl.md.erb +104 -0
- data/templates/demo/content/5_routes.md.erb +43 -0
- data/templates/demo/content/6_model_basics.md.erb +105 -0
- data/templates/demo/content/7_content_frags.md.erb +78 -0
- data/templates/demo/content/8_erb_syntax_and_view_helpers.md.erb +88 -0
- data/templates/demo/content/9_layouts.md.erb +15 -0
- data/templates/demo/layouts/_concatenated_layout.html.erb +12 -0
- data/templates/demo/layouts/_custom_layout.html.erb +14 -0
- data/templates/demo/layouts/_file_layout.html.erb +15 -0
- data/templates/demo/layouts/_global_layout.html.erb +108 -0
- data/templates/markdown_record_initializer.rb +3 -0
- data/templates/render_content.thor +57 -0
- metadata +270 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5cf70bc7bfe4be124645f86a8182c31f2026a5c8c1736b79852e1ca17981b835
|
4
|
+
data.tar.gz: 7ff16d507f7fec68fcf09ecebfa7012cf5c8e700f4ebe74d73e163b83a02cea4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4f28579beda2d8605428020e04db510d9df937513560e5c1c8fb0768767e43573f785584316c7c5748516d9d4881ce0b32db1430a8f658906486af634daf110f
|
7
|
+
data.tar.gz: 5882b40b524c9a121aac21ef9adadc32868e1138c92adc47e8dfbbadc84e71e130526831f3e0a78148f9a04298cdecbae8ac068334542ea788e38d3a0fe16676
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2023 Bryant Morrill
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,225 @@
|
|
1
|
+
# MarkdownRecord
|
2
|
+
|
3
|
+
Welcome to MarkdownRecord. This project is still in BETA stage, and as such is subject to rapid change. There are many things that still need improving, so bear that in mind. That said, please feel free to test this project out and provide feedback in the form of GitHub issues! Thank you.
|
4
|
+
|
5
|
+
MarkdownRecord is a Rails engine that allows you to write markdown with embedded json like this:
|
6
|
+
|
7
|
+
```md
|
8
|
+
<!--model
|
9
|
+
{
|
10
|
+
"type": "markdown_record/demo/section",
|
11
|
+
"id": 3,
|
12
|
+
"name": "Content DSL"
|
13
|
+
}
|
14
|
+
-->
|
15
|
+
|
16
|
+
# Content DSL
|
17
|
+
|
18
|
+
This section describes the Content DSL MarkdownRecord provides to allow you to define application data right alongside your written markdown content.
|
19
|
+
|
20
|
+
While writing documentation in your markdown source files, you can define json data using HTML comments which will then be made available to you within your application code...
|
21
|
+
|
22
|
+
```
|
23
|
+
|
24
|
+
And then interact with your data in your application code like this:
|
25
|
+
|
26
|
+
```ruby
|
27
|
+
MarkdownRecord::Demo::Section.find(3)
|
28
|
+
=> #<MarkdownRecord::Demo::Section filename: "content_dsl", id: 3, name: "Content DSL", subdirectory: "content", type: "markdown_record/demo/section">
|
29
|
+
```
|
30
|
+
|
31
|
+
And render your markdown content as HTML (with full ERB support) like this:
|
32
|
+
|
33
|
+
```html
|
34
|
+
<h1>Content DSL</h1>
|
35
|
+
|
36
|
+
<p>This section describes the Content DSL MarkdownRecord provides to allow you to define application data right alongside your written markdown content.</p>
|
37
|
+
|
38
|
+
<p>While writing documentation in your markdown source files, you can define json data using HTML comments which will then be made available to you within your application code...</p>
|
39
|
+
```
|
40
|
+
|
41
|
+
Or render your markdown content as JSON like this:
|
42
|
+
|
43
|
+
```json
|
44
|
+
{"markdown_record/demo/section":[{"type":"markdown_record/demo/section","id":3,"name":"Content DSL","subdirectory":"content","filename":"content_dsl"}]}
|
45
|
+
```
|
46
|
+
|
47
|
+
## All without creating a single controller, writing a single migration, creating a single view, or defining a single route.
|
48
|
+
|
49
|
+
In other words, MarkdownRecord allows you to write your website's content and define static data at the same time, in the same markdown source file, and have it immediately available to render from your application. By embedding your static data right inside your markdown, or rather extracting your data from your content, you can cut out the hassle of writing database migrations and building forms just to store data that doesn't need to be updated by end users. This approach also helps to keep your application maintainable and consistent, as there will be less code (always a good thing) and only one source of truth for both your written copy and its associated data.
|
50
|
+
|
51
|
+
The MarkdownRecord engine is packed with super useful features, such as content fragments which let you interact with your source files from within your application code, a powerful (and soon to be extensible) markdown Content DSL that lets you extract data out of your written content and interact with it in an object oriented way, and view helpers to make navigating between your rendered HTML content easy.
|
52
|
+
|
53
|
+
---
|
54
|
+
|
55
|
+
## Why use MarkdownRecord?
|
56
|
+
|
57
|
+
MarkdownRecord is a solution for when you need to render written content in your web application, but also need object oriented and relational representations of your written content and the concepts it describes. This is a fairly narrow use case, but there are a few obvious situations where this could come in handy, such as:
|
58
|
+
|
59
|
+
- API documentation that is queryable, such that a client could query for available endpoints, required and optional parameters, etc.
|
60
|
+
- A website containing a blog or other static written copy where you want to attach meta data to it such as topic, keywords, etc.
|
61
|
+
- Hosting the rules for a table top game alongside a character or army building feature which needs to know what options are defined in the rules.
|
62
|
+
- Any situation where you have written copy and you want to represent the relationships between pieces of it or the concepts it describes in an your application code.
|
63
|
+
|
64
|
+
MarkdownRecord could be described as a *server side content management system*, as opposed to client side systems such as WordPress and other common blogging platforms, where the writing and editing are done in a browser. With MarkdownRecord you can write content locally without having to worry about converting it to HTML, storing it in a database or integrating a text editor into your web application. It gives you an alternative and way to deal with data with very few compromises.
|
65
|
+
|
66
|
+
## Why not use MarkdownRecord?
|
67
|
+
|
68
|
+
MarkdownRecord should not be used if the code repository the host application lives in cannot be pushed to whenever content changes (unless there is some work around in place to fetch updated content and render it automatically). Without additional automation in place, you must run a command to have the engine pre-render your content locally, then push the results to wherever your application is hosted. As such, content that requires creating or editing from the client side is not something this engine should be used for.
|
69
|
+
|
70
|
+
---
|
71
|
+
# Usage
|
72
|
+
|
73
|
+
## Installation
|
74
|
+
|
75
|
+
This section explains how to install MarkdownRecord into a host application.
|
76
|
+
|
77
|
+
First, add this line to your application's Gemfile:
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
gem "markdown_record"
|
81
|
+
```
|
82
|
+
|
83
|
+
And then execute:
|
84
|
+
|
85
|
+
```bash
|
86
|
+
$ bundle install
|
87
|
+
```
|
88
|
+
|
89
|
+
Then, from the root directory of your application run:
|
90
|
+
|
91
|
+
```bash
|
92
|
+
$ rails g markdown_record --demo
|
93
|
+
```
|
94
|
+
|
95
|
+
*Note: if you are already familiar with MarkdownRecord and don't want to install the demo content, you can omit the --demo argument.*
|
96
|
+
|
97
|
+
The above command will install the engine, resulting in the following output and changes to your application:
|
98
|
+
|
99
|
+
```bash
|
100
|
+
create markdown_record/content
|
101
|
+
create markdown_record/layouts
|
102
|
+
create markdown_record/rendered
|
103
|
+
exist markdown_record/content
|
104
|
+
create markdown_record/content/controller_helpers.md.erb
|
105
|
+
create markdown_record/content/configuration.md.erb
|
106
|
+
create markdown_record/content/sandbox/foo.md
|
107
|
+
create markdown_record/content/home.md.erb
|
108
|
+
create markdown_record/content/installation.md.erb
|
109
|
+
create markdown_record/content/rendering_basics.md.erb
|
110
|
+
create markdown_record/content/content_dsl.md.erb
|
111
|
+
create markdown_record/content/routes.md.erb
|
112
|
+
create markdown_record/content/model_basics.md.erb
|
113
|
+
create markdown_record/content/content_frags.md.erb
|
114
|
+
create markdown_record/content/erb_syntax_and_view_helpers.md.erb
|
115
|
+
create markdown_record/content/custom_models_and_associations.md.erb
|
116
|
+
exist markdown_record/layouts
|
117
|
+
create markdown_record/layouts/_concatenated_layout.html.erb
|
118
|
+
create markdown_record/layouts/_custom_layout.html.erb
|
119
|
+
create markdown_record/layouts/_file_layout.html.erb
|
120
|
+
create markdown_record/layouts/_global_layout.html.erb
|
121
|
+
exist app/assets/images
|
122
|
+
create app/assets/images/ruby-logo.png
|
123
|
+
create config/initializers/markdown_record.rb
|
124
|
+
create Thorfile
|
125
|
+
create lib/tasks/render_content.thor
|
126
|
+
gsub config/routes.rb
|
127
|
+
```
|
128
|
+
|
129
|
+
The files and folders inside `markdown_record/content` are for demo purposes only, and can be deleted once you are ready to create your own content.
|
130
|
+
|
131
|
+
By default, MarkdownRecord will look in the `markdown_record/content` directory for all your content, and all rendered content will be saved to the `markdown_record/rendered` directory.
|
132
|
+
|
133
|
+
The engine will be mounted in `config/routes.rb` under the `mdr` path by default.
|
134
|
+
|
135
|
+
An initializer will be created for you, where you will be able to configure the engine to use different directories and change other default settings. A later section of this guide will provide more details on configuration options.
|
136
|
+
|
137
|
+
A `Thorfile` and some thor tasks will also be added to your application. These tasks are used to render your content to HTML and JSON.
|
138
|
+
|
139
|
+
The final step in the installation process is to render the demo content that was installed in `markdown_record/content`. To do so, run this Thor task in your application's root directory:
|
140
|
+
|
141
|
+
```bash
|
142
|
+
thor render_content:all -s
|
143
|
+
```
|
144
|
+
|
145
|
+
You should see the following output:
|
146
|
+
|
147
|
+
```bash
|
148
|
+
---------------------------------------------------------------
|
149
|
+
rendering html and json content with options {:concat=>true, :deep=>true, :save=>true, :layout=>"_concatenated_layout.html.erb", :render_content_fragment_json=>true} ...
|
150
|
+
---------------------------------------------------------------
|
151
|
+
rendered: /markdown_record/rendered/content_fragments.json
|
152
|
+
rendered: /markdown_record/rendered/content.json
|
153
|
+
rendered: /markdown_record/rendered/content/custom_models_and_associations_fragments.json
|
154
|
+
rendered: /markdown_record/rendered/content/custom_models_and_associations.json
|
155
|
+
rendered: /markdown_record/rendered/content/erb_syntax_and_view_helpers_fragments.json
|
156
|
+
rendered: /markdown_record/rendered/content/erb_syntax_and_view_helpers.json
|
157
|
+
rendered: /markdown_record/rendered/content/content_frags_fragments.json
|
158
|
+
rendered: /markdown_record/rendered/content/content_frags.json
|
159
|
+
rendered: /markdown_record/rendered/content/model_basics_fragments.json
|
160
|
+
rendered: /markdown_record/rendered/content/model_basics.json
|
161
|
+
rendered: /markdown_record/rendered/content/routes_fragments.json
|
162
|
+
rendered: /markdown_record/rendered/content/routes.json
|
163
|
+
rendered: /markdown_record/rendered/content/content_dsl_fragments.json
|
164
|
+
rendered: /markdown_record/rendered/content/content_dsl.json
|
165
|
+
rendered: /markdown_record/rendered/content/rendering_basics_fragments.json
|
166
|
+
rendered: /markdown_record/rendered/content/rendering_basics.json
|
167
|
+
rendered: /markdown_record/rendered/content/installation_fragments.json
|
168
|
+
rendered: /markdown_record/rendered/content/installation.json
|
169
|
+
rendered: /markdown_record/rendered/content/home_fragments.json
|
170
|
+
rendered: /markdown_record/rendered/content/home.json
|
171
|
+
rendered: /markdown_record/rendered/content/sandbox_fragments.json
|
172
|
+
rendered: /markdown_record/rendered/content/sandbox.json
|
173
|
+
rendered: /markdown_record/rendered/content/sandbox/foo_fragments.json
|
174
|
+
rendered: /markdown_record/rendered/content/sandbox/foo.json
|
175
|
+
rendered: /markdown_record/rendered/content/configuration_fragments.json
|
176
|
+
rendered: /markdown_record/rendered/content/configuration.json
|
177
|
+
rendered: /markdown_record/rendered/content/controller_helpers_fragments.json
|
178
|
+
rendered: /markdown_record/rendered/content/controller_helpers.json
|
179
|
+
rendered: /markdown_record/rendered/content.html
|
180
|
+
rendered: /markdown_record/rendered/content/custom_models_and_associations.html
|
181
|
+
rendered: /markdown_record/rendered/content/erb_syntax_and_view_helpers.html
|
182
|
+
rendered: /markdown_record/rendered/content/content_frags.html
|
183
|
+
rendered: /markdown_record/rendered/content/model_basics.html
|
184
|
+
rendered: /markdown_record/rendered/content/routes.html
|
185
|
+
rendered: /markdown_record/rendered/content/content_dsl.html
|
186
|
+
rendered: /markdown_record/rendered/content/rendering_basics.html
|
187
|
+
rendered: /markdown_record/rendered/content/installation.html
|
188
|
+
rendered: /markdown_record/rendered/content/home.html
|
189
|
+
rendered: /markdown_record/rendered/content/sandbox.html
|
190
|
+
rendered: /markdown_record/rendered/content/sandbox/foo.html
|
191
|
+
rendered: /markdown_record/rendered/content/configuration.html
|
192
|
+
rendered: /markdown_record/rendered/content/controller_helpers.html
|
193
|
+
---------------------------------------------------------------
|
194
|
+
42 files rendered.
|
195
|
+
42 files saved.
|
196
|
+
```
|
197
|
+
|
198
|
+
Congratulations! You have installed MarkdownRecord. If you are not viewing this from the host application already, go ahead and start your Rails server and navigate to http://localhost:3000/mdr/content/home to continue following this guide.
|
199
|
+
|
200
|
+
## Contributing
|
201
|
+
|
202
|
+
Contributions to this project are welcome. Please simply fork the project and open MRs into the main repo if you have something you would like to add or fix. Opening issues for any bugs or improvements you want to be considered is also appreciated.
|
203
|
+
|
204
|
+
While working within this code base, use `rake spec` to run tests. You can pass `SPEC=<path to spec file>` to run a specific spec file, and you make append `:<line number>` to run a specific example.
|
205
|
+
|
206
|
+
Things that need doing:
|
207
|
+
|
208
|
+
- Backfill pending tests
|
209
|
+
- Backfill missing tests
|
210
|
+
- Reorganize the `lib` folder to not be such a mess
|
211
|
+
- Write RDoc docs throughout
|
212
|
+
|
213
|
+
To test a local version of this gem in a local app, simply add the `path` parameter in your gemfile like so:
|
214
|
+
|
215
|
+
```
|
216
|
+
gem "markdown_record", path: "../markdown_record"
|
217
|
+
```
|
218
|
+
|
219
|
+
## Roadmap
|
220
|
+
|
221
|
+
- Make the Content DSL extensible
|
222
|
+
- Add support for raw JSON files as source content
|
223
|
+
|
224
|
+
## License
|
225
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
//= link_directory ../stylesheets/markdown_record .css
|
@@ -0,0 +1,15 @@
|
|
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 any plugin's vendor/assets/stylesheets directory 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 bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module MarkdownRecord
|
2
|
+
class ContentController < ApplicationController
|
3
|
+
def show
|
4
|
+
respond_to do |format|
|
5
|
+
format.html do |html|
|
6
|
+
render_html
|
7
|
+
end
|
8
|
+
format.json { render_json }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def download
|
13
|
+
respond_to do |format|
|
14
|
+
format.html { download_html }
|
15
|
+
format.json { download_json }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module MarkdownRecord
|
2
|
+
module ControllerHelpers
|
3
|
+
def render_html(fragment = content_fragment, layout = MarkdownRecord.config.public_layout)
|
4
|
+
if fragment.html_exists?
|
5
|
+
render file: fragment.html_path, layout: layout
|
6
|
+
else
|
7
|
+
head :not_found
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def render_json(fragment = content_fragment)
|
12
|
+
if fragment.json_exists?
|
13
|
+
render file: fragment.json_path, layout: nil
|
14
|
+
else
|
15
|
+
head :not_found
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def download_html(fragment = content_fragment, layout = MarkdownRecord.config.public_layout)
|
20
|
+
if fragment.html_exists?
|
21
|
+
send_file fragment.html_path, layout: layout
|
22
|
+
else
|
23
|
+
head :not_found
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def download_json(fragment = content_fragment)
|
28
|
+
if fragment.json_exists?
|
29
|
+
send_file fragment.json_path, layout: nil
|
30
|
+
else
|
31
|
+
head :not_found
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def content_fragment(content_path = params[:content_path])
|
36
|
+
::MarkdownRecord::ContentFragment.find(content_path)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module MarkdownRecord
|
2
|
+
module ViewHelpers
|
3
|
+
def link_to_markdown_record(model, name = nil, html_options = nil, &block)
|
4
|
+
return nil if model.nil?
|
5
|
+
|
6
|
+
path = path_to_markdown_record(model, "")
|
7
|
+
name ||= model.name if model.respond_to?(:name)
|
8
|
+
|
9
|
+
block_given? ? link_to(path, html_options, nil, &block) : link_to(name, path, html_options, &block)
|
10
|
+
end
|
11
|
+
|
12
|
+
def link_to_markdown_record_html(model, name = nil, html_options = nil, &block)
|
13
|
+
return nil if model.nil?
|
14
|
+
|
15
|
+
path = path_to_markdown_record_html(model)
|
16
|
+
name ||= model.name if model.respond_to?(:name)
|
17
|
+
|
18
|
+
block_given? ? link_to(path, html_options, nil, &block) : link_to(name, path, html_options, &block)
|
19
|
+
end
|
20
|
+
|
21
|
+
def link_to_download_markdown_record_html(model, name = nil, html_options = nil, &block)
|
22
|
+
return nil if model.nil?
|
23
|
+
|
24
|
+
path = path_to_markdown_record_html(model, true)
|
25
|
+
name ||= model.name if model.respond_to?(:name)
|
26
|
+
|
27
|
+
block_given? ? link_to("/#{path}", html_options, nil, &block) : link_to(name, path, html_options, &block)
|
28
|
+
end
|
29
|
+
|
30
|
+
def path_to_markdown_record_html(model, download = false)
|
31
|
+
path_to_markdown_record(model, "html", download)
|
32
|
+
end
|
33
|
+
|
34
|
+
def url_for_markdown_record_html(model, download = false)
|
35
|
+
path = path_to_markdown_record_html(model, download)
|
36
|
+
|
37
|
+
"#{root_url}/#{path}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def link_to_markdown_record_json(model, name = nil, html_options = nil, &block)
|
41
|
+
return nil if model.nil?
|
42
|
+
|
43
|
+
path = path_to_markdown_record_json(model)
|
44
|
+
name ||= model.name if model.respond_to?(:name)
|
45
|
+
|
46
|
+
block_given? ? link_to(path, html_options, nil, &block) : link_to(name, path, html_options, &block)
|
47
|
+
end
|
48
|
+
|
49
|
+
def link_to_download_markdown_record_json(model, name = nil, html_options = nil, &block)
|
50
|
+
return nil if model.nil?
|
51
|
+
|
52
|
+
path = path_to_markdown_record_json(model, true)
|
53
|
+
name ||= model.name if model.respond_to?(:name)
|
54
|
+
|
55
|
+
block_given? ? link_to("/#{path}", html_options, nil, &block) : link_to(name, path, html_options, &block)
|
56
|
+
end
|
57
|
+
|
58
|
+
def path_to_markdown_record_json(model, download = false)
|
59
|
+
path_to_markdown_record(model, "json", download)
|
60
|
+
end
|
61
|
+
|
62
|
+
def url_for_markdown_record_html(model, download = false)
|
63
|
+
path = path_to_markdown_record_json(model, download)
|
64
|
+
|
65
|
+
"#{root_url}/#{path}"
|
66
|
+
end
|
67
|
+
|
68
|
+
def path_to_markdown_record(model, ext, download = false)
|
69
|
+
raise ArgumentError.new("A MarkdownRecord model must be provided.") unless model&.is_a?(::MarkdownRecord::Base)
|
70
|
+
|
71
|
+
subdirectory = model.fragment_id
|
72
|
+
|
73
|
+
path = Pathname.new(MarkdownRecord.config.mount_path).join(ext)
|
74
|
+
path = path.join("download") if download
|
75
|
+
path = path.join(subdirectory).to_s
|
76
|
+
|
77
|
+
"/#{path}"
|
78
|
+
end
|
79
|
+
|
80
|
+
def render_html_example(example)
|
81
|
+
CGI.escapeHTML(example)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module MarkdownRecord
|
2
|
+
module Tests
|
3
|
+
class ChildModel < ::MarkdownRecord::Base
|
4
|
+
attribute :string_field
|
5
|
+
attribute :int_field
|
6
|
+
attribute :float_field
|
7
|
+
attribute :bool_field
|
8
|
+
attribute :date_field
|
9
|
+
attribute :maybe_field
|
10
|
+
attribute :hash_field
|
11
|
+
|
12
|
+
belongs_to_content :model
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module MarkdownRecord
|
2
|
+
module Tests
|
3
|
+
class FakeActiveRecordModel
|
4
|
+
include ::ActiveAttr::Model
|
5
|
+
include ::MarkdownRecord::ContentAssociations
|
6
|
+
attribute :model_ids
|
7
|
+
attribute :child_model_id
|
8
|
+
|
9
|
+
has_many_content :models
|
10
|
+
belongs_to_content :child_model
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module MarkdownRecord
|
2
|
+
module Tests
|
3
|
+
class Model < ::MarkdownRecord::Base
|
4
|
+
attribute :string_field
|
5
|
+
attribute :int_field
|
6
|
+
attribute :float_field
|
7
|
+
attribute :bool_field
|
8
|
+
attribute :date_field
|
9
|
+
attribute :maybe_field
|
10
|
+
attribute :hash_field
|
11
|
+
|
12
|
+
has_many_content :child_models
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module MarkdownRecord
|
2
|
+
module Tests
|
3
|
+
class OtherChildModel < ::MarkdownRecord::Base
|
4
|
+
attribute :string_field
|
5
|
+
attribute :int_field
|
6
|
+
attribute :float_field
|
7
|
+
attribute :bool_field
|
8
|
+
attribute :date_field
|
9
|
+
attribute :maybe_field
|
10
|
+
attribute :hash_field
|
11
|
+
|
12
|
+
belongs_to_content :model
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
::MarkdownRecord::Engine.routes.draw do
|
2
|
+
routing_config = ::MarkdownRecord.config.routing
|
3
|
+
|
4
|
+
get "html/download/*content_path", to: "html#download" if routing_config[:html].include?(:download)
|
5
|
+
get "html/*content_path", to: "html#show" if routing_config[:html].include?(:show)
|
6
|
+
|
7
|
+
get "json/download/*content_path", to: "json#download" if routing_config[:json].include?(:download)
|
8
|
+
get "json/*content_path", to: "json#show" if routing_config[:json].include?(:show)
|
9
|
+
|
10
|
+
get "download/*content_path", to: "content#download" if routing_config[:content].include?(:download)
|
11
|
+
get "/*content_path", to: "content#show" if routing_config[:content].include?(:show)
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "rails/generators"
|
3
|
+
|
4
|
+
class MarkdownRecordGenerator < Rails::Generators::Base
|
5
|
+
source_root File.expand_path("../../templates", __dir__)
|
6
|
+
class_option :demo, type: :boolean, aliases: :d
|
7
|
+
|
8
|
+
desc "This generator creates the default directories required for markdown_record and copies the default layout into the default location."
|
9
|
+
def create_directories
|
10
|
+
empty_directory "markdown_record/content"
|
11
|
+
empty_directory "markdown_record/layouts"
|
12
|
+
empty_directory "markdown_record/rendered"
|
13
|
+
end
|
14
|
+
|
15
|
+
def copy_demo_or_base
|
16
|
+
if options[:demo]
|
17
|
+
directory "demo/content", "markdown_record/content"
|
18
|
+
directory "demo/layouts", "markdown_record/layouts"
|
19
|
+
directory "demo/assets/images", "app/assets/images"
|
20
|
+
else
|
21
|
+
directory "base/content", "markdown_record/content"
|
22
|
+
directory "base/layouts", "markdown_record/layouts"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def copy_initializer
|
27
|
+
copy_file "markdown_record_initializer.rb", "config/initializers/markdown_record.rb"
|
28
|
+
end
|
29
|
+
|
30
|
+
def copy_thorfile
|
31
|
+
copy_file "Thorfile", "Thorfile"
|
32
|
+
end
|
33
|
+
|
34
|
+
def copy_thor_tasks
|
35
|
+
copy_file "render_content.thor", "lib/tasks/render_content.thor"
|
36
|
+
end
|
37
|
+
|
38
|
+
def mount_engine
|
39
|
+
gsub_file "config/routes.rb", "\n # Do not change this mount path here! Instead change it in the MarkdownRecord initializer.\n mount MarkdownRecord::Engine, at: MarkdownRecord.config.mount_path, as: \"markdown_record\"", ""
|
40
|
+
gsub_file "config/routes.rb", /Rails.application.routes.draw do/, "Rails.application.routes.draw do\n # Do not change this mount path here! Instead change it in the MarkdownRecord initializer.\n mount MarkdownRecord::Engine, at: MarkdownRecord.config.mount_path, as: \"markdown_record\""
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|