jekyll-admin 0.8.0 → 0.10.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE +21 -21
  3. data/README.md +94 -54
  4. data/lib/jekyll-admin.rb +47 -46
  5. data/lib/jekyll-admin/apiable.rb +224 -162
  6. data/lib/jekyll-admin/data_file.rb +106 -103
  7. data/lib/jekyll-admin/directory.rb +72 -73
  8. data/lib/jekyll-admin/file_helper.rb +91 -78
  9. data/lib/jekyll-admin/path_helper.rb +87 -78
  10. data/lib/jekyll-admin/public/asset-manifest.json +27 -0
  11. data/lib/jekyll-admin/public/index.html +1 -12
  12. data/lib/jekyll-admin/public/precache-manifest.5e08ed7edb8d446719b76ae6ead9e3fe.js +78 -0
  13. data/lib/jekyll-admin/public/service-worker.js +39 -0
  14. data/lib/jekyll-admin/public/static/css/2.b74256fb.chunk.css +2 -0
  15. data/lib/jekyll-admin/public/static/css/2.b74256fb.chunk.css.map +1 -0
  16. data/lib/jekyll-admin/public/static/css/main.7e0a6705.chunk.css +5 -0
  17. data/lib/jekyll-admin/public/static/css/main.7e0a6705.chunk.css.map +1 -0
  18. data/lib/jekyll-admin/public/static/js/2.a50fa19f.chunk.js +3 -0
  19. data/lib/jekyll-admin/public/static/js/2.a50fa19f.chunk.js.LICENSE.txt +67 -0
  20. data/lib/jekyll-admin/public/static/js/2.a50fa19f.chunk.js.map +1 -0
  21. data/lib/jekyll-admin/public/static/js/main.f3346e4e.chunk.js +2 -0
  22. data/lib/jekyll-admin/public/static/js/main.f3346e4e.chunk.js.map +1 -0
  23. data/lib/jekyll-admin/public/static/js/runtime-main.95f94e60.js +2 -0
  24. data/lib/jekyll-admin/public/static/js/runtime-main.95f94e60.js.map +1 -0
  25. data/lib/jekyll-admin/public/{1dc35d25e61d819a9c357074014867ab.ttf → static/media/fontawesome-webfont.1dc35d25.ttf} +0 -0
  26. data/lib/jekyll-admin/public/{d7c639084f684d66a1bc66855d193ed8.svg → static/media/fontawesome-webfont.24c601e7.svg} +684 -684
  27. data/lib/jekyll-admin/public/{25a32416abee198dd821b0b17a198a8f.eot → static/media/fontawesome-webfont.25a32416.eot} +0 -0
  28. data/lib/jekyll-admin/public/{c8ddf1e5e5bf3682bc7bebf30f394148.woff → static/media/fontawesome-webfont.c8ddf1e5.woff} +0 -0
  29. data/lib/jekyll-admin/public/{e6cf7c6ec7c2d6f670ae9d762604cb0b.woff2 → static/media/fontawesome-webfont.e6cf7c6e.woff2} +0 -0
  30. data/lib/jekyll-admin/public/{55131026930a0cd4539d1e2fdb92722d.ttf → static/media/lato-bold.55131026.ttf} +0 -0
  31. data/lib/jekyll-admin/public/{059514c92565e4045da1a69525dd9ec0.ttf → static/media/lato-regular.059514c9.ttf} +0 -0
  32. data/lib/jekyll-admin/public/{a770b6797b68e3f8920e473eb824bac0.gif → static/media/loader-big.a770b679.gif} +0 -0
  33. data/lib/jekyll-admin/public/static/media/rw-widgets.12f0820c.woff +0 -0
  34. data/lib/jekyll-admin/public/{03945ac4fc7fdefc44bc110bf1ba2393.svg → static/media/rw-widgets.792dcd18.svg} +14 -8
  35. data/lib/jekyll-admin/public/{e44520ab9079ea7633bfa874bed5d21d.eot → static/media/rw-widgets.bc7c4a59.eot} +0 -0
  36. data/lib/jekyll-admin/public/{bfc14ac982326f7d0b1340e20d3e0c37.ttf → static/media/rw-widgets.eceddf47.ttf} +0 -0
  37. data/lib/jekyll-admin/server.rb +108 -101
  38. data/lib/jekyll-admin/server/{collection.rb → collections.rb} +89 -82
  39. data/lib/jekyll-admin/server/configuration.rb +60 -57
  40. data/lib/jekyll-admin/server/data.rb +84 -82
  41. data/lib/jekyll-admin/server/{draft.rb → drafts.rb} +114 -110
  42. data/lib/jekyll-admin/server/{page.rb → pages.rb} +109 -90
  43. data/lib/jekyll-admin/server/site_meta.rb +25 -0
  44. data/lib/jekyll-admin/server/static_files.rb +83 -0
  45. data/lib/jekyll-admin/static_server.rb +26 -24
  46. data/lib/jekyll-admin/urlable.rb +75 -67
  47. data/lib/jekyll-admin/version.rb +5 -3
  48. data/lib/jekyll/commands/serve.rb +30 -24
  49. metadata +57 -59
  50. data/lib/jekyll-admin/page_without_a_file.rb +0 -7
  51. data/lib/jekyll-admin/public/33a752211d05af6684e26ec63c2ed965.gif +0 -0
  52. data/lib/jekyll-admin/public/8b4968b70019a0551a72940c5a2020d3.png +0 -0
  53. data/lib/jekyll-admin/public/8ea28ca3bfdf27145068e81dd07a34c6.png +0 -0
  54. data/lib/jekyll-admin/public/99adb54b0f30c0758bb4cb9ed5b80aa8.woff +0 -0
  55. data/lib/jekyll-admin/public/bundle.js +0 -117
  56. data/lib/jekyll-admin/public/bundle.js.map +0 -1
  57. data/lib/jekyll-admin/public/styles.css +0 -5
  58. data/lib/jekyll-admin/public/styles.css.map +0 -1
  59. data/lib/jekyll-admin/server/static_file.rb +0 -61
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c6c8cb4b507e24358e055d92c823931ddba82099
4
- data.tar.gz: 2f9057824d1dab4285a596022a98618feef283da
2
+ SHA256:
3
+ metadata.gz: c93755ba95fdfd4f990c1acf408229fbed7ab74f00346dd790c3d50387ea6a5b
4
+ data.tar.gz: 3fe240a9ee0ebef55deb07de51fcee8ee13fc8db3e511e76e11ca4bc59fd440d
5
5
  SHA512:
