jekyll-admin-josercc-josercc 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +54 -0
  4. data/lib/jekyll-admin-josercc.rb +47 -0
  5. data/lib/jekyll-admin-josercc/apiable.rb +153 -0
  6. data/lib/jekyll-admin-josercc/data_file.rb +106 -0
  7. data/lib/jekyll-admin-josercc/directory.rb +70 -0
  8. data/lib/jekyll-admin-josercc/file_helper.rb +64 -0
  9. data/lib/jekyll-admin-josercc/page_without_a_file.rb +7 -0
  10. data/lib/jekyll-admin-josercc/path_helper.rb +74 -0
  11. data/lib/jekyll-admin-josercc/public/03945ac4fc7fdefc44bc110bf1ba2393.svg +18 -0
  12. data/lib/jekyll-admin-josercc/public/059514c92565e4045da1a69525dd9ec0.ttf +0 -0
  13. data/lib/jekyll-admin-josercc/public/1dc35d25e61d819a9c357074014867ab.ttf +0 -0
  14. data/lib/jekyll-admin-josercc/public/25a32416abee198dd821b0b17a198a8f.eot +0 -0
  15. data/lib/jekyll-admin-josercc/public/33a752211d05af6684e26ec63c2ed965.gif +0 -0
  16. data/lib/jekyll-admin-josercc/public/55131026930a0cd4539d1e2fdb92722d.ttf +0 -0
  17. data/lib/jekyll-admin-josercc/public/847c038a8202754b465604459e16715d.png +0 -0
  18. data/lib/jekyll-admin-josercc/public/99adb54b0f30c0758bb4cb9ed5b80aa8.woff +0 -0
  19. data/lib/jekyll-admin-josercc/public/a770b6797b68e3f8920e473eb824bac0.gif +0 -0
  20. data/lib/jekyll-admin-josercc/public/bfc14ac982326f7d0b1340e20d3e0c37.ttf +0 -0
  21. data/lib/jekyll-admin-josercc/public/bundle.js +53 -0
  22. data/lib/jekyll-admin-josercc/public/bundle.js.map +1 -0
  23. data/lib/jekyll-admin-josercc/public/c4c172d28f17a61e4476715c58640841.png +0 -0
  24. data/lib/jekyll-admin-josercc/public/c8ddf1e5e5bf3682bc7bebf30f394148.woff +0 -0
  25. data/lib/jekyll-admin-josercc/public/d7c639084f684d66a1bc66855d193ed8.svg +685 -0
  26. data/lib/jekyll-admin-josercc/public/e44520ab9079ea7633bfa874bed5d21d.eot +0 -0
  27. data/lib/jekyll-admin-josercc/public/e6cf7c6ec7c2d6f670ae9d762604cb0b.woff2 +0 -0
  28. data/lib/jekyll-admin-josercc/public/favicon.ico +0 -0
  29. data/lib/jekyll-admin-josercc/public/index.html +12 -0
  30. data/lib/jekyll-admin-josercc/public/styles.css +5 -0
  31. data/lib/jekyll-admin-josercc/public/styles.css.map +1 -0
  32. data/lib/jekyll-admin-josercc/server.rb +100 -0
  33. data/lib/jekyll-admin-josercc/server/collection.rb +82 -0
  34. data/lib/jekyll-admin-josercc/server/configuration.rb +57 -0
  35. data/lib/jekyll-admin-josercc/server/data.rb +82 -0
  36. data/lib/jekyll-admin-josercc/server/page.rb +90 -0
  37. data/lib/jekyll-admin-josercc/server/static_file.rb +61 -0
  38. data/lib/jekyll-admin-josercc/static_server.rb +24 -0
  39. data/lib/jekyll-admin-josercc/urlable.rb +65 -0
  40. data/lib/jekyll-admin-josercc/version.rb +3 -0
  41. data/lib/jekyll/commands/build.rb +14 -0
  42. data/lib/jekyll/commands/serve.rb +26 -0
  43. metadata +228 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5723ba047b812f6f7694323d930b1ef8097bd683
