satanic_pages 0.1.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e26a94d425f4b9aa926dd89feea4090734e63e94e62f792fb4d13db1eb6b6ea8
4
- data.tar.gz: aa60e1b98f09c40cfcf8be3d4e334624849b36ca2c201d41b5e3776d5af4f4b4
3
+ metadata.gz: 4c0ba138a00f4ba596ba407c0609e62f415cb0e89b570097fd87ae8f04040da1
4
+ data.tar.gz: 12bb35a382f16e9118d2ecc327844dfee1729ae88ca34f78852870168bb900b7
5
5
  SHA512:
6
- metadata.gz: 3b2fb33c968a61afb5067c1fea752548ea873c4392d23bca8e965cabf6c9de9ea40ac4e672eb2e0a951cd6f132f40fb6c9627ef35401f6ee0929f0831cbf371d
7
- data.tar.gz: 3a02d1ca797597f20a8825e8242052047a9eb33e89ac434eced2dfbbac7f920f155825c7e06d491af7fffc8ef9b42871a098cba049b3b26b4cac8d1966a8e744
6
+ metadata.gz: 8bf85437c0980b47b39f2b8c13bfd6225e463520d94c80d7df45544cc5ac6cdf8f1aea921cbf88f5ebd139c48931a3d1477ab571f0e4c12e0472bf77a18b2679
7
+ data.tar.gz: 8d94f595ed06305b1e886ba1cb4085fe5e98b1b10369bdb219ed6fb66b5c8779d36fe4b70186d91286e0deee213f6f1bc4b3423665b4237a5c71060de2433587
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <center><img src="https://s3.brnbw.com/Artboard-GDaMBcpYEJ.png" alt="Satanic Pages" width=762 /></center>
2
2
 
3
- Static pages with YAML frontmatter, embedded in your Rails app.
3
+ Static Markdown pages with YAML frontmatter and inline Erb, embedded in your Rails app.
4
4
 
5
5
  As simple as, …
6
6
  **`app/views/pages/exorcism_tips.html.md`:**
@@ -14,12 +14,12 @@ tags:
14
14
  - devil worship
15
15
  - activity ideas
16
16
  ---
17
- By <%= current_page.author %>.
17
+ By <%= data.author %>.
18
18
 
19
19
  Through trial and error, I've found that the perfect exorcism
20
20
  starts with a refreshing drink.
21
21
 
22
- Tagged <%= render "tag_list", tags: current_page.tags %>:
22
+ Tagged <%= render "tag_list", tags: data.tags %>:
23
23
 
24
24
  ## Devilishly good lemonade recipe
25
25
 
@@ -32,19 +32,41 @@ In `app/views/layouts/pages.html.erb`:
32
32
 
33
33
  ```ruby
34
34
  <%= render_layout "application" do %>
35
- <h1><%= current_page.title %></h1>
35
+ <h1><%= data.title %></h1>
36
36
  <article>
37
37
  <%= yield %>
38
38
  </article>
39
39
  <% end %>
40
40
  ```
41
41
 
42
+ Frontmatter is supplied as a struct like object.
43
+
44
+ Given this frontmatter:
45
+
46
+ ```yaml
47
+ ---
48
+ author: Beelzebub
49
+ ---
50
+ ```
51
+
52
+ Use `!` and `?` method helpers for added strictness.
53
+
54
+ ```ruby
55
+ data.author # => "Beelzebub"
56
+ data.author! # => "Beelzebub"
57
+ data.author? # => true
58
+
59
+ data.title # => nil
60
+ data.title! # => raises SatanicPages::Frontmatter::MissingAttributeError
61
+ data.title? # => false
62
+ ```
63
+
42
64
  ## Installation
43
65
  Add this line to your application's Gemfile:
44
66
 
45
67
  ```sh
46
68
  $ bundle add satanic_pages
47
- $ bundle add markdown-rails # optional, but probably
69
+ $ bundle install
48
70
  ```
49
71
 
50
72
  Add the _Concern_ to a regular controller:
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SatanicPages
2
4
  module Controller
3
5
  extend ActiveSupport::Concern
4
6
 
5
7
  included do
6
- helper_method :current_page
8
+ helper_method :data
7
9
  end
8
10
 
9
11
  class_methods do
@@ -17,37 +19,28 @@ module SatanicPages
17
19
  end
18
20
 
19
21
  def show
20
- @test = "wut"
21
22
  render_static_page
22
23
  end
23
24
 
24
25
  private
25
26
 
26
- def slug_param
27
- params.require(:page)
28
- end
29
-
30
- def pages
31
- self.class.pages
27
+ def render_static_page
28
+ # For nested pages, we need to render the template directly using its full path
29
+ # Construct the template path based on the controller's view path and the page path
30
+ template_path = "#{controller_path}/#{current_page.path}"
31
+ render(template: template_path)
32
32
  end
33
33
 
