ecrire 0.26.2 → 0.26.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -1
- data/lib/ecrire/app/controllers/application_controller.rb +62 -7
- data/lib/ecrire/app/controllers/ecrire/theme_controller.rb +14 -15
- data/lib/ecrire/app/controllers/static_controller.rb +6 -1
- data/lib/ecrire/app/helpers/admin/posts_helper.rb +0 -1
- data/lib/ecrire/app/helpers/application_helper.rb +69 -19
- data/lib/ecrire/app/helpers/pagination_helper.rb +26 -0
- data/lib/ecrire/app/models/post.rb +77 -8
- data/lib/ecrire/app/views/admin/posts/titles/_title.html.erb +1 -1
- data/lib/ecrire/application.rb +26 -0
- data/lib/ecrire/config/environment.rb +3 -1
- data/lib/ecrire/onboarding/views/layouts/application.html.erb +4 -3
- data/lib/ecrire/theme/engine.rb +77 -17
- data/lib/ecrire/theme/template/assets/stylesheets/browser.css.scss +1 -0
- data/lib/ecrire/theme/template/assets/stylesheets/mobile.css.scss +1 -0
- data/lib/ecrire/theme/template/assets/stylesheets/tablet.css.scss +1 -0
- data/lib/ecrire/theme/template/controllers/posts_controller.rb +8 -1
- data/lib/ecrire/theme/template/views/layouts/application.html.erb +6 -12
- data/lib/ecrire/version.rb +1 -1
- data/lib/ecrire.rb +4 -0
- data/test/editor/models/post_test.rb +12 -0
- data/test/theme/helpers/application_helper_test.rb +31 -0
- metadata +5 -18
- data/lib/ecrire/app/controllers/admin/partials_controller.rb +0 -43
- data/lib/ecrire/app/controllers/admin/properties_controller.rb +0 -35
- data/lib/ecrire/app/controllers/images_controller.rb +0 -2
- data/lib/ecrire/app/controllers/partials_controller.rb +0 -8
- data/lib/ecrire/app/helpers/admin/labels_helper.rb +0 -26
- data/lib/ecrire/app/helpers/open_graph_helper.rb +0 -45
- data/lib/ecrire/app/helpers/posts_helper.rb +0 -13
- data/lib/ecrire/app/models/admin/partial.rb +0 -4
- data/lib/ecrire/app/models/concerns/.keep +0 -0
- data/lib/ecrire/app/models/partial.rb +0 -3
- data/lib/ecrire/app/models/property/image.rb +0 -30
- data/lib/ecrire/app/models/property/label.rb +0 -28
- data/lib/ecrire/theme/template/assets/javascripts/theme.js.coffee +0 -1
- data/lib/ecrire/theme/template/secrets.yml +0 -11
- /data/lib/ecrire/app/assets/javascripts/{application.js → ecrire.js} +0 -0
- /data/lib/ecrire/app/assets/stylesheets/{application.css.scss → ecrire.css.scss} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 42ebfbcd7b234a8ed0eced636045769471049b42
|
4
|
+
data.tar.gz: fcf2461eb398ad52f848e08f4be8d2a8975ef354
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5fc4670039672091e34e0055e400063b5715c95f39375efc770f528d32d09435aff6cccc141be01e901d99cd9ba40aa05c4aebbc4ba9c76e04048eceace9c07d
|
7
|
+
data.tar.gz: 633ca19d3ad1b9d88a3da8f8419c737cd89b0750ea423b19a92de5593f98c0ce48668b523db7b2ccf04d3afc609e33411caa3b9eb47ff83bd3ec407e42d62d4f
|
data/.gitignore
CHANGED
@@ -1,17 +1,73 @@
|
|
1
|
+
##
|
2
|
+
# Base controller for every controller in Ecrire (Theme & Admin)
|
3
|
+
# Ecrire::ThemeController inherits from this class so there are no reason why
|
4
|
+
# you should inherit from this class.
|
5
|
+
#
|
6
|
+
# The controller handles user authentication, and CSRF protection.
|
7
|
+
#
|
8
|
+
# It also provides a +url+ method to build complex URL using a
|
9
|
+
# very light syntax.
|
10
|
+
#
|
1
11
|
class ApplicationController < ::ActionController::Base
|
2
12
|
protect_from_forgery with: :exception
|
3
13
|
|
4
14
|
helper_method :current_user, :signed_in?
|
5
15
|
helper_method :warden, :post_path, :url
|
6
16
|
|
17
|
+
##
|
18
|
+
# Return current signed +user+ or nil, if the user is not
|
19
|
+
# signed in
|
7
20
|
def current_user
|
8
21
|
warden.user
|
9
22
|
end
|
10
23
|
|
24
|
+
##
|
25
|
+
# Returns +true+ if the user is signed in
|
11
26
|
def signed_in?
|
12
27
|
!warden.user.nil?
|
13
28
|
end
|
14
29
|
|
30
|
+
|
31
|
+
##
|
32
|
+
# Returns a URL based on the path and options provided.
|
33
|
+
# It does not try to validate the URL, it only generates it and assume
|
34
|
+
# it's a valid URL.
|
35
|
+
#
|
36
|
+
# +path+: The relative path of the URL you want to build.
|
37
|
+
#
|
38
|
+
# +options+: Hash containing options for rendering the url.
|
39
|
+
#
|
40
|
+
#
|
41
|
+
# The +path+ and +options+ are linked together via a mapping construct
|
42
|
+
# that you can use to map records to part of the URL.
|
43
|
+
#
|
44
|
+
# To map records to the +path+, you need to specify the record & the method you want to use inside the path.
|
45
|
+
#
|
46
|
+
# url('/admin/posts/:posts.id', post: @post)
|
47
|
+
# -> '/admin/posts/32'
|
48
|
+
#
|
49
|
+
# The method looks for every occurence of ":[key].[method]" and will look in +options+ for that key and call the given method on that key.
|
50
|
+
#
|
51
|
+
# This means the object can be anything as long as it handles the method.
|
52
|
+
#
|
53
|
+
# Here are a other examples:
|
54
|
+
#
|
55
|
+
# url('/users/:user.id/tags/:tag.id/', user: @user, tag: @tag)
|
56
|
+
# -> '/users/12/tags/12'
|
57
|
+
#
|
58
|
+
# url('/users')
|
59
|
+
# -> '/users'
|
60
|
+
#
|
61
|
+
# The +options+ also looks for the +absolute_path+ key. If it's set to +true+, the
|
62
|
+
# method will return an absolute path.
|
63
|
+
#
|
64
|
+
# url('/users/:user.id/tags/:tag.id/', user: @user, tag: @tag, absolute_path: true)
|
65
|
+
# -> 'http://localhost:3000/users/12/tags/12'
|
66
|
+
#
|
67
|
+
# url('/users', absolute_path: true)
|
68
|
+
# -> 'http://localhost:3000/users'
|
69
|
+
#
|
70
|
+
|
15
71
|
def url(path, options = {})
|
16
72
|
records = options.with_indifferent_access
|
17
73
|
regex = /(:([a-z]+)\.([a-z]+))/i
|
@@ -19,19 +75,18 @@ class ApplicationController < ::ActionController::Base
|
|
19
75
|
records[$2].send($3)
|
20
76
|
end
|
21
77
|
|
22
|
-
if options.delete(:
|
23
|
-
options[:path]
|
24
|
-
options[:host]
|
25
|
-
options[:protocol]
|
26
|
-
options[:port]
|
78
|
+
if options.delete(:absolute_path)
|
79
|
+
options[:path] = path
|
80
|
+
options[:host] ||= request.host
|
81
|
+
options[:protocol] ||= request.protocol
|
82
|
+
options[:port] ||= request.port
|
27
83
|
ActionDispatch::Http::URL.full_url_for(options)
|
28
84
|
else
|
29
85
|
path
|
30
86
|
end
|
31
87
|
end
|
32
88
|
|
33
|
-
|
34
|
-
protected
|
89
|
+
private
|
35
90
|
|
36
91
|
def authenticate!
|
37
92
|
warden.authenticate!
|
@@ -1,4 +1,16 @@
|
|
1
1
|
module Ecrire
|
2
|
+
##
|
3
|
+
# The class any controller in a theme needs to inherit from
|
4
|
+
#
|
5
|
+
# +ThemeController+ provides boilerplate code so the blog handles a few cases
|
6
|
+
# for you.
|
7
|
+
#
|
8
|
+
# Ecrire will try to redirect to the homepage when it meets selected exceptions
|
9
|
+
# Currently, the following 3 exceptions are handled:
|
10
|
+
# - ActiveRecord::RecordNotFound
|
11
|
+
# - ActionController::RoutingError
|
12
|
+
# - ActionView::ActionViewError
|
13
|
+
#
|
2
14
|
class ThemeController < ::ApplicationController
|
3
15
|
|
4
16
|
unless Rails.env.development?
|
@@ -7,23 +19,10 @@ module Ecrire
|
|
7
19
|
rescue_from ActionView::ActionViewError, with: :redirect_home
|
8
20
|
end
|
9
21
|
|
10
|
-
before_action :pagination, only: :index
|
11
|
-
protect_from_forgery except: :index
|
12
|
-
|
13
|
-
def index
|
14
|
-
respond_to do |format|
|
15
|
-
format.html
|
16
|
-
format.rss
|
17
|
-
format.json do
|
18
|
-
headers['Access-Control-Allow-Origin'] = '*'
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
22
|
|
23
|
-
|
24
|
-
end
|
23
|
+
before_action :pagination, only: :index
|
25
24
|
|
26
|
-
|
25
|
+
private
|
27
26
|
|
28
27
|
def pagination
|
29
28
|
params[:per] ||= 10
|
@@ -1,13 +1,35 @@
|
|
1
|
+
##
|
2
|
+
# +ApplicationHelper+ provides functions to help build a theme's layout
|
3
|
+
#
|
1
4
|
module ApplicationHelper
|
5
|
+
|
6
|
+
##
|
7
|
+
# Render the admin navigation bar if a user is signed in.
|
8
|
+
#
|
9
|
+
# You don't have to check if the user is signed in before using this method
|
10
|
+
# Ecrire will check this automatically
|
11
|
+
#
|
2
12
|
def admin_navigation
|
3
13
|
return unless signed_in?
|
4
14
|
render 'sessions/navigation'
|
5
15
|
end
|
6
16
|
|
17
|
+
##
|
18
|
+
# Render <title> tag
|
19
|
+
#
|
20
|
+
# The content of the title tag can be one of three things.
|
21
|
+
# In priority of order:
|
22
|
+
# 1. The value of content_for(:title) if it's set,
|
23
|
+
# 2. The title of the variable @post, if it's set,
|
24
|
+
# 3. The +title+ passed
|
25
|
+
#
|
26
|
+
# If you need more information about content_for and how to use it, please read:
|
27
|
+
# http://ecrire.io/posts/configure-layout-element-with-content_for
|
28
|
+
#
|
7
29
|
def title_tag(title = 'Ecrire')
|
8
30
|
content_tag :title do
|
9
|
-
if
|
10
|
-
|
31
|
+
if content_for?(:title)
|
32
|
+
content_for(:title)
|
11
33
|
elsif !@post.nil?
|
12
34
|
@post.title
|
13
35
|
else
|
@@ -16,28 +38,56 @@ module ApplicationHelper
|
|
16
38
|
end
|
17
39
|
end
|
18
40
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
41
|
+
##
|
42
|
+
# Render a RSS auto-discovery tag
|
43
|
+
#
|
44
|
+
# You can pass another relative path if you want.
|
45
|
+
# Ecrire will render an absolute path using the +relative_path+
|
46
|
+
#
|
47
|
+
def rss_tag(relative_path = '/feed')
|
48
|
+
content_tag :link, nil, rel: 'alternate', type: 'application/rss+xml', title: 'RSS', href: url(relative_path, absolute_path: true)
|
25
49
|
end
|
26
50
|
|
27
|
-
def description_meta_tag
|
28
|
-
if Rails.application.secrets.fetch(:meta, {}).has_key?(:description)
|
29
|
-
content_tag :meta, nil, name: 'description', content: Rails.application.secrets[:meta][:description]
|
30
|
-
end
|
31
|
-
end
|
32
51
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
52
|
+
##
|
53
|
+
# Render the favicon tag
|
54
|
+
#
|
55
|
+
# Will generate the asset url given with the +name+ of your favicon.
|
56
|
+
#
|
57
|
+
def favicon_tag(name = 'favicon.ico')
|
58
|
+
content_tag :link, nil, rel: %w(shortcut icon), href: asset_url(name)
|
39
59
|
end
|
40
60
|
|
61
|
+
##
|
62
|
+
# Render the <main> tag
|
63
|
+
#
|
64
|
+
# The +html_options+ is a hash that will map to key/value for the tag.
|
65
|
+
# Unless you know what you are doing, you should not specify an id in +html_options+.
|
66
|
+
# Ecrire will generate one using the controller and action for the given request.
|
67
|
+
#
|
68
|
+
# You can also provide any key/value that you wish to see rendered in the main tag.
|
69
|
+
#
|
70
|
+
# Example with posts#index (/posts):
|
71
|
+
#
|
72
|
+
# <%= main_tag contentEditable: true do %>
|
73
|
+
# Hello world!
|
74
|
+
# <% end %>
|
75
|
+
#
|
76
|
+
# <main contentEditable=true id='PostsIndex'>
|
77
|
+
# Hello world!
|
78
|
+
# </main>
|
79
|
+
#
|
80
|
+
# Another example with posts#index (/posts):
|
81
|
+
#
|
82
|
+
# <%= main_tag class: 'content' do %>
|
83
|
+
# Hello World!
|
84
|
+
# <% end %>
|
85
|
+
#
|
86
|
+
# <main class='content' id='PostsIndex'>
|
87
|
+
# Hello World!
|
88
|
+
# </main>
|
89
|
+
#
|
90
|
+
#
|
41
91
|
def main_tag(html_options = {}, &block)
|
42
92
|
html_options[:id] ||= [controller_name, action_name].map(&:capitalize).join
|
43
93
|
html_options[:class] = [html_options[:class]].compact.flatten
|
@@ -0,0 +1,26 @@
|
|
1
|
+
##
|
2
|
+
# This module overloads the +paginate+ method defined
|
3
|
+
# by Kaminari to force kaminari to use the routes provided by the theme.
|
4
|
+
#
|
5
|
+
# This might not be needed when Kaminari reaches 1.0 per https://github.com/amatsuda/kaminari/pull/636
|
6
|
+
#
|
7
|
+
module PaginationHelper
|
8
|
+
|
9
|
+
##
|
10
|
+
# Returns pagination for the given scope(record).
|
11
|
+
#
|
12
|
+
# The argument list is the same as the one declared by kaminari
|
13
|
+
# to keep the expected behavior when calling ```super```
|
14
|
+
#
|
15
|
+
# Example:
|
16
|
+
#
|
17
|
+
# ``` erb
|
18
|
+
# <%= paginate(@posts) %>
|
19
|
+
# ```
|
20
|
+
#
|
21
|
+
def paginate(scope, options = {}, &block)
|
22
|
+
_with_routes Ecrire::Theme::Engine.routes do
|
23
|
+
super
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -1,11 +1,28 @@
|
|
1
1
|
require 'nokogiri'
|
2
2
|
|
3
|
+
##
|
4
|
+
# Posts written by users stored in database
|
5
|
+
#
|
6
|
+
# == Available scopes
|
7
|
+
#
|
8
|
+
# Scopes are builtin methods to facilitate retrieving posts
|
9
|
+
# from the database. Scopes can also be chained to narrow your query
|
10
|
+
# even more.
|
11
|
+
#
|
12
|
+
# +published+: Return posts that are published
|
13
|
+
#
|
14
|
+
# +drafted+: Return posts that are NOT published
|
15
|
+
#
|
16
|
+
# +search_by_title+: Return all post that have a title that match
|
17
|
+
# the key you provide
|
18
|
+
#
|
19
|
+
#
|
3
20
|
class Post < ActiveRecord::Base
|
4
21
|
has_one :header, class_name: Image
|
5
22
|
has_many :titles, -> { order "titles.created_at DESC" }
|
6
23
|
|
7
|
-
|
8
|
-
|
24
|
+
scope :published, lambda { status("published") }
|
25
|
+
scope :drafted, lambda { status("drafted") }
|
9
26
|
scope :status, lambda {|status|
|
10
27
|
if status.eql?("published")
|
11
28
|
where "posts.published_at IS NOT NULL"
|
@@ -14,8 +31,11 @@ class Post < ActiveRecord::Base
|
|
14
31
|
end
|
15
32
|
}
|
16
33
|
|
17
|
-
scope :
|
18
|
-
|
34
|
+
scope :search_by_title, lambda {|title|
|
35
|
+
ids = Title.search_by_name(title).map(&:post_id).compact
|
36
|
+
Post.includes(:titles).where('posts.id in (?)', ids)
|
37
|
+
}
|
38
|
+
|
19
39
|
scope :without, lambda { |post| where("posts.id != ?", post.id) }
|
20
40
|
|
21
41
|
validates :titles, length: {minimum: 1}
|
@@ -24,6 +44,7 @@ class Post < ActiveRecord::Base
|
|
24
44
|
|
25
45
|
attr_writer :tags
|
26
46
|
|
47
|
+
#:nodoc:
|
27
48
|
def title=(new_title)
|
28
49
|
if self.published?
|
29
50
|
self.titles.new(name: new_title)
|
@@ -34,54 +55,102 @@ class Post < ActiveRecord::Base
|
|
34
55
|
end
|
35
56
|
end
|
36
57
|
|
58
|
+
##
|
59
|
+
# Return the current title for this post
|
60
|
+
#
|
37
61
|
def title
|
38
62
|
(self.titles.first || self.titles.new).name
|
39
63
|
end
|
40
64
|
|
65
|
+
##
|
66
|
+
# Return the slug link to the current title
|
67
|
+
#
|
68
|
+
def slug
|
69
|
+
self.titles.first.slug
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
# Returns the year this post was published
|
74
|
+
#
|
41
75
|
def year
|
42
76
|
published_at.year
|
43
77
|
end
|
44
78
|
|
79
|
+
##
|
80
|
+
# Returns the month this post was published
|
81
|
+
#
|
45
82
|
def month
|
46
83
|
published_at.month
|
47
84
|
end
|
48
85
|
|
49
|
-
|
50
|
-
self.titles.first.slug
|
51
|
-
end
|
52
|
-
|
86
|
+
#:nodoc:
|
53
87
|
def status=(new_status)
|
54
88
|
if new_status.eql? "publish"
|
55
89
|
publish!
|
56
90
|
end
|
57
91
|
end
|
58
92
|
|
93
|
+
##
|
94
|
+
# Publish this post if it is not yet published
|
95
|
+
#
|
96
|
+
# Update the database with the publish date
|
97
|
+
#
|
59
98
|
def publish!
|
60
99
|
return unless published_at.nil?
|
61
100
|
self.published_at = DateTime.now
|
62
101
|
save!
|
63
102
|
end
|
64
103
|
|
104
|
+
##
|
105
|
+
# Returns whether this post is published or not
|
106
|
+
#
|
65
107
|
def published?
|
66
108
|
!draft?
|
67
109
|
end
|
68
110
|
|
111
|
+
##
|
112
|
+
# The opposite of +published?+
|
113
|
+
#
|
69
114
|
def draft?
|
70
115
|
published_at.nil?
|
71
116
|
end
|
72
117
|
|
118
|
+
##
|
119
|
+
# Returns the content of this post. Depending on the current status
|
120
|
+
# of this post, it can be one of three things:
|
121
|
+
#
|
122
|
+
# - Compiled content;
|
123
|
+
# - Markdown content;
|
124
|
+
# - Empty string.
|
125
|
+
#
|
126
|
+
# This method should be used when trying to render the body of a post
|
127
|
+
# to a page in HTML.
|
128
|
+
#
|
73
129
|
def content
|
74
130
|
(self.compiled_content || super || '').html_safe
|
75
131
|
end
|
76
132
|
|
133
|
+
##
|
134
|
+
# Returns the compiled excerpt for this post.
|
135
|
+
# The excerpt is based on content but only returns text.
|
136
|
+
#
|
137
|
+
# The excerpt is parsed from the content and it also
|
138
|
+
# filters out images and header.
|
139
|
+
#
|
77
140
|
def excerpt
|
78
141
|
(self.compiled_excerpt || "").html_safe
|
79
142
|
end
|
80
143
|
|
144
|
+
##
|
145
|
+
# Returns true if an image header was set for this post
|
146
|
+
#
|
81
147
|
def header?
|
82
148
|
!self.header.nil? && !self.header.url.blank?
|
83
149
|
end
|
84
150
|
|
151
|
+
##
|
152
|
+
# Returns the list of Tags link set for this post
|
153
|
+
#
|
85
154
|
def tags
|
86
155
|
@tags ||= Tag.where("tags.id in (?)", super || [])
|
87
156
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<% post = Post.new(titles: [title], published_at: title.post.published_at) %>
|
2
2
|
<li>
|
3
3
|
<%= content_tag :p, title.name %>
|
4
|
-
<%= link_to url(Ecrire::Theme::Engine.post_path, post: post,
|
4
|
+
<%= link_to url(Ecrire::Theme::Engine.post_path, post: post, absolute_path: true), url(Ecrire::Theme::Engine.post_path, post: post, absolute_path: true) %>
|
5
5
|
</li>
|
data/lib/ecrire/application.rb
CHANGED
@@ -6,6 +6,21 @@ require 'observejs'
|
|
6
6
|
require 'pg_search'
|
7
7
|
|
8
8
|
module Ecrire
|
9
|
+
##
|
10
|
+
# Ecrire::Application is the entry point when running
|
11
|
+
# a blog.
|
12
|
+
#
|
13
|
+
# The big difference between this application and a normal Rails
|
14
|
+
# application is that Ecrire will look for +secrets.yml+ in the
|
15
|
+
# current working directory.
|
16
|
+
#
|
17
|
+
# If it doesn't find one, it will load the Onboarding process
|
18
|
+
# so the user can configure the database and the first user.
|
19
|
+
#
|
20
|
+
# If the application finds +secrets.yml+, it will load the Theme which is located
|
21
|
+
# in the current working directory.
|
22
|
+
#
|
23
|
+
#
|
9
24
|
class Application < Rails::Application
|
10
25
|
require 'ecrire/config/environment'
|
11
26
|
|
@@ -23,6 +38,13 @@ module Ecrire
|
|
23
38
|
require 'ecrire/onboarding/engine'
|
24
39
|
end
|
25
40
|
|
41
|
+
##
|
42
|
+
# Return paths based off Rails default plus some customization.
|
43
|
+
#
|
44
|
+
# These paths are Ecrire's, not the users's theme.
|
45
|
+
#
|
46
|
+
# For the user's paths, look at Ecrire::Theme::Engine.paths
|
47
|
+
#
|
26
48
|
def paths
|
27
49
|
@paths ||= begin
|
28
50
|
paths = super
|
@@ -32,6 +54,10 @@ module Ecrire
|
|
32
54
|
end
|
33
55
|
end
|
34
56
|
|
57
|
+
##
|
58
|
+
# Returns true if Ecrire::Onboarding::Engine is loaded
|
59
|
+
# in the application runtime
|
60
|
+
#
|
35
61
|
def self.onboarding?
|
36
62
|
defined?(Ecrire::Onboarding::Engine)
|
37
63
|
end
|
@@ -22,7 +22,9 @@ Ecrire::Application.configure do
|
|
22
22
|
lambda do |filename, path|
|
23
23
|
path =~ /assets/ && !%w(.js .css).include?(File.extname(filename))
|
24
24
|
end,
|
25
|
-
/^(admin|
|
25
|
+
/^(admin|ecrire)\.(css|js)$/,
|
26
|
+
/^(application).(js|coffee)$/,
|
27
|
+
/^(browser|tablet|mobile).(css|scss)$/
|
26
28
|
]
|
27
29
|
|
28
30
|
Warden::Manager.serialize_into_session do |user|
|
@@ -3,12 +3,13 @@
|
|
3
3
|
|
4
4
|
<head>
|
5
5
|
<%= title_tag 'Before you start blogging...' %>
|
6
|
-
<%= stylesheet_link_tag "
|
7
|
-
<%= javascript_include_tag "
|
6
|
+
<%= stylesheet_link_tag "ecrire", media: "all", "data-turbolinks-track" => true %>
|
7
|
+
<%= javascript_include_tag "ecrire", "base", "data-turbolinks-track" => true %>
|
8
8
|
|
9
9
|
<%= stylesheet_link_tag "theme", media: "all", "data-turbolinks-track" => true %>
|
10
10
|
<%= javascript_include_tag "theme", "base", "data-turbolinks-track" => true %>
|
11
|
-
<%=
|
11
|
+
<%= csrf_meta_tags %>
|
12
|
+
<%= favicon_tag %>
|
12
13
|
</head>
|
13
14
|
|
14
15
|
<body>
|
data/lib/ecrire/theme/engine.rb
CHANGED
@@ -1,25 +1,47 @@
|
|
1
1
|
module Ecrire
|
2
|
+
##
|
3
|
+
# Theme module links the user's theme with
|
4
|
+
# Ecrire::Application. It uses Rails::Engine to hook
|
5
|
+
# itself up and split the codebase between the Gem and the user's
|
6
|
+
# Theme.
|
7
|
+
#
|
2
8
|
module Theme
|
3
|
-
class Engine < Rails::Engine
|
4
|
-
attr_accessor :post_path
|
5
|
-
|
6
|
-
initializer 'ecrire.logs', before: :initialize_logger do |app|
|
7
|
-
unless Rails.env.test?
|
8
|
-
app.paths.add "log", with: "log/#{Rails.env}.log"
|
9
|
-
end
|
10
|
-
end
|
11
9
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
##
|
11
|
+
# Engine is the foundation of Rails. It can be used
|
12
|
+
# to encapsulate part of the application and this is
|
13
|
+
# exactly what it does here.
|
14
|
+
#
|
15
|
+
# Ecrire::Theme::Engine is the block that hooks into Ecrire::Application
|
16
|
+
# to provide Theme support.
|
17
|
+
#
|
18
|
+
# This class is the only element that the Gem includes at runtime.
|
19
|
+
#
|
20
|
+
# Everything else is defined in the user's theme folder.
|
21
|
+
#
|
22
|
+
# This engine is the reason why it's possible to have
|
23
|
+
# Ecrire as a gem and theme as user's folder.
|
24
|
+
#
|
25
|
+
class Engine < Rails::Engine
|
16
26
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
27
|
+
##
|
28
|
+
# +post_path+ needs to be defined so Ecrire can link from the admin
|
29
|
+
# to a post. This is also needed when listing all the titles a post has
|
30
|
+
# and the URL they represent.
|
31
|
+
#
|
32
|
+
attr_accessor :post_path
|
22
33
|
|
34
|
+
##
|
35
|
+
# Return paths for a theme. The paths
|
36
|
+
# follow the structure of the default theme.
|
37
|
+
#
|
38
|
+
# It creates a new Rails::Paths because
|
39
|
+
# it's highly customized and it was less readable to
|
40
|
+
# disable and changes every paths.
|
41
|
+
#
|
42
|
+
# This could be modified in the user's theme.
|
43
|
+
#
|
44
|
+
#
|
23
45
|
def paths
|
24
46
|
@paths ||= begin
|
25
47
|
paths = Rails::Paths::Root.new(root_path)
|
@@ -42,10 +64,30 @@ module Ecrire
|
|
42
64
|
end
|
43
65
|
end
|
44
66
|
|
67
|
+
##
|
68
|
+
# Disables migration for now.
|
69
|
+
# Any Rails::Engine instance can support migrations
|
70
|
+
# which means that Theme could have their own
|
71
|
+
# models.
|
72
|
+
#
|
73
|
+
# It's likely that at some point this behavior is resumed but
|
74
|
+
# I want to make sure that I understand the implication before
|
75
|
+
# turning this back on.
|
76
|
+
#
|
77
|
+
# For example, I would like to make sure that the Admin is shelled from
|
78
|
+
# those future migrations.
|
45
79
|
def has_migrations?
|
46
80
|
false
|
47
81
|
end
|
48
82
|
|
83
|
+
##
|
84
|
+
# Return the root_path for the current theme
|
85
|
+
#
|
86
|
+
# The method starts at the current working directory and moves from parent
|
87
|
+
# to parent until it either finds +config.ru+ or it reaches the root.
|
88
|
+
#
|
89
|
+
# Raise an error if it reaches the root and can't find +config.ru+.
|
90
|
+
#
|
49
91
|
def root_path(file = 'config.ru')
|
50
92
|
begin
|
51
93
|
pathname = Pathname.pwd
|
@@ -62,6 +104,24 @@ module Ecrire
|
|
62
104
|
end
|
63
105
|
end
|
64
106
|
|
107
|
+
initializer 'ecrire.logs', before: :initialize_logger do |app|
|
108
|
+
unless Rails.env.test?
|
109
|
+
app.paths.add "log", with: "log/#{Rails.env}.log"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
initializer 'ecrire.load_paths', before: :bootstrap_hook do |app|
|
114
|
+
ActiveSupport::Dependencies.autoload_paths.unshift(*self.paths.autoload_paths)
|
115
|
+
ActiveSupport::Dependencies.autoload_once_paths.unshift(*self.paths.autoload_once)
|
116
|
+
end
|
117
|
+
|
118
|
+
initializer 'ecrire.append_paths', before: :set_autoload_paths do |app|
|
119
|
+
app.config.eager_load_paths.unshift *paths.eager_load
|
120
|
+
app.config.autoload_once_paths.unshift *paths.autoload_once
|
121
|
+
app.config.autoload_paths.unshift *paths.autoload_paths
|
122
|
+
end
|
123
|
+
|
124
|
+
|
65
125
|
end
|
66
126
|
end
|
67
127
|
end
|
@@ -8,7 +8,14 @@ class PostsController < Ecrire::ThemeController
|
|
8
8
|
@posts = @posts.where.not(id: @latest.id)
|
9
9
|
end
|
10
10
|
@tags = Tag.all
|
11
|
-
|
11
|
+
|
12
|
+
respond_to do |format|
|
13
|
+
format.html
|
14
|
+
format.rss
|
15
|
+
format.json do
|
16
|
+
headers['Access-Control-Allow-Origin'] = '*'
|
17
|
+
end
|
18
|
+
end
|
12
19
|
end
|
13
20
|
|
14
21
|
def show
|
@@ -3,14 +3,17 @@
|
|
3
3
|
|
4
4
|
<head>
|
5
5
|
<%= title_tag %>
|
6
|
-
|
7
|
-
<%= javascript_include_tag "
|
6
|
+
|
7
|
+
<%= javascript_include_tag "ecrire", "application", "data-turbolinks-track" => true %>
|
8
8
|
|
9
9
|
<%= stylesheet_link_tag "browser", media: "(min-width: 1025px)", "data-turbolinks-track" => true %>
|
10
10
|
<%= stylesheet_link_tag "tablet", media: "(min-width: 641px) and (max-width: 1024px)", "data-turbolinks-track" => true %>
|
11
11
|
<%= stylesheet_link_tag "mobile", media: "(max-width: 640px)", "data-turbolinks-track" => true %>
|
12
12
|
|
13
|
-
<%=
|
13
|
+
<%= csrf_meta_tags %>
|
14
|
+
|
15
|
+
<%= favicon_tag %>
|
16
|
+
<%= rss_tag %>
|
14
17
|
</head>
|
15
18
|
|
16
19
|
<body>
|
@@ -31,21 +34,12 @@
|
|
31
34
|
</ol>
|
32
35
|
</nav>
|
33
36
|
|
34
|
-
|
35
|
-
<% if content_for?(:header) %>
|
36
|
-
<div class='content'>
|
37
|
-
<%= content_for :header %>
|
38
|
-
</div>
|
39
|
-
<% end %>
|
40
|
-
|
41
37
|
</header>
|
42
38
|
|
43
39
|
<article>
|
44
40
|
<%= yield %>
|
45
41
|
</article>
|
46
42
|
|
47
|
-
<footer>
|
48
|
-
</footer>
|
49
43
|
<% end %>
|
50
44
|
</body>
|
51
45
|
</html>
|
data/lib/ecrire/version.rb
CHANGED
data/lib/ecrire.rb
CHANGED
@@ -3,6 +3,10 @@ module Ecrire
|
|
3
3
|
autoload :Application, 'ecrire/application'
|
4
4
|
autoload :Markdown, 'ecrire/markdown'
|
5
5
|
|
6
|
+
##
|
7
|
+
# Returns true if Ecrire could find
|
8
|
+
# a Gemfile in the current working directory
|
9
|
+
#
|
6
10
|
def self.bundle?
|
7
11
|
ENV['BUNDLE_GEMFILE'] ||= Dir.pwd + '/Gemfile'
|
8
12
|
File.exists?(ENV['BUNDLE_GEMFILE'])
|
@@ -22,6 +22,18 @@ class PostTest < ActiveSupport::TestCase
|
|
22
22
|
assert post.read_attribute(:tags).include?(tag.id)
|
23
23
|
end
|
24
24
|
|
25
|
+
test 'find post by title' do
|
26
|
+
keyword = 'title'
|
27
|
+
|
28
|
+
posts = Title.search_by_name(keyword).map(&:post).uniq
|
29
|
+
|
30
|
+
assert posts.count == Post.search_by_title(keyword).count
|
31
|
+
|
32
|
+
Post.search_by_title(keyword).each do |post|
|
33
|
+
assert posts.include?(post)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
25
37
|
test "fetch published post" do
|
26
38
|
@posts = Post.status("published")
|
27
39
|
assert_equal @posts.count, Post.published.count
|
@@ -25,6 +25,37 @@ class ApplicationHelperTest < ActionView::TestCase
|
|
25
25
|
assert_select node(html), "#TestIndex"
|
26
26
|
end
|
27
27
|
|
28
|
+
test 'title_tag should always render the tag' do
|
29
|
+
html = title_tag
|
30
|
+
assert_select node(html), 'title', 1
|
31
|
+
end
|
32
|
+
|
33
|
+
test 'title_tag content should always prioritize content_for' do
|
34
|
+
@post = Post.first
|
35
|
+
title = "A new title"
|
36
|
+
content_for :title, title
|
37
|
+
html = title_tag
|
38
|
+
|
39
|
+
assert_select node(html), 'title', title
|
40
|
+
end
|
41
|
+
|
42
|
+
test 'title_tag should render the post if content_for(:title) is not set' do
|
43
|
+
@post = Post.first
|
44
|
+
html = title_tag('yada')
|
45
|
+
|
46
|
+
assert_select node(html), 'title', @post.title
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
test 'title_tag should render the argument passed if nothing else is set' do
|
51
|
+
html = title_tag
|
52
|
+
assert_select node(html), 'title', 'Ecrire'
|
53
|
+
|
54
|
+
html = title_tag('Oops')
|
55
|
+
assert_select node(html), 'title', 'Oops'
|
56
|
+
end
|
57
|
+
|
58
|
+
|
28
59
|
def node(html)
|
29
60
|
Nokogiri::HTML::Document.parse(html)
|
30
61
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ecrire
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.26.
|
4
|
+
version: 0.26.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pier-Olivier Thibault
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-05-
|
11
|
+
date: 2015-05-20 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Blog engine on Rails
|
14
14
|
email: pothibo@gmail.com
|
@@ -48,7 +48,7 @@ files:
|
|
48
48
|
- lib/ecrire/app/assets/javascripts/admin/posts/tag.js.coffee
|
49
49
|
- lib/ecrire/app/assets/javascripts/admin/posts/title.coffee
|
50
50
|
- lib/ecrire/app/assets/javascripts/admin/posts/toggle.js.coffee
|
51
|
-
- lib/ecrire/app/assets/javascripts/
|
51
|
+
- lib/ecrire/app/assets/javascripts/ecrire.js
|
52
52
|
- lib/ecrire/app/assets/javascripts/shared/overlay.js.coffee
|
53
53
|
- lib/ecrire/app/assets/javascripts/shared/popup.js.coffee
|
54
54
|
- lib/ecrire/app/assets/javascripts/vendor/moment.js
|
@@ -65,7 +65,7 @@ files:
|
|
65
65
|
- lib/ecrire/app/assets/stylesheets/admin/save.css.scss
|
66
66
|
- lib/ecrire/app/assets/stylesheets/admin/tags.css.scss
|
67
67
|
- lib/ecrire/app/assets/stylesheets/admin/title.css.scss
|
68
|
-
- lib/ecrire/app/assets/stylesheets/
|
68
|
+
- lib/ecrire/app/assets/stylesheets/ecrire.css.scss
|
69
69
|
- lib/ecrire/app/assets/stylesheets/editor/code.css.scss
|
70
70
|
- lib/ecrire/app/assets/stylesheets/editor/content.css.scss
|
71
71
|
- lib/ecrire/app/assets/stylesheets/editor/figure.css.scss
|
@@ -77,40 +77,29 @@ files:
|
|
77
77
|
- lib/ecrire/app/controllers/admin/application_controller.rb
|
78
78
|
- lib/ecrire/app/controllers/admin/configurations/images_controller.rb
|
79
79
|
- lib/ecrire/app/controllers/admin/images_controller.rb
|
80
|
-
- lib/ecrire/app/controllers/admin/partials_controller.rb
|
81
80
|
- lib/ecrire/app/controllers/admin/posts/tags_controller.rb
|
82
81
|
- lib/ecrire/app/controllers/admin/posts/titles_controller.rb
|
83
82
|
- lib/ecrire/app/controllers/admin/posts_controller.rb
|
84
|
-
- lib/ecrire/app/controllers/admin/properties_controller.rb
|
85
83
|
- lib/ecrire/app/controllers/admin/tags_controller.rb
|
86
84
|
- lib/ecrire/app/controllers/admin/titles_controller.rb
|
87
85
|
- lib/ecrire/app/controllers/application_controller.rb
|
88
86
|
- lib/ecrire/app/controllers/ecrire/theme_controller.rb
|
89
|
-
- lib/ecrire/app/controllers/images_controller.rb
|
90
|
-
- lib/ecrire/app/controllers/partials_controller.rb
|
91
87
|
- lib/ecrire/app/controllers/sessions_controller.rb
|
92
88
|
- lib/ecrire/app/controllers/static_controller.rb
|
93
89
|
- lib/ecrire/app/forms/admin/image_builder.rb
|
94
90
|
- lib/ecrire/app/forms/admin/partial_builder.rb
|
95
91
|
- lib/ecrire/app/forms/admin/post_builder.rb
|
96
92
|
- lib/ecrire/app/helpers/admin/images_helper.rb
|
97
|
-
- lib/ecrire/app/helpers/admin/labels_helper.rb
|
98
93
|
- lib/ecrire/app/helpers/admin/posts_helper.rb
|
99
94
|
- lib/ecrire/app/helpers/application_helper.rb
|
100
95
|
- lib/ecrire/app/helpers/content_tag_helper.rb
|
101
|
-
- lib/ecrire/app/helpers/
|
102
|
-
- lib/ecrire/app/helpers/posts_helper.rb
|
96
|
+
- lib/ecrire/app/helpers/pagination_helper.rb
|
103
97
|
- lib/ecrire/app/models/admin/image.rb
|
104
|
-
- lib/ecrire/app/models/admin/partial.rb
|
105
98
|
- lib/ecrire/app/models/admin/post.rb
|
106
99
|
- lib/ecrire/app/models/admin/tag.rb
|
107
100
|
- lib/ecrire/app/models/admin/title.rb
|
108
|
-
- lib/ecrire/app/models/concerns/.keep
|
109
101
|
- lib/ecrire/app/models/image.rb
|
110
|
-
- lib/ecrire/app/models/partial.rb
|
111
102
|
- lib/ecrire/app/models/post.rb
|
112
|
-
- lib/ecrire/app/models/property/image.rb
|
113
|
-
- lib/ecrire/app/models/property/label.rb
|
114
103
|
- lib/ecrire/app/models/tag.rb
|
115
104
|
- lib/ecrire/app/models/title.rb
|
116
105
|
- lib/ecrire/app/models/user.rb
|
@@ -239,7 +228,6 @@ files:
|
|
239
228
|
- lib/ecrire/theme/template/Procfile
|
240
229
|
- lib/ecrire/theme/template/Rakefile
|
241
230
|
- lib/ecrire/theme/template/assets/images/.keep
|
242
|
-
- lib/ecrire/theme/template/assets/javascripts/theme.js.coffee
|
243
231
|
- lib/ecrire/theme/template/assets/stylesheets/browser.css.scss
|
244
232
|
- lib/ecrire/theme/template/assets/stylesheets/browser/base.css.scss
|
245
233
|
- lib/ecrire/theme/template/assets/stylesheets/mobile.css.scss
|
@@ -256,7 +244,6 @@ files:
|
|
256
244
|
- lib/ecrire/theme/template/controllers/tags_controller.rb
|
257
245
|
- lib/ecrire/theme/template/helpers/blog_helper.rb
|
258
246
|
- lib/ecrire/theme/template/routes.rb
|
259
|
-
- lib/ecrire/theme/template/secrets.yml
|
260
247
|
- lib/ecrire/theme/template/views/layouts/application.html.erb
|
261
248
|
- lib/ecrire/theme/template/views/posts/_latest.html.erb
|
262
249
|
- lib/ecrire/theme/template/views/posts/_post.html.erb
|
@@ -1,43 +0,0 @@
|
|
1
|
-
module Admin
|
2
|
-
class PartialsController < Admin::ApplicationController
|
3
|
-
|
4
|
-
def index
|
5
|
-
@partials = Admin::Partial.page(params[:page]).per(params[:per_page])
|
6
|
-
|
7
|
-
respond_to do |format|
|
8
|
-
format.js
|
9
|
-
format.html
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
def new
|
14
|
-
@partial = Admin::Partial.new
|
15
|
-
end
|
16
|
-
|
17
|
-
def edit
|
18
|
-
@partial = Admin::Partial.find(params[:id].to_i)
|
19
|
-
end
|
20
|
-
|
21
|
-
def create
|
22
|
-
@partial = Admin::Partial.create(partial_params)
|
23
|
-
respond_to do |format|
|
24
|
-
format.html do
|
25
|
-
redirect_to edit_admin_partial_path(@partial)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def update
|
31
|
-
@partial = Admin::Partial.find(params[:id].to_i)
|
32
|
-
@partial.update(partial_params)
|
33
|
-
redirect_to edit_admin_partial_path(@partial) and return
|
34
|
-
end
|
35
|
-
|
36
|
-
protected
|
37
|
-
|
38
|
-
def partial_params
|
39
|
-
params.require(:admin_partial).permit(:title, :content, :javascript, :stylesheet)
|
40
|
-
end
|
41
|
-
|
42
|
-
end
|
43
|
-
end
|
@@ -1,35 +0,0 @@
|
|
1
|
-
module Admin
|
2
|
-
class PropertiesController < Admin::ApplicationController
|
3
|
-
INSTANCES = {
|
4
|
-
label: Property::Label,
|
5
|
-
image: Property::Image
|
6
|
-
}.with_indifferent_access
|
7
|
-
|
8
|
-
helper_method :post
|
9
|
-
|
10
|
-
def create
|
11
|
-
instance = instance_for_property(params[:property])
|
12
|
-
@property = instance.create(params)
|
13
|
-
render "admin/properties/#{instance.name}/create"
|
14
|
-
end
|
15
|
-
|
16
|
-
def destroy
|
17
|
-
instance = instance_for_property(params[:property])
|
18
|
-
@property = instance.destroy(params)
|
19
|
-
render "admin/properties/#{instance.name}/destroy"
|
20
|
-
end
|
21
|
-
|
22
|
-
protected
|
23
|
-
|
24
|
-
def post
|
25
|
-
@post ||= Admin::Post.find(params[:post_id])
|
26
|
-
end
|
27
|
-
|
28
|
-
def instance_for_property(name)
|
29
|
-
instance = INSTANCES[name].new
|
30
|
-
instance.post = post
|
31
|
-
instance
|
32
|
-
end
|
33
|
-
|
34
|
-
end
|
35
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module Admin::LabelsHelper
|
2
|
-
def create_label_button(label, post)
|
3
|
-
button_to label.name.capitalize,
|
4
|
-
admin_post_properties_path(post.id),
|
5
|
-
remote: true,
|
6
|
-
form: {id: "label-#{label.id}"},
|
7
|
-
form_class: %w(create label),
|
8
|
-
params: {
|
9
|
-
property: :label,
|
10
|
-
value: label.name
|
11
|
-
}
|
12
|
-
end
|
13
|
-
|
14
|
-
def destroy_label_button(label, post)
|
15
|
-
button_to label.name.capitalize,
|
16
|
-
admin_post_properties_path(post.id),
|
17
|
-
form: {id: "label-#{label.id}"},
|
18
|
-
form_class: %w(destroy label),
|
19
|
-
method: :delete,
|
20
|
-
remote: true,
|
21
|
-
params: {
|
22
|
-
property: :label,
|
23
|
-
value: label.name
|
24
|
-
}
|
25
|
-
end
|
26
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
module OpenGraphHelper
|
2
|
-
# OpenGraph is in meta tags. First I thought it would bring problem if meta tags wouldn't change between page load.
|
3
|
-
# Thinking it through, it doesn't matter if open graph tags aren't changed between pages as it's needed by crawler that does full page load
|
4
|
-
# So the tags will always match the content.
|
5
|
-
# I doubt this will change in the future as turbolinks checks for crawlers and disable itself when it meets one.
|
6
|
-
#
|
7
|
-
|
8
|
-
def open_graph_tags
|
9
|
-
if @post.nil?
|
10
|
-
og_website
|
11
|
-
else
|
12
|
-
og_article(@post)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
protected
|
17
|
-
|
18
|
-
def og_website
|
19
|
-
[
|
20
|
-
og_title,
|
21
|
-
og_type('website')
|
22
|
-
].join.html_safe
|
23
|
-
end
|
24
|
-
|
25
|
-
def og_article(post)
|
26
|
-
raise OGNoArticleError if post.nil?
|
27
|
-
[
|
28
|
-
og_title,
|
29
|
-
og_type('article'),
|
30
|
-
content_tag(:meta, nil, property: 'og:article:published_time', content: post.published_at.iso8601)
|
31
|
-
].join.html_safe
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
def og_type(value)
|
36
|
-
content_tag :meta, nil, property: 'og:type', content: value
|
37
|
-
end
|
38
|
-
|
39
|
-
def og_title
|
40
|
-
content_tag :meta, nil, property: 'og:title', content: title
|
41
|
-
end
|
42
|
-
|
43
|
-
class OGNoArticleError < StandardError; end
|
44
|
-
|
45
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
module PostsHelper
|
2
|
-
def edit_post_link(options = {})
|
3
|
-
return unless signed_in?
|
4
|
-
|
5
|
-
link_to t('posts.edit'), edit_admin_post_path(post.id), options
|
6
|
-
end
|
7
|
-
|
8
|
-
def paginate(scope, options = {}, &block)
|
9
|
-
_with_routes Ecrire::Theme::Engine.routes do
|
10
|
-
super
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
File without changes
|
@@ -1,30 +0,0 @@
|
|
1
|
-
module Property
|
2
|
-
class Image
|
3
|
-
attr_accessor :post
|
4
|
-
|
5
|
-
def name
|
6
|
-
"image"
|
7
|
-
end
|
8
|
-
|
9
|
-
def create(params)
|
10
|
-
unless post.header.nil?
|
11
|
-
post.header.destroy
|
12
|
-
end
|
13
|
-
img = post.images.build
|
14
|
-
img.file = params[:admin_image][:file]
|
15
|
-
img.save
|
16
|
-
post.header = img
|
17
|
-
post.save
|
18
|
-
end
|
19
|
-
|
20
|
-
# TODO:
|
21
|
-
# 3. Remove id in post properties
|
22
|
-
def destroy(value)
|
23
|
-
return if post.header.nil?
|
24
|
-
img = post.header
|
25
|
-
img.destroy
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
@@ -1,28 +0,0 @@
|
|
1
|
-
module Property
|
2
|
-
class Label
|
3
|
-
attr_accessor :post
|
4
|
-
|
5
|
-
def name
|
6
|
-
"label"
|
7
|
-
end
|
8
|
-
|
9
|
-
def create(params)
|
10
|
-
new_label = ::Label.find_or_create_by!(name: params[:value])
|
11
|
-
labels = post.labels
|
12
|
-
labels << new_label
|
13
|
-
post.labels = labels
|
14
|
-
post.save!
|
15
|
-
new_label
|
16
|
-
end
|
17
|
-
|
18
|
-
def destroy(params)
|
19
|
-
label = ::Label.find_by!(name: params[:value])
|
20
|
-
labels = post.labels
|
21
|
-
labels.delete(label)
|
22
|
-
post.labels = labels
|
23
|
-
post.save!
|
24
|
-
label
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
end
|
@@ -1 +0,0 @@
|
|
1
|
-
#= require_tree .
|
@@ -1,11 +0,0 @@
|
|
1
|
-
---
|
2
|
-
development: &1
|
3
|
-
adapter: postgresql
|
4
|
-
database: ecrire
|
5
|
-
user: pothibo
|
6
|
-
password: 3dbdbc10bdf7bd7d8ad7b6dbcf4bb26c
|
7
|
-
encoding: utf8
|
8
|
-
secret_key: 43fce5ef5993544ba39821911080adfa
|
9
|
-
secret_key_base: 43fce5ef5993544ba39821911080adfa
|
10
|
-
test: *1
|
11
|
-
production: *1
|
File without changes
|
File without changes
|