4
+ data.tar.gz: 1c5a7839083bdd5e70a67108759c586bbe9f9212
5
+ SHA512:
6
+ metadata.gz: f6a55bb99a9b30e3a175b79b7a6624f126977ef69f93a7ee3c063a6a8191f3d459b34a8d9f43be1379dfd9e0e025555771eec4b863cdc40118bb1fbc7c3d93c9
7
+ data.tar.gz: 851eb880cb16e78a5e444f5c5e88d851050c38ec714befbdcf5ff70b181aba0b662eac8fbf0cdcab494cc1c948cbec650c1b34d93139f34a7c226390f6e7c857
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright 2017 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 ADDED
@@ -0,0 +1,54 @@
1
+ [![Gem Version](https://img.shields.io/gem/v/jekyll-admin-josercc.svg)](https://rubygems.org/gems/jekyll-admin-josercc)
2
+ [![Build Status](https://travis-ci.org/jekyll/jekyll-admin-josercc.svg?branch=master)](https://travis-ci.org/jekyll/jekyll-admin-josercc)
3
+ [![Build status](https://ci.appveyor.com/api/projects/status/biop1r6ae524xlm2/branch/master?svg=true)](https://ci.appveyor.com/project/benbalter/jekyll-admin-josercc/branch/master)
4
+ [![Coverage Status](https://coveralls.io/repos/github/jekyll/jekyll-admin-josercc/badge.svg?branch=master)](https://coveralls.io/github/jekyll/jekyll-admin-josercc?branch=master)
5
+ [![NPM Dependencies](https://david-dm.org/jekyll/jekyll-admin-josercc.svg)](https://david-dm.org/jekyll/jekyll-admin-josercc)
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-josercc` 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-josercc', 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-josercc/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).
@@ -0,0 +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-josercc/apiable"
21
+ autoload :DataFile, "jekyll-admin-josercc/data_file"
22
+ autoload :Directory, "jekyll-admin-josercc/directory"
23
+ autoload :FileHelper, "jekyll-admin-josercc/file_helper"
24
+ autoload :PageWithoutAFile, "jekyll-admin-josercc/page_without_a_file"
25
+ autoload :PathHelper, "jekyll-admin-josercc/path_helper"
26
+ autoload :Server, "jekyll-admin-josercc/server"
27
+ autoload :StaticServer, "jekyll-admin-josercc/static_server"
28
+ autoload :URLable, "jekyll-admin-josercc/urlable"
29
+ autoload :Version, "jekyll-admin-josercc/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
+ require_relative "./jekyll/commands/build"
43
+
44
+ [Jekyll::Page, Jekyll::Document, Jekyll::StaticFile, Jekyll::Collection].each do |klass|
45
+ klass.include JekyllAdmin::APIable
46
+ klass.include JekyllAdmin::URLable
47
+ end
@@ -0,0 +1,153 @@
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["name"] = basename
48
+ end
49
+
50
+ output
51
+ end
52
+
53
+ private
54
+
55
+ # Pages don't have a hash method, but Documents do
56
+ def file_path
57
+ if is_a?(Jekyll::Document)
58
+ path
59
+ else
60
+ File.join(@base, @dir, name)
61
+ end
62
+ end
63
+
64
+ # StaticFiles don't have `attr_accesor` set for @site or @name
65
+ def site
66
+ @site
67
+ end
68
+
69
+ def name
70
+ @name
71
+ end
72
+
73
+ def file_contents
74
+ @file_contents ||= File.read(file_path, file_read_options) if file_exists?
75
+ end
76
+
77
+ def file_read_options
78
+ Jekyll::Utils.merged_file_read_opts(site, {})
79
+ end
80
+
81
+ def front_matter
82
+ return unless file_exists?
83
+ @front_matter ||= if file_contents =~ Jekyll::Document::YAML_FRONT_MATTER_REGEXP
84
+ SafeYAML.load(Regexp.last_match(1))
85
+ else
86
+ {}
87
+ end
88
+ end
89
+
90
+ def raw_content
91
+ return unless file_exists?
92
+ @raw_content ||= if file_contents =~ Jekyll::Document::YAML_FRONT_MATTER_REGEXP
93
+ $POSTMATCH
94
+ else
95
+ file_contents
96
+ end
97
+ end
98
+
99
+ def encoded_content
100
+ @encoded_content ||= Base64.encode64(file_contents) if file_exists?
101
+ end
102
+
103
+ def file_exists?
104
+ return @file_exists if defined? @file_exists
105
+ @file_exists = File.exist?(file_path)
106
+ end
107
+
108
+ # Base hash from which to generate the API output
109
+ def hash_for_api
110
+ output = to_liquid
111
+ if output.respond_to?(:hash_for_json)
112
+ output.hash_for_json
113
+ else
114
+ output.to_h
115
+ end
116
+ end
117
+
118
+ # Returns a hash of content fields for inclusion in the API output
119
+ def content_fields
120
+ output = {}
121
+
122
+ # Include file content-related fields
123
+ if is_a?(Jekyll::StaticFile)
124
+ output["encoded_content"] = encoded_content
125
+ elsif is_a?(JekyllAdmin::DataFile)
126
+ output["content"] = content
127
+ output["raw_content"] = raw_content
128
+ else
129
+ output["raw_content"] = raw_content
130
+ output["front_matter"] = front_matter
131
+ end
132
+
133
+ # Include next and previous documents non-recursively
134
+ if is_a?(Jekyll::Document)
135
+ %w(next previous).each do |direction|
136
+ method = "#{direction}_doc".to_sym
137
+ doc = public_send(method)
138
+ output[direction] = doc.to_api if doc
139
+ end
140
+ end
141
+
142
+ output
143
+ end
144
+
145
+ def url_fields
146
+ return {} unless respond_to?(:http_url) && respond_to?(:api_url)
147
+ {
148
+ "http_url" => http_url,
149
+ "api_url" => api_url,
150
+ }
151
+ end
152
+ end
153
+ end
@@ -0,0 +1,106 @@
1
+ module JekyllAdmin
2
+ class DataFile
3
+ METHODS_FOR_LIQUID = %w(path relative_path slug ext title).freeze
4
+ EXTENSIONS = %w(yaml yml json csv).freeze
5
+
6
+ include APIable
7
+ include URLable
8
+ include PathHelper
9
+ extend PathHelper
10
+
11
+ attr_reader :id
12
+
13
+ # Initialize a new DataFile object
14
+ #
15
+ # id - the file ID as passed from the API. This may or may not have an extension
16
+ def initialize(id)
17
+ @id ||= File.extname(id).empty? ? "#{id}.yml" : id
18
+ end
19
+ alias_method :path, :id
20
+
21
+ def exists?
22
+ @exists ||= File.exist?(absolute_path)
23
+ end
24
+
25
+ # Returns unparsed content as it exists on disk
26
+ def raw_content
27
+ @raw_content ||= File.open(absolute_path, "r:UTF-8", &:read)
28
+ end
29
+
30
+ # Returnes (re)parsed content using Jekyll's native parsing mechanism
31
+ def content
32
+ @content ||= data_reader.read_data_file(absolute_path)
33
+ end
34
+
35
+ # Returns the file's extension with preceeding `.`
36
+ def ext
37
+ @ext ||= if File.extname(id).to_s.empty?
38
+ ".yml"
39
+ else
40
+ File.extname(id)
41
+ end
42
+ end
43
+ alias_method :extension, :ext
44
+
45
+ # Returns the file's sanitized slug (as used in `site.data[slug]`)
46
+ def slug
47
+ @slug ||= data_reader.sanitize_filename(basename)
48
+ end
49
+
50
+ # Returns the human-readable title of the data file
51
+ def title
52
+ @title ||= Jekyll::Utils.titleize_slug(slug.tr("_", "-"))
53
+ end
54
+
55
+ # Return path relative to configured `data_dir`
56
+ def relative_path
57
+ id.sub("/#{DataFile.data_dir}/", "")
58
+ end
59
+
60
+ # Return the absolute path to given data file
61
+ def absolute_path
62
+ sanitized_path id
63
+ end
64
+
65
+ # Mimics Jekyll's native to_liquid functionality by returning a hash
66
+ # of data file metadata
67
+ def to_liquid
68
+ @to_liquid ||= METHODS_FOR_LIQUID.map { |key| [key, public_send(key)] }.to_h
69
+ end
70
+
71
+ def self.all
72
+ data_dir = sanitized_path DataFile.data_dir
73
+ files = Dir["#{data_dir}/**/*.{#{EXTENSIONS.join(",")}}"].reject do |d|
74
+ File.directory?(d)
75
+ end
76
+
77
+ files.map do |path|
78
+ new path_without_site_source(path)
79
+ end
80
+ end
81
+
82
+ # Relative path to data directory within site source
83
+ def self.data_dir
84
+ JekyllAdmin.site.config["data_dir"]
85
+ end
86
+
87
+ private
88
+
89
+ def data_reader
90
+ @data_reader = Jekyll::DataReader.new(JekyllAdmin.site)
91
+ end
92
+
93
+ def basename
94
+ @basename ||= File.basename(id, ".*")
95
+ end
96
+
97
+ def basename_with_extension
98
+ [basename, extension].join
99
+ end
100
+ alias_method :filename, :basename_with_extension
101
+
102
+ def namespace
103
+ "data"
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,70 @@
1
+ module JekyllAdmin
2
+ class Directory
3
+ extend Forwardable
4
+ def_delegator :@path, :basename, :name
5
+ def_delegator :@path, :mtime, :modified_time
6
+ attr_reader :path, :splat, :content_type, :base
7
+
8
+ include Enumerable
9
+ include JekyllAdmin::URLable
10
+ include JekyllAdmin::APIable
11
+
12
+ TYPE = :directory
13
+
14
+ # Arguments:
15
+ #
16
+ # path - full path of the directory which its entries will be listed
17
+ #
18
+ # base - passes site.source to generate `relative_path` needed for `to_api`
19
+ #
20
+ # content_type - type of the requested directory entries, this is used to generate
21
+ # API endpoint of the directory along with `splat`
22
+ #
23
+ # splat - the requested directory path relative to content namespace
24
+ def initialize(path, base: nil, content_type: nil, splat: nil)
25
+ @base = Pathname.new base
26
+ @content_type = content_type
27
+ @splat = Pathname.new splat
28
+ @path = Pathname.new path
29
+ end
30
+
31
+ def to_liquid
32
+ {
33
+ :name => name,
34
+ :modified_time => modified_time,
35
+ :path => relative_path,
36
+ :type => TYPE,
37
+ }
38
+ end
39
+
40
+ def relative_path
41
+ path.relative_path_from(base).to_s
42
+ end
43
+
44
+ def resource_path
45
+ if content_type == "pages"
46
+ "/pages/#{splat}/#{name}"
47
+ elsif content_type == "data"
48
+ "/data/#{splat}/#{name}/"
49
+ else
50
+ "/collections/#{content_type}/entries/#{splat}/#{name}"
51
+ end
52
+ end
53
+ alias_method :url, :resource_path
54
+
55
+ def http_url
56
+ nil
57
+ end
58
+
59
+ def directories
60
+ path.entries.map do |entry|
61
+ next if [".", ".."].include? entry.to_s
62
+ next unless path.join(entry).directory?
63
+ self.class.new(
64
+ path.join(entry),
65
+ :base => base, :content_type => content_type, :splat => splat
66
+ )
67
+ end.compact!
68
+ end
69
+ end
70
+ end