34
34
  def current_page
35
- pages.find(slug_param)
35
+ @page ||= self.class.pages.find(slug_param)
36
36
  end
37
37
 
38
- # Bit of a hack here. As Rails resolves the layout pretty late, there's no
39
- # public way of looking it up at this point.
40
- # We do however control the rendering, probably, so the only thing we check
41
- # for is if the controller class has called self.layout.
42
- def page_layout
43
- self.class._layout || "application"
38
+ def slug_param
39
+ params.require(:page)
44
40
  end
45
41
 
46
- def render_static_page
47
- # For nested pages, we need to render the template directly using its full path
48
- # Construct the template path based on the controller's view path and the page path
49
- template_path = "#{controller_path}/#{current_page.path}"
50
- render(template: template_path)
42
+ def data
43
+ current_page&.data
51
44
  end
52
45
  end
53
46
  end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SatanicPages
4
+ class Frontmatter
5
+ class MissingAttributeError < StandardError
6
+ end
7
+
8
+ def initialize(hash)
9
+ @hash = (hash&.with_indifferent_access || {}).freeze
10
+ end
11
+
12
+ def to_h
13
+ @hash
14
+ end
15
+
16
+ def method_missing(name, *args)
17
+ if name.to_s.end_with?("!")
18
+ attribute = name.to_s.chomp("!").to_sym
19
+
20
+ unless @hash[attribute]
21
+ raise MissingAttributeError, "Missing attribute: #{name.to_s.chomp("!")}"
22
+ end
23
+
24
+ @hash[attribute]
25
+
26
+ elsif name.to_s.end_with?("?")
27
+ @hash[name.to_s.chomp("?").to_sym].present?
28
+
29
+ else
30
+ @hash[name]
31
+ end
32
+ end
33
+
34
+ def self.parse(source)
35
+ frontmatter = nil
36
+
37
+ rest = source.gsub(/\A---\n(.*?)\n---\n/m) do
38
+ begin
39
+ frontmatter = YAML.safe_load($1)
40
+ ""
41
+ rescue => e
42
+ Rails.logger.error("Error parsing frontmatter: #{e.message}")
43
+ $&
44
+ end
45
+ end
46
+
47
+ [new(frontmatter), rest]
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SatanicPages
4
+ module LayoutHelper
5
+ # Thank you Sitepress for this lil' goodie
6
+ # https://github.com/sitepress/sitepress/blob/738aae7eaef61b494ad90786bc9f796374088ee1/sitepress-server/rails/app/helpers/application_helper.rb#L18
7
+ def render_layout(layout, **kwargs, &block)
8
+ render(html: capture(&block), layout: "layouts/#{layout}", **kwargs)
9
+ end
10
+ end
11
+ end
@@ -1,21 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SatanicPages
2
4
  class MarkdownTemplateHandler < MarkdownRails::Renderer::Rails
3
5
  def preprocess(source)
4
- frontmatter = {}
5
-
6
- content = source.gsub(/\A---\n(.*?)\n---\n/m) do
7
- begin
8
- frontmatter = YAML.safe_load($1)
9
- ""
10
- rescue => e
11
- Rails.logger.error("Error parsing frontmatter: #{e.message}")
12
- $&
13
- end
14
- end
15
-
16
- data = OpenStruct.new(frontmatter)
6
+ frontmatter, rest = Frontmatter.parse(source)
17
7
 
18
- render(inline: content, handler: :erb, locals: {current_page: data})
8
+ render(inline: rest, handler: :erb, locals: {data: frontmatter})
19
9
  # Remove template comments
20
10
  .gsub(/<!-- (BEGIN|END) (.*) -->/, "")
21
11
  # Force HTML tags to be inline
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "ostruct"
4
-
5
3
  module SatanicPages
6
4
  class Page
7
5
  def initialize(full_path, base_path)
@@ -16,8 +14,6 @@ module SatanicPages
16
14
 
17
15
  attr_reader :slug, :path, :full_path, :content, :data
18
16
 
19
- delegate_missing_to :data
20
-
21
17
  private
22
18
 
23
19
  def parse!
@@ -30,17 +26,7 @@ module SatanicPages
30
26
 
31
27
  @raw = File.read(full_path)
32
28
 
33
- @content = @raw.gsub(/\A---\n(.*?)\n---\n/m) do
34
- begin
35
- @data = OpenStruct.new(YAML.safe_load($1))
36
- nil
37
- rescue => e
38
- Rails.logger.error("Error parsing frontmatter: #{e.message}")
39
- $&
40
- end
41
- end
42
-
43
- @data ||= OpenStruct.new
29
+ @data, @content = Frontmatter.parse(@raw)
44
30
  end
45
31
  end
46
32
  end
@@ -5,8 +5,8 @@ module SatanicPages
5
5
  class PageNotFound < StandardError
6
6
  end
7
7
 
