sitepress-rails 1.0.1 → 2.0.0.beta1

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: '017964a6b834e56e38daccc09e5fd0c1b348e992cdcc364a4171878f14d5f2ff'
4
- data.tar.gz: 2661db0afdd1e579aa8553af8e698971aac74b1ec0133cf10bab646378fa7e42
3
+ metadata.gz: ef7991baba77ba1d9f5686ec4f8570e60b9ecfbd4d56c9daf0af7a4eef835cfa
4
+ data.tar.gz: 20c870b3d71fb594dbc8c904a74a084d8b67c90b4f5c2f7f7b02c71be69b1ce1
5
5
  SHA512:
6
- metadata.gz: 4301aca15a042853bbe39a53f9530119e82fcb096284c35855fe3d657c4cd04243ee2b4e715532174464a60636481c1d67d7a27f99e3e31c8359547b8e140338
7
- data.tar.gz: e7cb83e9ad10139e84c2fb1fad36f237f37a953021044ebb476c03d4b7cc44e39bf6ca827478bd8e10b4789f68aaaa71c8037fe15fb12c4b31a04e6247cfa661
6
+ metadata.gz: d4b6f85510e7fe4078679203d2f86ac04ac22428463714ce236f06220513443fa64998598c35ac5fdbd6494ff7547743dd4b0539d48d04824e8c775a638d07dc
7
+ data.tar.gz: 16174ec324144ffa5b3b3ea8bc67a93c724713af7a4269a48859653d2cab09db366dd597d0fce3c5fd4418b1948687a79d61e89077b0d04475f1d25d2c0a42d9
@@ -7,12 +7,16 @@ module Sitepress
7
7
  # to return the path to the layout.
8
8
  DEFAULT_PAGE_RAILS_FORMATS = [:html].freeze
9
9
 
10
+ # Default root path of resources.
11
+ ROOT_RESOURCE_PATH = "".freeze
12
+
10
13
  extend ActiveSupport::Concern
11
14
 
12
15
  included do
13
16
  rescue_from Sitepress::PageNotFoundError, with: :page_not_found
14
17
  helper Sitepress::Engine.helpers
15
18
  helper_method :current_page, :site
19
+ before_action :append_relative_partial_path, only: :show
16
20
  end
17
21
 
18
22
  def show
@@ -21,16 +25,15 @@ module Sitepress
21
25
 
22
26
  protected
23
27
  def render_page(page)
24
- with_sitepress_render_cache do
25
- render inline: page.body,
26
- type: page.asset.template_extensions.last,
27
- layout: page.data.fetch("layout", controller_layout),
28
- content_type: page.mime_type.to_s
28
+ if page.renderable?
29
+ render_text_resource page
30
+ else
31
+ send_binary_resource page
29
32
  end
30
33
  end
31
34
 
32
35
  def current_page
33
- @_current_page ||= find_resource
36
+ @current_page ||= find_resource
34
37
  end
35
38
 
36
39
  def site
@@ -42,6 +45,24 @@ module Sitepress
42
45
  end
43
46
 
44
47
  private
48
+ def append_relative_partial_path
49
+ append_view_path current_page.asset.path.dirname
50
+ end
51
+
52
+ def render_text_resource(resource)
53
+ with_sitepress_render_cache do
54
+ render inline: resource.body,
55
+ type: resource.asset.template_extensions.last,
56
+ layout: resource.data.fetch("layout", controller_layout),
57
+ content_type: resource.mime_type.to_s
58
+ end
59
+ end
60
+
61
+ def send_binary_resource(resource)
62
+ send_file resource.asset.path,
63
+ disposition: :inline,
64
+ type: resource.mime_type.to_s
65
+ end
45
66
 
46
67
  # Sitepress::PageNotFoundError is handled in the default Sitepress::SiteController
47
68
  # with an execption that Rails can use to display a 404 error.
@@ -55,9 +76,10 @@ module Sitepress
55
76
  end
56
77
  end
57
78
 
58
- # Default finder of the resource for the current controller context.###
79
+ # Default finder of the resource for the current controller context. If the :resource_path
80
+ # isn't present, then its probably the root path so grab that.
59
81
  def find_resource
60
- get params[:resource_path]
82
+ get params.fetch(:resource_path, ROOT_RESOURCE_PATH)
61
83
  end
62
84
 
63
85
  # When development environments disable the cache, we still want to turn it
