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.
Files changed (43) hide show
  1. data/app/assets/javascripts/application.js.erb +2 -0
  2. data/app/assets/stylesheets/admin.css.scss +16 -0
  3. data/app/controllers/admin_controller.rb +93 -0
  4. data/app/controllers/application_controller.rb +38 -0
  5. data/app/controllers/cache_controller.rb +34 -0
  6. data/app/controllers/settings_controller.rb +35 -0
  7. data/app/controllers/site_controller.rb +49 -0
  8. data/app/controllers/static_cache_controller.rb +19 -0
  9. data/app/helpers/application_helper.rb +74 -0
  10. data/app/helpers/cache_helper.rb +17 -0
  11. data/app/models/backup.rb +11 -0
  12. data/app/models/database_file.rb +2 -0
  13. data/app/models/markdown.rb +17 -0
  14. data/app/models/page_cache.rb +102 -0
  15. data/app/models/setting.rb +258 -0
  16. data/app/models/simple_template.rb +20 -0
  17. data/app/models/sitemap_entry.rb +5 -0
  18. data/app/models/static_cache.rb +47 -0
  19. data/app/models/tweetable.rb +17 -0
  20. data/app/views/admin/main.html.erb +7 -0
  21. data/app/views/admin/sign_in.html.erb +19 -0
  22. data/app/views/cache/index.html.erb +61 -0
  23. data/app/views/layouts/admin.html.erb +43 -0
  24. data/app/views/layouts/application.html.erb +134 -0
  25. data/app/views/layouts/application.rss.erb +16 -0
  26. data/app/views/layouts/application.xml.erb +2 -0
  27. data/app/views/layouts/general_admin.html.erb +10 -0
  28. data/app/views/layouts/sign_in.html.erb +12 -0
  29. data/app/views/settings/initial_setup.html.erb +25 -0
  30. data/app/views/settings/show.html.erb +39 -0
  31. data/app/views/site/robots.text.erb +1 -0
  32. data/app/views/site/sitemap.xml.erb +12 -0
  33. data/app/views/static_cache/index.html.erb +29 -0
  34. data/cartoonist.gemspec +3 -2
  35. data/config/locales/en.yml +99 -0
  36. data/db/migrate/20120320043253_create_database_files.rb +9 -0
  37. data/db/migrate/20120401014029_create_settings.rb +12 -0
  38. data/lib/cartoonist/engine.rb +129 -0
  39. data/lib/cartoonist.rb +236 -0
  40. data/public/errors/404.html +13 -0
  41. data/public/errors/422.html +11 -0
  42. data/public/errors/500.html +13 -0
  43. 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,5 @@
1
+ class SitemapEntry < Struct.new(:path, :lastmod, :changefreq, :priority)
2
+ def formatted_lastmod
3
+ lastmod.strftime "%Y-%m-%d"
4
+ end
5
+ 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,7 @@
1
+ <p>
2
+ <a href="/admin/reload"><%= t "admin.general.actions.reload" %></a>
3
+ </p>
4
+
5
+ <p>
6
+ <a href="/admin/backup.json"><%= t "admin.general.actions.backup" %></a>
7
+ </p>
@@ -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,2 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <%= yield %>
@@ -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>