8
- def initialize(ctrl)
9
- @base_path = Rails.root.join("app/views/", ctrl)
8
+ def initialize(controller_name)
9
+ @base_path = Rails.root.join("app/views/", controller_name)
10
10
 
11
11
  @pages = Dir[base_path + "**/*.html*"]
12
12
  .reject { |path| path.match?(/(^_|\/_)/) }
@@ -18,12 +18,18 @@ module SatanicPages
18
18
 
19
19
  attr_reader :base_path, :pages
20
20
 
21
- def find(path)
21
+ def find!(path)
22
22
  @pages.fetch(path)
23
23
  rescue KeyError
24
24
  raise PageNotFound, "No page `#{path}' found at #{base_path}"
25
25
  end
26
26
 
27
+ def find(path)
28
+ find!(path)
29
+ rescue PageNotFound
30
+ nil
31
+ end
32
+
27
33
  def match?(req_path)
28
34
  path = req_path.gsub(/^\//, "")
29
35
  pages.keys.include?(path)
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SatanicPages
4
+ class Railtie < ::Rails::Railtie
5
+ initializer("satanic_pages.view_helpers") do
6
+ ActiveSupport.on_load(:action_view) { include SatanicPages::LayoutHelper }
7
+ end
8
+
9
+ initializer("satanic_pages.register_markdown") do
10
+ require "satanic_pages/markdown_template_handler"
11
+
12
+ end
13
+ end
14
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SatanicPages
2
- VERSION = "0.1.2"
4
+ VERSION = "0.3.0"
3
5
  end
data/lib/satanic_pages.rb CHANGED
@@ -1,6 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "markdown-rails"
4
+
1
5
  require "satanic_pages/version"
2
- require "satanic_pages/engine"
6
+ require "satanic_pages/railtie"
3
7
 
8
+ require "satanic_pages/controller"
9
+ require "satanic_pages/frontmatter"
10
+ require "satanic_pages/layout_helper"
4
11
  require "satanic_pages/page"
5
12
  require "satanic_pages/page_list"
6
13
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: satanic_pages
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mikkel Malmberg
@@ -10,33 +10,33 @@ cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
- name: ostruct
13
+ name: rails
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
16
  - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: '0.6'
18
+ version: '7'
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - ">="
24
24
  - !ruby/object:Gem::Version
25
- version: '0.6'
25
+ version: '7'
26
26
  - !ruby/object:Gem::Dependency
27
- name: rails
27
+ name: markdown-rails
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
- version: '7'
32
+ version: '2'
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
- version: '7'
39
+ version: '2'
40
40
  description: An embeddable static pages engine for Rails apps and the devil
41
41
  email:
42
42
  - mikkel@brnbw.com
@@ -47,13 +47,14 @@ files:
47
47
  - MIT-LICENSE
48
48
  - README.md
49
49
  - Rakefile
50
- - app/controllers/concerns/satanic_pages/controller.rb
51
- - app/helpers/satanic_pages/layout_helper.rb
52
50
  - lib/satanic_pages.rb
53
- - lib/satanic_pages/engine.rb
51
+ - lib/satanic_pages/controller.rb
52
+ - lib/satanic_pages/frontmatter.rb
53
+ - lib/satanic_pages/layout_helper.rb
54
54
  - lib/satanic_pages/markdown_template_handler.rb
55
55
  - lib/satanic_pages/page.rb
56
56
  - lib/satanic_pages/page_list.rb
57
+ - lib/satanic_pages/railtie.rb
57
58
  - lib/satanic_pages/version.rb
58
59
  homepage: https://github.com/mikker/satanic_pages
59
60
  licenses:
@@ -1,7 +0,0 @@
1
- module SatanicPages::LayoutHelper
2
- # Thank you Sitepress for this lil' goodie
3
- # https://github.com/sitepress/sitepress/blob/738aae7eaef61b494ad90786bc9f796374088ee1/sitepress-server/rails/app/helpers/application_helper.rb#L18
4
- def render_layout(layout, **kwargs, &block)
5
- render(html: capture(&block), layout: "layouts/#{layout}", **kwargs)
6
- end
7
- end
@@ -1,27 +0,0 @@
1
- module SatanicPages
2
- class Engine < ::Rails::Engine
3
- initializer("satanic_pages.view_helpers") do
4
- require_relative "../../app/helpers/satanic_pages/layout_helper"
5
- ActiveSupport.on_load(:action_view) { include SatanicPages::LayoutHelper }
6
- end
7
-
8
- initializer("satanic_pages.register_markdown") do
9
- if has_markdown_rails?
10
- require "satanic_pages/markdown_template_handler"
11
-
12
- end
13
- end
14
-
15
- private
16
-
17
- def has_markdown_rails?
18
- return true if defined?(MarkdownRails)
19
-
20
- require "markdown-rails"
21
-
22
- true
23
- rescue LoadError
24
- false
25
- end
26
- end
27
- end