cartoonist 0.0.3.5 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/app/assets/javascripts/application.js.erb +2 -0
- data/app/assets/stylesheets/admin.css.scss +16 -0
- data/app/controllers/admin_controller.rb +93 -0
- data/app/controllers/application_controller.rb +38 -0
- data/app/controllers/cache_controller.rb +34 -0
- data/app/controllers/settings_controller.rb +35 -0
- data/app/controllers/site_controller.rb +49 -0
- data/app/controllers/static_cache_controller.rb +19 -0
- data/app/helpers/application_helper.rb +74 -0
- data/app/helpers/cache_helper.rb +17 -0
- data/app/models/backup.rb +11 -0
- data/app/models/database_file.rb +2 -0
- data/app/models/markdown.rb +17 -0
- data/app/models/page_cache.rb +102 -0
- data/app/models/setting.rb +258 -0
- data/app/models/simple_template.rb +20 -0
- data/app/models/sitemap_entry.rb +5 -0
- data/app/models/static_cache.rb +47 -0
- data/app/models/tweetable.rb +17 -0
- data/app/views/admin/main.html.erb +7 -0
- data/app/views/admin/sign_in.html.erb +19 -0
- data/app/views/cache/index.html.erb +61 -0
- data/app/views/layouts/admin.html.erb +43 -0
- data/app/views/layouts/application.html.erb +134 -0
- data/app/views/layouts/application.rss.erb +16 -0
- data/app/views/layouts/application.xml.erb +2 -0
- data/app/views/layouts/general_admin.html.erb +10 -0
- data/app/views/layouts/sign_in.html.erb +12 -0
- data/app/views/settings/initial_setup.html.erb +25 -0
- data/app/views/settings/show.html.erb +39 -0
- data/app/views/site/robots.text.erb +1 -0
- data/app/views/site/sitemap.xml.erb +12 -0
- data/app/views/static_cache/index.html.erb +29 -0
- data/cartoonist.gemspec +3 -2
- data/config/locales/en.yml +99 -0
- data/db/migrate/20120320043253_create_database_files.rb +9 -0
- data/db/migrate/20120401014029_create_settings.rb +12 -0
- data/lib/cartoonist/engine.rb +129 -0
- data/lib/cartoonist.rb +236 -0
- data/public/errors/404.html +13 -0
- data/public/errors/422.html +11 -0
- data/public/errors/500.html +13 -0
- metadata +41 -2
@@ -0,0 +1,258 @@
|
|
1
|
+
class Setting < ActiveRecord::Base
|
2
|
+
class << self
|
3
|
+
def [](label)
|
4
|
+
raise "Invalid label" unless label.present?
|
5
|
+
meta = Meta[label.to_sym]
|
6
|
+
raise "Missing setting definition for '#{label}'" unless meta
|
7
|
+
record = where(:label => label.to_s).first
|
8
|
+
|
9
|
+
if record
|
10
|
+
meta.convert record.value
|
11
|
+
elsif meta.type == :array || meta.type == :hash
|
12
|
+
meta.default.dup
|
13
|
+
else
|
14
|
+
meta.default
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def []=(label, value)
|
19
|
+
raise "Invalid label" unless label.present?
|
20
|
+
meta = Meta[label.to_sym]
|
21
|
+
raise "Missing setting definition for '#{label}'" unless meta
|
22
|
+
old_value = self[label]
|
23
|
+
record = where(:label => label.to_s).first
|
24
|
+
record = Setting.new :label => label.to_s unless record
|
25
|
+
record.value = meta.convert_to_save value
|
26
|
+
record.save!
|
27
|
+
meta.onchange.call if meta.onchange && old_value != value
|
28
|
+
value
|
29
|
+
end
|
30
|
+
|
31
|
+
def define(label, options = {})
|
32
|
+
Meta[label.to_sym] = Meta.new label, options
|
33
|
+
end
|
34
|
+
|
35
|
+
def tabs
|
36
|
+
Tab.all.sort.map &:label
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class Meta
|
41
|
+
attr_reader :label, :tab, :section, :order, :type, :default, :onchange, :select_from
|
42
|
+
@@settings = {}
|
43
|
+
@@by_tab_section_and_label = {}
|
44
|
+
|
45
|
+
def initialize(label, options)
|
46
|
+
@label = label.to_sym
|
47
|
+
@tab = (options[:tab] || Tab.default)
|
48
|
+
@section = (options[:section] || Section.default)
|
49
|
+
@order = (options[:order] || 0)
|
50
|
+
@type = (options[:type] || :string).to_sym
|
51
|
+
@onchange = options[:onchange]
|
52
|
+
@select_from = options[:select_from]
|
53
|
+
raise "Invalid setting type #{@type}" unless [:string, :symbol, :boolean, :int, :float, :array, :hash].include? @type
|
54
|
+
|
55
|
+
# Auto create general tab and section if it isn't created
|
56
|
+
if @tab == :general && !Tab[@tab]
|
57
|
+
Tab.define :general, :order => 0
|
58
|
+
end
|
59
|
+
|
60
|
+
if @section == :general && !Section.by_tab_and_label[@tab][@section]
|
61
|
+
Section.define :general, :order => 0, :tab => @tab
|
62
|
+
end
|
63
|
+
|
64
|
+
if options.include? :default
|
65
|
+
@default = options[:default]
|
66
|
+
elsif @type == :string
|
67
|
+
@default = ""
|
68
|
+
elsif @type == :symbol
|
69
|
+
@default = :""
|
70
|
+
elsif @type == :boolean
|
71
|
+
@default = false
|
72
|
+
elsif @type == :int
|
73
|
+
@default = 0
|
74
|
+
elsif @type == :float
|
75
|
+
@default = 0.0
|
76
|
+
elsif @type == :array
|
77
|
+
@default = []
|
78
|
+
elsif @type == :hash
|
79
|
+
@default = {}
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def select_from_options
|
84
|
+
if select_from.respond_to? :call
|
85
|
+
select_from.call
|
86
|
+
else
|
87
|
+
select_from
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def convert(value)
|
92
|
+
if value.nil?
|
93
|
+
return default.dup if type == :array || type == :hash
|
94
|
+
return default
|
95
|
+
end
|
96
|
+
|
97
|
+
case type
|
98
|
+
when :string
|
99
|
+
value
|
100
|
+
when :symbol
|
101
|
+
value.to_sym
|
102
|
+
when :boolean
|
103
|
+
value == "true"
|
104
|
+
when :int
|
105
|
+
value.to_i
|
106
|
+
when :float
|
107
|
+
value.to_f
|
108
|
+
when :array
|
109
|
+
YAML.load value
|
110
|
+
when :hash
|
111
|
+
YAML.load value
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def convert_to_save(value)
|
116
|
+
return value if value.nil?
|
117
|
+
|
118
|
+
if type == :boolean
|
119
|
+
(!!value).to_s
|
120
|
+
elsif type == :array || type == :hash
|
121
|
+
value.to_yaml
|
122
|
+
else
|
123
|
+
value.to_s
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def <=>(other)
|
128
|
+
result = order <=> other.order
|
129
|
+
result = label <=> other.label if result == 0
|
130
|
+
result
|
131
|
+
end
|
132
|
+
|
133
|
+
class << self
|
134
|
+
def [](label)
|
135
|
+
raise "Missing setting '#{label}'" unless @@settings[label.to_sym]
|
136
|
+
@@settings[label.to_sym]
|
137
|
+
end
|
138
|
+
|
139
|
+
def []=(label, definition)
|
140
|
+
raise "Duplicate setting '#{label}' given!" if @@settings[label.to_sym]
|
141
|
+
@@settings[label.to_sym] = definition
|
142
|
+
@@by_tab_section_and_label[definition.tab] ||= {}
|
143
|
+
@@by_tab_section_and_label[definition.tab][definition.section] ||= {}
|
144
|
+
@@by_tab_section_and_label[definition.tab][definition.section][label.to_sym] = definition
|
145
|
+
end
|
146
|
+
|
147
|
+
def by_tab_section_and_label
|
148
|
+
@@by_tab_section_and_label
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
class Tab
|
154
|
+
attr_reader :label, :order
|
155
|
+
@@all = []
|
156
|
+
@@by_label = {}
|
157
|
+
@@default = :general
|
158
|
+
|
159
|
+
def initialize(label, options = {})
|
160
|
+
@label = label.to_sym
|
161
|
+
@order = options[:order] || 1
|
162
|
+
Section.by_tab_and_label[@label] ||= {}
|
163
|
+
end
|
164
|
+
|
165
|
+
def sections
|
166
|
+
Section.by_tab_and_label[label] ||= {}
|
167
|
+
Section.by_tab_and_label[label].values.sort.map &:label
|
168
|
+
end
|
169
|
+
|
170
|
+
def [](section_label)
|
171
|
+
Section.by_tab_and_label[label] ||= {}
|
172
|
+
Section.by_tab_and_label[label][section_label.to_sym]
|
173
|
+
end
|
174
|
+
|
175
|
+
def <=>(other)
|
176
|
+
result = order <=> other.order
|
177
|
+
result = label <=> other.label if result == 0
|
178
|
+
result
|
179
|
+
end
|
180
|
+
|
181
|
+
class << self
|
182
|
+
def [](label)
|
183
|
+
@@by_label[label.to_sym]
|
184
|
+
end
|
185
|
+
|
186
|
+
def all
|
187
|
+
@@all
|
188
|
+
end
|
189
|
+
|
190
|
+
def default
|
191
|
+
@@default
|
192
|
+
end
|
193
|
+
|
194
|
+
def define(label, options = {})
|
195
|
+
raise "Duplicate tab '#{label}' being defined" if @@by_label.include? label.to_sym
|
196
|
+
tab = Tab.new label, options
|
197
|
+
@@all << tab
|
198
|
+
@@by_label[label.to_sym] = tab
|
199
|
+
begin
|
200
|
+
@@default = label.to_sym
|
201
|
+
yield if block_given?
|
202
|
+
ensure
|
203
|
+
@@default = :general
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
class Section
|
210
|
+
attr_reader :label, :order, :tab
|
211
|
+
@@all = []
|
212
|
+
@@by_tab_and_label = {}
|
213
|
+
@@default = :general
|
214
|
+
|
215
|
+
def initialize(label, options = {})
|
216
|
+
@label = label.to_sym
|
217
|
+
@order = options[:order] || 1
|
218
|
+
@tab = (options[:tab] || Tab.default).to_sym
|
219
|
+
end
|
220
|
+
|
221
|
+
def settings
|
222
|
+
Meta.by_tab_section_and_label[tab][label].values.sort.map &:label
|
223
|
+
end
|
224
|
+
|
225
|
+
def <=>(other)
|
226
|
+
result = order <=> other.order
|
227
|
+
result = label <=> other.label if result == 0
|
228
|
+
result
|
229
|
+
end
|
230
|
+
|
231
|
+
class << self
|
232
|
+
def all
|
233
|
+
@@all
|
234
|
+
end
|
235
|
+
|
236
|
+
def default
|
237
|
+
@@default
|
238
|
+
end
|
239
|
+
|
240
|
+
def define(label, options = {})
|
241
|
+
section = Section.new label, options
|
242
|
+
@@all << section
|
243
|
+
@@by_tab_and_label[section.tab] ||= {}
|
244
|
+
@@by_tab_and_label[section.tab][label.to_sym] = section
|
245
|
+
begin
|
246
|
+
@@default = label.to_sym
|
247
|
+
yield if block_given?
|
248
|
+
ensure
|
249
|
+
@@default = :general
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
def by_tab_and_label
|
254
|
+
@@by_tab_and_label
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class SimpleTemplate
|
2
|
+
class << self
|
3
|
+
def [](str, variables = {})
|
4
|
+
return "" if str.nil?
|
5
|
+
variables ||= {}
|
6
|
+
|
7
|
+
str.gsub /\{\{([^\}]*)\}\}/ do |matched|
|
8
|
+
key = $1.strip.to_sym
|
9
|
+
|
10
|
+
if variables.include? key
|
11
|
+
value = variables[key]
|
12
|
+
value = value.call if value.respond_to? :call
|
13
|
+
value
|
14
|
+
else
|
15
|
+
""
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
class StaticCache
|
2
|
+
attr_reader :name
|
3
|
+
|
4
|
+
CACHE_PATH = File.join Rails.root, "public/cache/static"
|
5
|
+
|
6
|
+
def initialize(name)
|
7
|
+
@name = name
|
8
|
+
end
|
9
|
+
|
10
|
+
def expire!
|
11
|
+
gz_name = "#{name}.gz"
|
12
|
+
StaticCache.cache_files(:with_gz => true).select do |file|
|
13
|
+
file == name || file == gz_name
|
14
|
+
end.each do |file|
|
15
|
+
File.delete File.join(CACHE_PATH, file)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class << self
|
20
|
+
def find(name)
|
21
|
+
name = "" if name == "INDEX"
|
22
|
+
actual = cache_files.select { |x| x == name }.first
|
23
|
+
raise ActiveRecord::RecordNotFound.new("No records found!") unless actual
|
24
|
+
StaticCache.new actual
|
25
|
+
end
|
26
|
+
|
27
|
+
def all
|
28
|
+
cache_files.map do |name|
|
29
|
+
StaticCache.new name
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def cache_files(options = {})
|
34
|
+
Dir.glob(File.join(CACHE_PATH, "**/*"), File::FNM_DOTMATCH).map do |file|
|
35
|
+
next if file =~ /\.gz$/ unless options[:with_gz]
|
36
|
+
next if File.directory? file
|
37
|
+
file.sub "#{CACHE_PATH}/", ""
|
38
|
+
end.compact.sort.uniq
|
39
|
+
end
|
40
|
+
|
41
|
+
def expire_all!
|
42
|
+
files = Dir.glob File.join(CACHE_PATH, "**/*"), File::FNM_DOTMATCH
|
43
|
+
files.reject! { |file| File.directory? file }
|
44
|
+
File.delete *files unless files.empty?
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Tweetable
|
2
|
+
def tweet!
|
3
|
+
return if tweeted?
|
4
|
+
return unless Time.now >= expected_tweet_time
|
5
|
+
|
6
|
+
if Rails.env.production?
|
7
|
+
Twitter.update tweet
|
8
|
+
end
|
9
|
+
|
10
|
+
self.tweeted_at = Time.now
|
11
|
+
save!
|
12
|
+
end
|
13
|
+
|
14
|
+
def tweeted?
|
15
|
+
tweeted_at.present?
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<% if flash[:error] %>
|
2
|
+
<p style="color: red;">
|
3
|
+
<%= flash[:error] %>
|
4
|
+
</p>
|
5
|
+
<% end %>
|
6
|
+
|
7
|
+
<%= form_tag "/admin/sign_in", :method => :post do %>
|
8
|
+
<p>
|
9
|
+
Username: <input type="text" name="username" autofocus="autofocus" />
|
10
|
+
</p>
|
11
|
+
|
12
|
+
<p>
|
13
|
+
Password: <input type="password" name="password" />
|
14
|
+
</p>
|
15
|
+
|
16
|
+
<p>
|
17
|
+
<input type="submit" value="Sign in" />
|
18
|
+
</p>
|
19
|
+
<% end %>
|
@@ -0,0 +1,61 @@
|
|
1
|
+
<p>
|
2
|
+
<%= form_tag "/cache/expire_www", :method => :post, :class => "inline" do %>
|
3
|
+
<input type="submit" value="<%= t "cache.index.expire_www" %>" />
|
4
|
+
<% end %>
|
5
|
+
|
6
|
+
<%= form_tag "/cache/expire_m", :method => :post, :class => "inline" do %>
|
7
|
+
<input type="submit" value="<%= t "cache.index.expire_m" %>" />
|
8
|
+
<% end %>
|
9
|
+
|
10
|
+
<%= form_tag "/cache/expire_tmp", :method => :post, :class => "inline" do %>
|
11
|
+
<input type="submit" value="<%= t "cache.index.expire_tmp" %>" />
|
12
|
+
<% end %>
|
13
|
+
|
14
|
+
<%= form_tag "/cache/expire_all", :method => :post, :class => "inline" do %>
|
15
|
+
<input type="submit" value="<%= t "cache.index.expire_all" %>" />
|
16
|
+
<% end %>
|
17
|
+
</p>
|
18
|
+
|
19
|
+
<p>
|
20
|
+
<table class="cache">
|
21
|
+
<thead>
|
22
|
+
<tr>
|
23
|
+
<th><%= t "cache.index.page" %></th>
|
24
|
+
<th><%= t "cache.index.www" %></th>
|
25
|
+
<th><%= t "cache.index.m" %></th>
|
26
|
+
<th><%= t "cache.index.www_tmp" %></th>
|
27
|
+
<th><%= t "cache.index.m_tmp" %></th>
|
28
|
+
<th></th>
|
29
|
+
</tr>
|
30
|
+
</thead>
|
31
|
+
<tbody>
|
32
|
+
<% @caches.each do |cache| %>
|
33
|
+
<tr>
|
34
|
+
<td><%= cache.display_name %></td>
|
35
|
+
|
36
|
+
<td class="<%= td_cache_class cache.www? %>">
|
37
|
+
<%= td_cache_text cache.www? %>
|
38
|
+
</td>
|
39
|
+
|
40
|
+
<td class="<%= td_cache_class cache.m? %>">
|
41
|
+
<%= td_cache_text cache.m? %>
|
42
|
+
</td>
|
43
|
+
|
44
|
+
<td class="<%= td_cache_class cache.www_tmp? %>">
|
45
|
+
<%= td_cache_text cache.www_tmp? %>
|
46
|
+
</td>
|
47
|
+
|
48
|
+
<td class="<%= td_cache_class cache.m_tmp? %>">
|
49
|
+
<%= td_cache_text cache.m_tmp? %>
|
50
|
+
</td>
|
51
|
+
|
52
|
+
<td>
|
53
|
+
<%= form_tag "/cache/#{u cache.delete_name}", :method => :delete do %>
|
54
|
+
<input type="submit" value="<%= t "cache.index.expire" %>" />
|
55
|
+
<% end %>
|
56
|
+
</td>
|
57
|
+
</tr>
|
58
|
+
<% end %>
|
59
|
+
</tbody>
|
60
|
+
</table>
|
61
|
+
</p>
|
@@ -0,0 +1,43 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title><%= yield(:title) || Setting[:site_name] %></title>
|
5
|
+
<%= stylesheet_link_tag "admin.css" %>
|
6
|
+
<%= csrf_meta_tags %>
|
7
|
+
<link rel="icon" href="http://<%= Setting[:domain] %><%= asset_path Cartoonist::Theme.favicon %>" type="image/x-icon" />
|
8
|
+
<link rel="shortcut icon" href="http://<%= Setting[:domain] %><%= asset_path Cartoonist::Theme.favicon %>" type="image/x-icon" />
|
9
|
+
</head>
|
10
|
+
<body>
|
11
|
+
<p class="tabs">
|
12
|
+
<% Cartoonist::Admin::Tab.all.each do |tab| %>
|
13
|
+
<a class="tab" href="<%= Cartoonist::Admin::Tab[tab] %>"><%= t tab, :scope => "admin.layout.tab" %></a>
|
14
|
+
<% end %>
|
15
|
+
| <%= t "admin.layout.user_heading", :user => session[:user] %> <a href="/admin/logout"><%= t "admin.layout.logout" %></a>
|
16
|
+
</p>
|
17
|
+
|
18
|
+
<% if content_for? :subtabs %>
|
19
|
+
<p class="subtabs">
|
20
|
+
<%= yield :subtabs %>
|
21
|
+
</p>
|
22
|
+
<% end %>
|
23
|
+
|
24
|
+
<% if Rails.env.production? %>
|
25
|
+
<p style="background-color: red; color: white; font-size: 20px; font-weight: bold; text-align: center;">
|
26
|
+
<%= t "admin.layout.production_warning" %>
|
27
|
+
</p>
|
28
|
+
<% else %>
|
29
|
+
<p style="background-color: yellow; color: black; font-size: 20px; text-align: center;">
|
30
|
+
<%= t "admin.layout.not_live_warning" %>
|
31
|
+
</p>
|
32
|
+
<% end %>
|
33
|
+
|
34
|
+
<% if flash[:message] %>
|
35
|
+
<p style="color: red;">
|
36
|
+
<%= flash[:message] %>
|
37
|
+
</p>
|
38
|
+
<% end %>
|
39
|
+
|
40
|
+
<h1><%= yield :page_title %></h1>
|
41
|
+
<%= content_for?(:content) ? yield(:content) : yield %>
|
42
|
+
</body>
|
43
|
+
</html>
|
@@ -0,0 +1,134 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html class="<%= html_class %>">
|
3
|
+
<head>
|
4
|
+
<title><%= yield(:title) || Setting[:site_name] %></title>
|
5
|
+
<%= stylesheet_link_tag Cartoonist::Theme.css %>
|
6
|
+
<% if @output_csrf_meta_tags %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
<% end %>
|
9
|
+
<link rel="icon" href="http://<%= Setting[:domain] %><%= asset_path Cartoonist::Theme.favicon %>" type="image/x-icon" />
|
10
|
+
<link rel="shortcut icon" href="http://<%= Setting[:domain] %><%= asset_path Cartoonist::Theme.favicon %>" type="image/x-icon" />
|
11
|
+
<% if rss? %>
|
12
|
+
<link href="<%= rss_path %>" rel="alternate" title="<%= rss_title %>" type="application/rss+xml" />
|
13
|
+
<% end %>
|
14
|
+
<% if !preview? && Rails.env.production? %>
|
15
|
+
<script type="text/javascript">
|
16
|
+
var _gaq = _gaq || [];
|
17
|
+
_gaq.push(['_setAccount', '<%= j Setting[:google_analytics_account] %>']);
|
18
|
+
_gaq.push(['_trackPageview']);
|
19
|
+
|
20
|
+
(function() {
|
21
|
+
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
22
|
+
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
23
|
+
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
24
|
+
})();
|
25
|
+
</script>
|
26
|
+
<% elsif !preview? %>
|
27
|
+
<!-- Google analytics goes here on live -->
|
28
|
+
<% end %>
|
29
|
+
</head>
|
30
|
+
<body>
|
31
|
+
<div class="site-wrapper">
|
32
|
+
<div class="header">
|
33
|
+
<div class="main-header">
|
34
|
+
<div class="logo"><%= t "application.layout.logo" %></div>
|
35
|
+
<h1 class="site-name"><%= Setting[:site_name] %></h1>
|
36
|
+
<h2 class="heading"><%= Setting[:site_heading] %></h2>
|
37
|
+
<h2 class="site-updates"><%= Setting[:site_update_description] %></h2>
|
38
|
+
|
39
|
+
<div class="small-buttons">
|
40
|
+
<%= yield :small_buttons %>
|
41
|
+
</div>
|
42
|
+
</div>
|
43
|
+
|
44
|
+
<div class="navigation">
|
45
|
+
<div class="long-buttons">
|
46
|
+
<% Cartoonist::Navigation::Link.all.each do |link| %>
|
47
|
+
<a class="<%= link.class %>" href="<%= link.url preview? %>" title="<%= t link.title if link.title %>"><%= t link.label %></a>
|
48
|
+
<% end %>
|
49
|
+
</div>
|
50
|
+
</div>
|
51
|
+
</div>
|
52
|
+
|
53
|
+
<div class="content-container">
|
54
|
+
<div class="content-header"></div>
|
55
|
+
<div class="content <%= yield(:content_class) || "default-content" %>">
|
56
|
+
<%= content_for?(:content) ? yield(:content) : yield %>
|
57
|
+
</div>
|
58
|
+
<div class="content-footer"></div>
|
59
|
+
</div>
|
60
|
+
|
61
|
+
<% if @disqus_enabled %>
|
62
|
+
<div class="comments-container">
|
63
|
+
<div id="disqus_thread">
|
64
|
+
<% if @disqus_options[:count_link] %>
|
65
|
+
<a id="disqus_comments" href="#disqus_thread" data-disqus-identifier="/<%= @disqus_options[:path] %>"></a>
|
66
|
+
<% end %>
|
67
|
+
</div>
|
68
|
+
<noscript>
|
69
|
+
<%= t "application.layout.disqus.noscript_pre_link" %><a href="http://disqus.com/?ref_noscript"><%= t "application.layout.disqus.noscript_link" %></a><%= t "application.layout.disqus.noscript_post_link" %>
|
70
|
+
</noscript>
|
71
|
+
</div>
|
72
|
+
<% end %>
|
73
|
+
|
74
|
+
<div class="footer">
|
75
|
+
<%= yield :post_date_content %>
|
76
|
+
<p class="copyright"><%= copyright_message %></p>
|
77
|
+
<%= yield :admin_content %>
|
78
|
+
<% if licensed? %>
|
79
|
+
<div class="license">
|
80
|
+
<p>
|
81
|
+
This work is licensed under a
|
82
|
+
<a href="<%= content_license_url %>">Creative Commons
|
83
|
+
Attribution-Noncommercial 3.0 Unported License</a>.
|
84
|
+
<a href="/license">See details</a>.
|
85
|
+
</p>
|
86
|
+
|
87
|
+
<div class="license-buttons-container">
|
88
|
+
<div class="license-buttons">
|
89
|
+
<a href="<%= content_license_url %>" class="cc-logo">Creative Commons</a>
|
90
|
+
<a href="<%= content_license_url %>" class="cc-attribute">Attribution</a>
|
91
|
+
<a href="<%= content_license_url %>" class="cc-non-commercial">Noncommercial</a>
|
92
|
+
</div>
|
93
|
+
</div>
|
94
|
+
</div>
|
95
|
+
<% end %>
|
96
|
+
</div>
|
97
|
+
</div>
|
98
|
+
<% if @disqus_enabled && Rails.env.production? %>
|
99
|
+
<script type="text/javascript">
|
100
|
+
var disqus_shortname = "<%= j Setting[:disqus_shortname] %>";
|
101
|
+
var disqus_title = "<%= j @disqus_options[:title] %>";
|
102
|
+
var disqus_category_id = "<%= j @disqus_options[:category].to_s %>";
|
103
|
+
var disqus_identifier = "/<%= j @disqus_options[:path] %>";
|
104
|
+
var disqus_url = "http://<%= j Setting[:domain] %>/<%= j @disqus_options[:path] %>";
|
105
|
+
<% if @disqus_options[:count_link] %>
|
106
|
+
(function () {
|
107
|
+
var s = document.createElement('script'); s.async = true;
|
108
|
+
s.type = 'text/javascript';
|
109
|
+
s.src = 'http://' + disqus_shortname + '.disqus.com/count.js';
|
110
|
+
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(s);
|
111
|
+
}());
|
112
|
+
|
113
|
+
var comments = document.getElementById("disqus_comments");
|
114
|
+
comments.onclick = function() {
|
115
|
+
document.getElementById("disqus_thread").removeChild(comments);
|
116
|
+
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
|
117
|
+
dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
|
118
|
+
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
|
119
|
+
return false;
|
120
|
+
};
|
121
|
+
<% else %>
|
122
|
+
(function() {
|
123
|
+
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
|
124
|
+
dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
|
125
|
+
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
|
126
|
+
})();
|
127
|
+
<% end %>
|
128
|
+
</script>
|
129
|
+
<% end %>
|
130
|
+
<% if Cartoonist::Asset.included_js? %>
|
131
|
+
<%= javascript_include_tag "application" %>
|
132
|
+
<% end %>
|
133
|
+
</body>
|
134
|
+
</html>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" ?>
|
2
|
+
<rss version="2.0">
|
3
|
+
<channel>
|
4
|
+
<title><%= yield :rss_title %></title>
|
5
|
+
<description><%= Setting[:site_heading] %></description>
|
6
|
+
<link>http://<%= Setting[:domain] %>/</link>
|
7
|
+
<pubDate><%= yield :pub_date %></pubDate>
|
8
|
+
<lastBuildDate><%= yield :pub_date %></lastBuildDate>
|
9
|
+
<image>
|
10
|
+
<url>http://<%= Setting[:domain] %><%= asset_path Cartoonist::Theme.rss_logo %></url>
|
11
|
+
<title><%= Setting[:site_name] %></title>
|
12
|
+
<link>http://<%= Setting[:domain] %></link>
|
13
|
+
</image>
|
14
|
+
<%= yield %>
|
15
|
+
</channel>
|
16
|
+
</rss>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<% content_for :subtabs do %>
|
2
|
+
<a class="subtab" href="/admin"><%= t "admin.general.layout.actions" %></a>
|
3
|
+
<a class="subtab" href="/settings"><%= t "admin.general.layout.settings" %></a>
|
4
|
+
<a class="subtab" href="/cache"><%= t "admin.general.layout.cache" %></a>
|
5
|
+
<a class="subtab" href="/static_cache"><%= t "admin.general.layout.static_cache" %></a>
|
6
|
+
<% end %>
|
7
|
+
|
8
|
+
<% content_for :page_title, t("admin.general.layout.section") %>
|
9
|
+
<% content_for(:content) { yield } %>
|
10
|
+
<%= render :template => "layouts/admin" %>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Sign In</title>
|
5
|
+
<%= csrf_meta_tags %>
|
6
|
+
<link rel="icon" href="http://<%= Setting[:domain] %><%= asset_path Cartoonist::Theme.favicon %>" type="image/x-icon" />
|
7
|
+
<link rel="shortcut icon" href="http://<%= Setting[:domain] %><%= asset_path Cartoonist::Theme.favicon %>" type="image/x-icon" />
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
<%= yield %>
|
11
|
+
</body>
|
12
|
+
</html>
|