6
- metadata.gz: 5adb026ac7cbbd4178e8b83800c94393b59250881dd733f38e38c43e4dd669bf85b6f9c4da011cd7d1956d2a1dbf082a3aa426d3ccde4e3f901c70453f0bec27
7
- data.tar.gz: 4e4afa807df84b51cdbf40a2d3be587de4426b494f8ef59dc309989197d966984de7cdc38dfbf7e75882e144fec7249388df5ca5d53b1dd1314da475d2227dbc
6
+ metadata.gz: daf916c04fa0321001c032e3107b584ebe34158033227de8fd6ae8a0d09a57fc58556dde94eeb6e55a7470dd46e901260871048a841c04ccd09abfbd4915cf36
7
+ data.tar.gz: 99a4956fc3b8eae740a87f1851a4240bbebcfff6ec46b46ab28d517b622ec074a78dcbd0b6fbe349386c3a9187fc57c36b1d78ce92130b201acd9d0a1f9177f7
data/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- The MIT License (MIT)
2
-
3
- Copyright 2016-present Mert Kahyaoğlu and the Jekyll Admin contributors
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- THE SOFTWARE.
1
+ The MIT License (MIT)
2
+
3
+ Copyright 2016-present Mert Kahyaoğlu and the Jekyll Admin contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md CHANGED
@@ -1,54 +1,94 @@
1
- [![Gem Version](https://img.shields.io/gem/v/jekyll-admin.svg)](https://rubygems.org/gems/jekyll-admin)
2
- [![Build Status](https://travis-ci.org/jekyll/jekyll-admin.svg?branch=master)](https://travis-ci.org/jekyll/jekyll-admin)
3
- [![Build status](https://ci.appveyor.com/api/projects/status/biop1r6ae524xlm2/branch/master?svg=true)](https://ci.appveyor.com/project/benbalter/jekyll-admin/branch/master)
4
- [![Coverage Status](https://coveralls.io/repos/github/jekyll/jekyll-admin/badge.svg?branch=master)](https://coveralls.io/github/jekyll/jekyll-admin?branch=master)
5
- [![NPM Dependencies](https://david-dm.org/jekyll/jekyll-admin.svg)](https://david-dm.org/jekyll/jekyll-admin)
6
-
7
- A Jekyll plugin that provides users with a traditional CMS-style graphical interface to author content and administer Jekyll sites. The project is divided into two parts. A Ruby-based HTTP API that handles Jekyll and filesystem operations, and a JavaScript-based front end, built on that API.
8
-
9
- ![screenshot of Jekyll Admin](/screenshot.png)
10
-
11
- ## Installation
12
-
13
- Refer to the [installing plugins](https://jekyllrb.com/docs/plugins/#installing-a-plugin) section of Jekyll's documentation and install the `jekyll-admin` plugin as you would any other plugin. Here's the short version:
14
-
15
- 1. Add the following to your site's Gemfile:
16
-
17
- ```ruby
18
- gem 'jekyll-admin', group: :jekyll_plugins
19
- ```
20
-
21
- 2. Run `bundle install`
22
-
23
- ## Usage
24
-
25
- 1. Start Jekyll as you would normally (`bundle exec jekyll serve`)
26
- 2. Navigate to `http://localhost:4000/admin` to access the administrative interface
27
-
28
- ## Options
29
-
30
- Jekyll Admin related options can be specified in `_config.yml`
31
- under a key called `jekyll_admin`. Currently it has only one option `hidden_links`
32
- which is for hiding unwanted links on the sidebar. The following keys under `hidden_links` can be used in order to hide default links;
33
-
34
- ```yaml
35
- jekyll_admin:
36
- hidden_links:
37
- - posts
38
- - pages
39
- - staticfiles
40
- - datafiles
41
- - configuration
42
- ```
43
-
44
- ## Contributing
45
-
46
- Interested in contributing to Jekyll Admin? We’d love your help. Jekyll Admin is an open source project, built one contribution at a time by users like you. See [the contributing instructions](.github/CONTRIBUTING.md), and [the development docs](http://jekyll.github.io/jekyll-admin/development/) for more information.
47
-
48
- ## Looking for a hosted version?
49
-
50
- Jekyll Admin is intended to be run on your computer alongside your local Jekyll installation. If you're looking for a hosted version, we'd recommend checking out [Siteleaf](https://www.siteleaf.com/) a hosted Jekyll editor with deep GitHub integration (whom we'd also like to thank for inspiring parts of Jekyll Admin itself!).
51
-
52
- ## License
53
-
54
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
1
+ [![Gem Version](https://img.shields.io/gem/v/jekyll-admin.svg)](https://rubygems.org/gems/jekyll-admin)
2
+ [![Build Status](https://travis-ci.org/jekyll/jekyll-admin.svg?branch=master)](https://travis-ci.org/jekyll/jekyll-admin)
3
+ [![Build status](https://ci.appveyor.com/api/projects/status/u6u9tn7rk5tln33s/branch/master?svg=true)](https://ci.appveyor.com/project/jekyll/jekyll-admin)
4
+ [![Coverage Status](https://coveralls.io/repos/github/jekyll/jekyll-admin/badge.svg?branch=master)](https://coveralls.io/github/jekyll/jekyll-admin?branch=master)
5
+ [![NPM Dependencies](https://david-dm.org/jekyll/jekyll-admin.svg)](https://david-dm.org/jekyll/jekyll-admin)
6
+ [![Financial Contributors on Open Collective](https://opencollective.com/jekyll-admin/all/badge.svg?label=financial+contributors)](https://opencollective.com/jekyll-admin)
7
+
8
+ A Jekyll plugin that provides users with a traditional CMS-style graphical interface to author content and administer Jekyll sites. The project is divided into two parts. A Ruby-based HTTP API that handles Jekyll and filesystem operations, and a JavaScript-based front end, built on that API.
9
+
10
+ ![screenshot of Jekyll Admin](/screenshot.png)
11
+
12
+ ## Installation
13
+
14
+ Refer to the [installing plugins](https://jekyllrb.com/docs/plugins/installation/) section of Jekyll's documentation and install the `jekyll-admin` plugin as you would any other plugin. Here's the short version:
15
+
16
+ 1. Add the following to your site's Gemfile:
17
+
18
+ ```ruby
19
+ gem 'jekyll-admin', group: :jekyll_plugins
20
+ ```
21
+
22
+ 2. Run `bundle install`
23
+
24
+ ## Usage
25
+
26
+ 1. Start Jekyll as you would normally (`bundle exec jekyll serve`)
27
+ 2. Navigate to `http://localhost:4000/admin` to access the administrative interface
28
+
29
+ ## Options
30
+
31
+ Jekyll Admin related options can be specified in `_config.yml`
32
+ under a key called `jekyll_admin`. Currently it has only one option `hidden_links`
33
+ which is for hiding unwanted links on the sidebar. The following keys under `hidden_links` can be used in order to hide default links;
34
+
35
+ ```yaml
36
+ jekyll_admin:
37
+ hidden_links:
38
+ - posts
39
+ - pages
40
+ - staticfiles
41
+ - datafiles
42
+ - configuration
43
+ ```
44
+
45
+ ### Customizing collection label in Sidebar
46
+
47
+ The plugin allows you to customize the name of a collection that is displayed in the sidebar by defining it in the collection's
48
+ metadata in the config file. For example, if your source's *posts* are actually *news-items* on the deployed site, then it can
49
+ be distracting to see the label `Posts` in the admin's sidebar. This situation can be resolved with the following configuration:
50
+
51
+ ```yaml
52
+ collections:
53
+ posts:
54
+ output: true
55
+ sidebar_label: News
56
+ ```
57
+
58
+ ## Contributing
59
+
60
+ Interested in contributing to Jekyll Admin? We’d love your help. Jekyll Admin is an open source project, built one contribution at a time by users like you. See [the contributing instructions](.github/CONTRIBUTING.md), and [the development docs](https://jekyll.github.io/jekyll-admin/development/) for more information.
61
+
62
+ ## Contributors
63
+
64
+ ### Code Contributors
65
+
66
+ This project exists thanks to all the people who contribute. [[Contribute](.github/CONTRIBUTING.md)].
67
+ <a href="https://github.com/jekyll/jekyll-admin/graphs/contributors"><img src="https://opencollective.com/jekyll-admin/contributors.svg?width=890&button=false" /></a>
68
+
69
+ ### Financial Contributors
70
+
71
+ Become a financial contributor and help us sustain our community. [[Contribute](https://opencollective.com/jekyll-admin/contribute)]
72
+
73
+ #### Individuals
74
+
75
+ <a href="https://opencollective.com/jekyll-admin"><img src="https://opencollective.com/jekyll-admin/individuals.svg?width=890"></a>
76
+
77
+ #### Organizations
78
+
79
+ Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/jekyll-admin/contribute)]
80
+
81
+ <a href="https://opencollective.com/jekyll-admin/organization/0/website"><img src="https://opencollective.com/jekyll-admin/organization/0/avatar.svg"></a>
82
+ <a href="https://opencollective.com/jekyll-admin/organization/1/website"><img src="https://opencollective.com/jekyll-admin/organization/1/avatar.svg"></a>
83
+ <a href="https://opencollective.com/jekyll-admin/organization/2/website"><img src="https://opencollective.com/jekyll-admin/organization/2/avatar.svg"></a>
84
+ <a href="https://opencollective.com/jekyll-admin/organization/3/website"><img src="https://opencollective.com/jekyll-admin/organization/3/avatar.svg"></a>
85
+ <a href="https://opencollective.com/jekyll-admin/organization/4/website"><img src="https://opencollective.com/jekyll-admin/organization/4/avatar.svg"></a>
86
+ <a href="https://opencollective.com/jekyll-admin/organization/5/website"><img src="https://opencollective.com/jekyll-admin/organization/5/avatar.svg"></a>
87
+ <a href="https://opencollective.com/jekyll-admin/organization/6/website"><img src="https://opencollective.com/jekyll-admin/organization/6/avatar.svg"></a>
88
+ <a href="https://opencollective.com/jekyll-admin/organization/7/website"><img src="https://opencollective.com/jekyll-admin/organization/7/avatar.svg"></a>
89
+ <a href="https://opencollective.com/jekyll-admin/organization/8/website"><img src="https://opencollective.com/jekyll-admin/organization/8/avatar.svg"></a>
90
+ <a href="https://opencollective.com/jekyll-admin/organization/9/website"><img src="https://opencollective.com/jekyll-admin/organization/9/avatar.svg"></a>
91
+
92
+ ## License
93
+
94
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -1,46 +1,47 @@
1
- # Default Sinatra to "production" mode (surpress errors) unless
2
- # otherwise specified by the `RACK_ENV` environmental variable.
3
- # Must be done prior to requiring Sinatra, or we'll get a LoadError
4
- # as it looks for sinatra/cross-origin, which is development only
5
- ENV["RACK_ENV"] = "production" if ENV["RACK_ENV"].to_s.empty?
6
-
7
- require "json"
8
- require "jekyll"
9
- require "base64"
10
- require "webrick"
11
- require "sinatra"
12
- require "fileutils"
13
- require "sinatra/base"
14
- require "sinatra/json"
15
- require "addressable/uri"
16
- require "sinatra/reloader"
17
- require "sinatra/namespace"
18
-
19
- module JekyllAdmin
20
- autoload :APIable, "jekyll-admin/apiable"
21
- autoload :DataFile, "jekyll-admin/data_file"
22
- autoload :Directory, "jekyll-admin/directory"
23
- autoload :FileHelper, "jekyll-admin/file_helper"
24
- autoload :PageWithoutAFile, "jekyll-admin/page_without_a_file"
25
- autoload :PathHelper, "jekyll-admin/path_helper"
26
- autoload :Server, "jekyll-admin/server"
27
- autoload :StaticServer, "jekyll-admin/static_server"
28
- autoload :URLable, "jekyll-admin/urlable"
29
- autoload :Version, "jekyll-admin/version"
30
-
31
- def self.site
32
- @site ||= begin
33
- site = Jekyll.sites.first
34
- site.future = true
35
- site
36
- end
37
- end
38
- end
39
-
40
- # Monkey Patches
41
- require_relative "./jekyll/commands/serve"
42
-
43
- [Jekyll::Page, Jekyll::Document, Jekyll::StaticFile, Jekyll::Collection].each do |klass|
44
- klass.include JekyllAdmin::APIable
45
- klass.include JekyllAdmin::URLable
46
- end
1
+ # frozen_string_literal: true
2
+
3
+ # Default Sinatra to "production" mode (surpress errors) unless
4
+ # otherwise specified by the `RACK_ENV` environmental variable.
5
+ # Must be done prior to requiring Sinatra, or we'll get a LoadError
6
+ # as it looks for sinatra/cross-origin, which is development only
7
+ ENV["RACK_ENV"] = "production" if ENV["RACK_ENV"].to_s.empty?
8
+
9
+ require "json"
10
+ require "jekyll"
11
+ require "base64"
12
+ require "webrick"
13
+ require "sinatra"
14
+ require "fileutils"
15
+ require "sinatra/base"
16
+ require "sinatra/json"
17
+ require "addressable/uri"
18
+ require "sinatra/reloader"
19
+ require "sinatra/namespace"
20
+
21
+ module JekyllAdmin
22
+ autoload :APIable, "jekyll-admin/apiable"
23
+ autoload :DataFile, "jekyll-admin/data_file"
24
+ autoload :Directory, "jekyll-admin/directory"
25
+ autoload :FileHelper, "jekyll-admin/file_helper"
26
+ autoload :PathHelper, "jekyll-admin/path_helper"
27
+ autoload :Server, "jekyll-admin/server"
28
+ autoload :StaticServer, "jekyll-admin/static_server"
29
+ autoload :URLable, "jekyll-admin/urlable"
30
+ autoload :Version, "jekyll-admin/version"
31
+
32
+ def self.site
33
+ @site ||= begin
34
+ site = Jekyll.sites.first
35
+ site.future = true
36
+ site
37
+ end
38
+ end
39
+ end
40
+
41
+ [Jekyll::Page, Jekyll::Document, Jekyll::StaticFile, Jekyll::Collection].each do |klass|
42
+ klass.include JekyllAdmin::APIable
43
+ klass.include JekyllAdmin::URLable
44
+ end
45
+
46
+ # Monkey Patches
47
+ require_relative "jekyll/commands/serve"
@@ -1,162 +1,224 @@
1
- module JekyllAdmin
2
- # Abstract module to be included in Convertible and Document to provide
3
- # additional, API-specific functionality without duplicating logic
4
- module APIable
5
-
6
- CONTENT_FIELDS = %w(next previous content excerpt).freeze
7
-
8
- # Returns a hash suitable for use as an API response.
9
- #
10
- # For Documents and Pages:
11
- #
12
- # 1. Adds the file's raw content to the `raw_content` field
13
- # 2. Adds the file's raw YAML front matter to the `front_matter` field
14
- #
15
- # For Static Files it addes the Base64 `encoded_content` field
16
- #
17
- # Options:
18
- #
19
- # include_content - if true, includes the content in the respond, false by default
20
- # to support mapping on indexes where we only want metadata
21
- #
22
- #
23
- # Returns a hash (which can then be to_json'd)
24
- def to_api(include_content: false)
25
- output = hash_for_api
26
- output = output.merge(url_fields)
27
-
28
- # Include content, if requested, otherwise remove it
29
- if include_content
30
- output = output.merge(content_fields)
31
- else
32
- CONTENT_FIELDS.each { |field| output.delete(field) }
33
- end
34
-
35
- # Documents have duplicate output and content fields, Pages do not
36
- # Since it's an API, use `content` in both for consistency
37
- output.delete("output")
38
-
39
- # By default, calling to_liquid on a collection will return a docs
40
- # array with each rendered document, which we don't want.
41
- if is_a?(Jekyll::Collection)
42
- output.delete("docs")
43
- output["entries_url"] = entries_url
44
- end
45
-
46
- if is_a?(Jekyll::Document)
47
- output["relative_path"] = relative_path.sub("_drafts/", "") if draft?
48
- output["name"] = basename
49
- end
50
-
51
- if is_a?(Jekyll::StaticFile)
52
- output["from_theme"] = from_theme_gem?
53
- end
54
-
55
- output
56
- end
57
-
58
- private
59
-
60
- # Pages don't have a hash method, but Documents do
61
- def file_path
62
- if is_a?(Jekyll::Document)
63
- path
64
- else
65
- File.join(@base, @dir, name)
66
- end
67
- end
68
-
69
- def from_theme_gem?
70
- @base == site.in_theme_dir
71
- end
72
-
73
- # StaticFiles don't have `attr_accesor` set for @site or @name
74
- def site
75
- @site
76
- end
77
-
78
- def name
79
- @name
80
- end
81
-
82
- def file_contents
83
- @file_contents ||= File.read(file_path, file_read_options) if file_exists?
84
- end
85
-
86
- def file_read_options
87
- Jekyll::Utils.merged_file_read_opts(site, {})
88
- end
89
-
90
- def front_matter
91
- return unless file_exists?
92
- @front_matter ||= if file_contents =~ Jekyll::Document::YAML_FRONT_MATTER_REGEXP
93
- SafeYAML.load(Regexp.last_match(1))
94
- else
95
- {}
96
- end
97
- end
98
-
99
- def raw_content
100
- return unless file_exists?
101
- @raw_content ||= if file_contents =~ Jekyll::Document::YAML_FRONT_MATTER_REGEXP
102
- $POSTMATCH
103
- else
104
- file_contents
105
- end
106
- end
107
-
108
- def encoded_content
109
- @encoded_content ||= Base64.encode64(file_contents) if file_exists?
110
- end
111
-
112
- def file_exists?
113
- return @file_exists if defined? @file_exists
114
- @file_exists = File.exist?(file_path)
115
- end
116
-
117
- # Base hash from which to generate the API output
118
- def hash_for_api
119
- output = to_liquid
120
- if output.respond_to?(:hash_for_json)
121
- output.hash_for_json
122
- else
123
- output.to_h
124
- end
125
- end
126
-
127
- # Returns a hash of content fields for inclusion in the API output
128
- def content_fields
129
- output = {}
130
-
131
- # Include file content-related fields
132
- if is_a?(Jekyll::StaticFile)
133
- output["encoded_content"] = encoded_content
134
- elsif is_a?(JekyllAdmin::DataFile)
135
- output["content"] = content
136
- output["raw_content"] = raw_content
137
- else
138
- output["raw_content"] = raw_content
139
- output["front_matter"] = front_matter
140
- end
141
-
142
- # Include next and previous documents non-recursively
143
- if is_a?(Jekyll::Document)
144
- %w(next previous).each do |direction|
145
- method = "#{direction}_doc".to_sym
146
- doc = public_send(method)
147
- output[direction] = doc.to_api if doc
148
- end
149
- end
150
-
151
- output
152
- end
153
-
154
- def url_fields
155
- return {} unless respond_to?(:http_url) && respond_to?(:api_url)
156
- {
157
- "http_url" => http_url,
158
- "api_url" => api_url,
159
- }
160
- end
161
- end
162
- end
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllAdmin
4
+ # Abstract module to be included in Convertible and Document to provide
5
+ # additional, API-specific functionality without duplicating logic
6
+ module APIable
7
+ CONTENT_FIELDS = %w(next previous content excerpt).freeze
8
+ API_SCAFFOLD = %w(name path relative_path).map { |i| [i, nil] }.to_h.freeze
9
+
10
+ # Returns a hash suitable for use as an API response.
11
+ #
12
+ # For Documents and Pages:
13
+ #
14
+ # 1. Adds the file's raw content to the `raw_content` field
15
+ # 2. Adds the file's raw YAML front matter to the `front_matter` field
16
+ #
17
+ # For Static Files it addes the Base64 `encoded_content` field
18
+ #
19
+ # Options:
20
+ #
21
+ # include_content - if true, includes the content in the respond, false by default
22
+ # to support mapping on indexes where we only want metadata
23
+ #
24
+ # Returns a hash (which can then be to_json'd)
25
+ def to_api(include_content: false)
26
+ output = API_SCAFFOLD.merge hash_for_api
27
+
28
+ # Include content, if requested, otherwise remove it
29
+ if include_content
30
+ output.merge!(content_fields)
31
+ else
32
+ CONTENT_FIELDS.each { |field| output.delete(field) }
33
+ end
34
+
35
+ # Documents have duplicate output and content fields, Pages do not
36
+ # Since it's an API, use `content` in both for consistency
37
+ output.delete("output")
38
+
39
+ output["name"] = basename if is_a?(Jekyll::Document)
40
+ output["from_theme"] = from_theme_gem? if is_a?(Jekyll::StaticFile)
41
+ output["relative_path"] = relative_path_for_api
42
+
43
+ # By default, calling to_liquid on a collection will return a docs
44
+ # array with each rendered document, which we don't want.
45
+ if is_a?(Jekyll::Collection)
46
+ output.delete("docs")
47
+ output["name"] = label
48
+ output["path"] = relative_directory
49
+ output["entries_url"] = entries_url
50
+ end
51
+
52
+ output.merge!(url_fields)
53
+ output
54
+ end
55
+
56
+ private
57
+
58
+ # Relative path of files and directories with their *special directories*
59
+ # and any leading slashes stripped away.
60
+ #
61
+ # Examples:
62
+ # `_drafts/foo/draft-post.md` => `foo/draft-post.md`
63
+ # `_posts/foo/2019-10-18-hello.md` => `foo/2019-10-18-hello.md`
64
+ # `/assets/img/logo.png` => `assets/img/logo.png`
65
+ def relative_path_for_api
66
+ return unless respond_to?(:relative_path) && relative_path
67
+
68
+ @relative_path_for_api ||= begin
69
+ rel_path = relative_path.dup
70
+ strip_leading_slash!(rel_path)
71
+ strip_leading_special_directory!(rel_path)
72
+ strip_leading_slash!(rel_path)
73
+
74
+ rel_path
75
+ end
76
+ end
77
+
78
+ # Prefer substituting substrings instead of using a regex in order to avoid multiple
79
+ # regex allocations. String literals are frozen and reused.
80
+
81
+ def strip_leading_slash!(path)
82
+ return unless path.start_with?("/")
83
+
84
+ path.sub!("/", "")
85
+ end
86
+
87
+ def strip_leading_special_directory!(path)
88
+ return unless special_directory && path.start_with?(special_directory)
89
+
90
+ path.sub!(special_directory, "")
91
+ end
92
+
93
+ def special_directory
94
+ return @special_directory if defined?(@special_directory)
95
+
96
+ @special_directory = begin
97
+ if is_a?(Jekyll::Document) && draft?
98
+ "_drafts"
99
+ elsif is_a?(Jekyll::Document)
100
+ collection.relative_directory
101
+ elsif is_a?(Jekyll::Collection)
102
+ relative_directory
103
+ end
104
+ end
105
+ end
106
+
107
+ # Pages don't have a hash method, but Documents do
108
+ def file_path
109
+ if is_a?(Jekyll::Document)
110
+ path
111
+ else
112
+ File.join(@base, @dir, name)
113
+ end
114
+ end
115
+
116
+ def from_theme_gem?
117
+ @base == site.in_theme_dir
118
+ end
119
+
120
+ # StaticFiles don't have `attr_accesor` set for @site or @name
121
+ def site
122
+ @site
123
+ end
124
+
125
+ def name
126
+ @name
127
+ end
128
+
129
+ def file_contents
130
+ @file_contents ||= File.read(file_path, file_read_options) if file_exists?
131
+ end
132
+
133
+ def file_read_options
134
+ Jekyll::Utils.merged_file_read_opts(site, {})
135
+ end
136
+
137
+ def front_matter_defaults
138
+ return unless file_exists?
139
+
140
+ @front_matter_defaults ||= begin
141
+ return {} unless respond_to?(:relative_path) && respond_to?(:type)
142
+
143
+ site.frontmatter_defaults.all(relative_path, type)
144
+ end
145
+ end
146
+
147
+ def front_matter
148
+ return unless file_exists?
149
+
150
+ @front_matter ||= if file_contents =~ Jekyll::Document::YAML_FRONT_MATTER_REGEXP
151
+ SafeYAML.load(Regexp.last_match(1))
152
+ else
153
+ {}
154
+ end
155
+ end
156
+
157
+ def raw_content
158
+ return unless file_exists?
159
+
160
+ @raw_content ||= if file_contents =~ Jekyll::Document::YAML_FRONT_MATTER_REGEXP
161
+ $POSTMATCH
162
+ else
163
+ file_contents
164
+ end
165
+ end
166
+
167
+ def encoded_content
168
+ @encoded_content ||= Base64.encode64(file_contents) if file_exists?
169
+ end
170
+
171
+ def file_exists?
172
+ return @file_exists if defined? @file_exists
173
+
174
+ @file_exists = File.exist?(file_path)
175
+ end
176
+
177
+ # Base hash from which to generate the API output
178
+ def hash_for_api
179
+ output = to_liquid
180
+ if output.respond_to?(:hash_for_json)
181
+ output.hash_for_json
182
+ else
183
+ output.to_h
184
+ end
185
+ end
186
+
187
+ # Returns a hash of content fields for inclusion in the API output
188
+ def content_fields
189
+ output = {}
190
+
191
+ # Include file content-related fields
192
+ if is_a?(Jekyll::StaticFile)
193
+ output["encoded_content"] = encoded_content
194
+ elsif is_a?(JekyllAdmin::DataFile)
195
+ output["content"] = content
196
+ output["raw_content"] = raw_content
197
+ else
198
+ output["raw_content"] = raw_content
199
+ output["front_matter"] = front_matter
200
+ output["front_matter_defaults"] = front_matter_defaults
201
+ end
202
+
203
+ # Include next and previous documents non-recursively
204
+ if is_a?(Jekyll::Document)
205
+ %w(next previous).each do |direction|
206
+ method = "#{direction}_doc".to_sym
207
+ doc = public_send(method)
208
+ output[direction] = doc.to_api if doc
209
+ end
210
+ end
211
+
212
+ output
213
+ end
214
+
215
+ def url_fields
216
+ return {} unless respond_to?(:http_url) && respond_to?(:api_url)
217
+
218
+ {
219
+ "http_url" => http_url,
220
+ "api_url" => api_url,
221
+ }
222
+ end
223
+ end
224
+ end