@@ -89,8 +111,12 @@ module Sitepress
89
111
 
90
112
  if layout.instance_of? String # Rails 4 and 5 return a string from above.
91
113
  layout
92
- else # Rails 3 and older return an object that gives us a file name
114
+ elsif layout # Rails 3 and older return an object that gives us a file name
93
115
  File.basename(layout.identifier).split('.').first
116
+ else
117
+ # If none of the conditions are met, then no layout was
118
+ # specified, so nil is returned.
119
+ nil
94
120
  end
95
121
  end
96
122
 
@@ -1,5 +1,5 @@
1
1
  module Sitepress
2
- class SiteController < ::ApplicationController
2
+ class SiteController < ActionController::Base
3
3
  # Extracted into a module because other controllers may need
4
4
  # to be capable of serving Sitepress pages.
5
5
  include Sitepress::SitePages
data/config/routes.rb CHANGED
@@ -2,6 +2,11 @@ Sitepress.configuration.parent_engine.routes.draw do
2
2
  if Sitepress.configuration.routes
3
3
  constraints Sitepress::RouteConstraint.new do
4
4
  get "*resource_path", controller: "sitepress/site", action: "show", as: :page, format: false
5
+ if has_named_route? :root
6
+ Rails.logger.warn 'Sitepress tried to configure `root to: "sitepress/site#show"`, but a root route was already defined.'
7
+ else
8
+ root to: "sitepress/site#show"
9
+ end
5
10
  end
6
11
  end
7
12
  end
@@ -0,0 +1,12 @@
1
+ module Sitepress
2
+ module BuildPaths
3
+ # In many cases, you'll want to serve up `pages/blah.html.haml` as `/blah` on
4
+ # hosts like S3. To achieve this effect, we have to compile `pages/blah.html.haml`
5
+ # to a folder with the filename `index.html`, so the final path would be `/blah/index.html`
6
+ class DirectoryIndexPath < IndexPath
7
+ def path_with_default_format
8
+ File.join(node.name, "#{node.default_name}.#{format}")
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,20 @@
1
+ module Sitepress
2
+ module BuildPaths
3
+ # Compiles pages directly from `/pages/blah.html.haml` to `/blah.html`. Handles root `index`
4
+ # pages too, mainly grabbing the root, which doesn't have a name in the node, to the default_name
5
+ # of the node, which is usually `index`.
6
+ class IndexPath < RootPath
7
+ def path_without_format
8
+ node.name
9
+ end
10
+
11
+ def path_with_format
12
+ "#{node.name}.#{format}"
13
+ end
14
+
15
+ def path_with_default_format
16
+ path_with_format
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,40 @@
1
+ module Sitepress
2
+ module BuildPaths
3
+ # Compiles pages directly from `/pages/blah.html.haml` to `/blah.html`. Handles root `index`
4
+ # pages too, mainly grabbing the root, which doesn't have a name in the node, to the default_name
5
+ # of the node, which is usually `index`.
6
+ class RootPath
7
+ attr_reader :resource
8
+
9
+ extend Forwardable
10
+ def_delegators :resource, :node, :format
11
+
12
+ def initialize(resource)
13
+ @resource = resource
14
+ end
15
+
16
+ def path
17
+ if format.nil?
18
+ path_without_format
19
+ elsif format == node.default_format
20
+ path_with_default_format
21
+ elsif format
22
+ path_with_format
23
+ end
24
+ end
25
+
26
+ protected
27
+ def path_without_format
28
+ node.default_name
29
+ end
30
+
31
+ def path_with_format
32
+ "#{node.default_name}.#{format}"
33
+ end
34
+
35
+ def path_with_default_format
36
+ path_with_format
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,68 @@
1
+ require "pathname"
2
+ require "fileutils"
3
+
4
+ module Sitepress
5
+ # Compile all resources from a Sitepress site into static pages.
6
+ class Compiler
7
+ include FileUtils
8
+
9
+ class ResourceCompiler
10
+ attr_reader :resource
11
+
12
+ def initialize(resource)
13
+ @resource = resource
14
+ end
15
+
16
+ def compilation_path
17
+ File.join(*resource.lineage, compilation_filename)
18
+ end
19
+
20
+ # Compiled assets have a slightly different filename for assets, especially the root node.
21
+ def compilation_filename(path_builder: BuildPaths::DirectoryIndexPath, root_path_builder: BuildPaths::RootPath)
22
+ path_builder = resource.node.root? ? root_path_builder : path_builder
23
+ path_builder.new(resource).path
24
+ end
25
+
26
+ def render(page)
27
+ Renderers::Server.new(resource).render
28
+ end
29
+ end
30
+
31
+ attr_reader :site
32
+
33
+ def initialize(site:, stdout: $stdout)
34
+ @site = site
35
+ @stdout = stdout
36
+ end
37
+
38
+ # Iterates through all pages and writes them to disk
39
+ def compile(target_path:)
40
+ target_path = Pathname.new(target_path)
41
+ mkdir_p target_path
42
+ cache_resources = @site.cache_resources
43
+ @stdout.puts "Compiling #{@site.root_path.expand_path}"
44
+
45
+ begin
46
+ @site.cache_resources = true
47
+ @site.resources.each do |resource|
48
+ compiler = ResourceCompiler.new(resource)
49
+ path = target_path.join(compiler.compilation_path)
50
+ mkdir_p path.dirname
51
+ if resource.renderable?
52
+ @stdout.puts " Rendering #{path}"
53
+ File.open(path.expand_path, "w"){ |f| f.write compiler.render(resource) }
54
+ else
55
+ @stdout.puts " Copying #{path}"
56
+ FileUtils.cp resource.asset.path, path.expand_path
57
+ end
58
+ rescue => e
59
+ @stdout.puts "Error compiling #{resource.inspect}"
60
+ raise
61
+ end
62
+ @stdout.puts "Successful compilation to #{target_path.expand_path}"
63
+ ensure
64
+ @site.cache_resources = cache_resources
65
+ end
66
+ end
67
+ end
68
+ end
@@ -1,18 +1,51 @@
1
+ require "rails/engine"
2
+
1
3
  module Sitepress
2
4
  class Engine < ::Rails::Engine
3
- config.before_configuration do |app|
4
- Sitepress.configure do |config|
5
- app.paths["app/helpers"].push config.site.root_path.join("helpers")
6
- app.paths["app/assets"].push config.site.root_path.join("assets")
7
- app.paths["app/views"].push config.site.root_path
8
- end
5
+ # Set the path for the site configuration file.
6
+ paths.add "config/site.rb", with: [
7
+ File.expand_path("./config/site.rb"), # When Sitepress is launched via `sitepress server`.
8
+ "config/site.rb" # When Sitepress is launched embedded in Rails project.
9
+ ]
10
+
11
+ # Load the `config/site.rb` file so users can configure Sitepress.
12
+ initializer :load_sitepress_file, before: :set_sitepress_paths do
13
+ site_file = paths["config/site.rb"].existent.first
14
+ load site_file if site_file
9
15
  end
10
16
 
11
- initializer "sitepress.configure" do |app|
12
- Sitepress.configure do |config|
13
- config.parent_engine = app
14
- config.cache_resources = app.config.cache_classes
17
+ # Load paths from `Sitepress#site` into rails so it can render views, helpers, etc. properly.
18
+ initializer :set_sitepress_paths, before: :set_autoload_paths do |app|
19
+ app.paths["app/helpers"].push site.helpers_path.expand_path
20
+ app.paths["app/views"].push site.root_path.expand_path
21
+ app.paths["app/views"].push site.pages_path.expand_path
22
+ end
23
+
24
+ # Configure sprockets paths for the site.
25
+ initializer :set_asset_paths, before: :append_assets_path do |app|
26
+ manifest_file = sitepress_configuration.manifest_file_path.expand_path
27
+
28
+ if manifest_file.exist?
29
+ app.paths["app/assets"].push site.assets_path.expand_path
30
+ app.config.assets.precompile << manifest_file.to_s
31
+ else
32
+ Rails.logger.warn "WARNING: Sitepress could not enable Sprockets because it could not find a manifest file at #{manifest_file.to_s.inspect}."
15
33
  end
16
34
  end
35
+
36
+ # Configure Sitepress with Rails settings.
37
+ initializer :configure_sitepress do |app|
38
+ sitepress_configuration.parent_engine = app
39
+ sitepress_configuration.cache_resources = app.config.cache_classes
40
+ end
41
+
42
+ private
43
+ def sitepress_configuration
44
+ Sitepress.configuration
45
+ end
46
+
47
+ def site
48
+ sitepress_configuration.site
49
+ end
17
50
  end
18
51
  end
@@ -1,19 +1,21 @@
1
1
  require "sitepress-core"
2
2
 
3
3
  module Sitepress
4
- # Contains singletons for rails and some configuration data.
5
- Configuration = Struct.new(:site, :routes, :parent_engine)
6
-
7
- # Rescued by ActionController to display page not found error.
8
- PageNotFoundError = Class.new(StandardError)
9
-
4
+ autoload :Compiler, "sitepress/compiler"
10
5
  autoload :RailsConfiguration, "sitepress/rails_configuration"
11
6
  autoload :RouteConstraint, "sitepress/route_constraint"
12
- module Extensions
13
- autoload :RailsRequestPaths, "sitepress/extensions/rails_request_paths"
14
- autoload :PartialsRemover, "sitepress/extensions/partials_remover"
15
- autoload :IndexRequestPath, "sitepress/extensions/index_request_path"
7
+ module Renderers
8
+ autoload :Controller, "sitepress/renderers/controller"
9
+ autoload :Server, "sitepress/renderers/server"
16
10
  end
11
+ module BuildPaths
12
+ autoload :RootPath, "sitepress/build_paths/root_path"
13
+ autoload :IndexPath, "sitepress/build_paths/index_path"
14
+ autoload :DirectoryIndexPath, "sitepress/build_paths/directory_index_path"
15
+ end
16
+
17
+ # Rescued by ActionController to display page not found error.
18
+ PageNotFoundError = Class.new(StandardError)
17
19
 
18
20
  # Make site available via Sitepress.site from Rails app.
19
21
  def self.site
@@ -13,7 +13,6 @@ module Sitepress
13
13
  extend Forwardable
14
14
  def_delegators :site, :cache_resources, :cache_resources=, :cache_resources?
15
15
 
16
- # Set defaults.
17
16
  def initialize
18
17
  self.routes = true
19
18
  end
@@ -23,10 +22,12 @@ module Sitepress
23
22
  end
24
23
 
25
24
  def site
26
- @site ||= Site.new(root_path: default_root).tap do |site|
27
- site.resources_pipeline << Extensions::PartialsRemover.new
28
- site.resources_pipeline << Extensions::RailsRequestPaths.new
29
- end
25
+ @site ||= Site.new(root_path: default_root)
26
+ end
27
+
28
+ # Location of Sprockets manifest file
29
+ def manifest_file_path
30
+ site.assets_path.join("config/manifest.js")
30
31
  end
31
32
 
32
33
  private
@@ -0,0 +1,51 @@
1
+ module Sitepress
2
+ module Renderers
3
+ class Controller
4
+ attr_reader :controller, :page
5
+
6
+ def initialize(page, controller = SiteController)
7
+ @controller = controller
8
+ @page = page
9
+ end
10
+
11
+ def render
12
+ renderer.render inline: page.body,
13
+ type: page.asset.template_extensions.last,
14
+ layout: resolve_layout,
15
+ content_type: page.mime_type.to_s
16
+ end
17
+
18
+ private
19
+ def layout
20
+ controller._layout
21
+ end
22
+
23
+ def has_layout_conditions?
24
+ controller._layout_conditions?
25
+ end
26
+
27
+ def layout_conditions
28
+ controller._layout_conditions
29
+ end
30
+
31
+ def renderer
32
+ controller.renderer.new("PATH_INFO" => page.request_path)
33
+ end
34
+
35
+ def resolve_layout
36
+ return page.data.fetch("layout") if page.data.key? "layout"
37
+ return layout unless has_layout_conditions?
38
+
39
+ clause, formats = layout_conditions.first
40
+ format = page.format.to_s
41
+
42
+ case clause
43
+ when :only
44
+ layout if formats.include? format
45
+ when :except
46
+ layout if formats.exclude? format
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,25 @@
1
+ module Sitepress
2
+ module Renderers
3
+ class Server
4
+ attr_reader :rails_app, :page
5
+
6
+ def initialize(page, rails_app = Rails.application)
7
+ @rails_app = rails_app
8
+ @page = page
9
+ end
10
+
11
+ def render
12
+ code, headers, response = rails_app.routes.call env
13
+ response.body
14
+ end
15
+
16
+ def env
17
+ {
18
+ "PATH_INFO"=> page.request_path,
19
+ "REQUEST_METHOD"=>"GET",
20
+ "rack.input" => "GET"
21
+ }
22
+ end
23
+ end
24
+ end
25
+ end