not_pressed-core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +41 -0
- data/README.md +285 -0
- data/app/assets/javascripts/not_pressed/lightbox.js +110 -0
- data/app/assets/stylesheets/not_pressed/admin.css +1161 -0
- data/app/assets/stylesheets/not_pressed/content.css +193 -0
- data/app/assets/stylesheets/not_pressed/gallery.css +117 -0
- data/app/assets/stylesheets/not_pressed/themes/starter.css +118 -0
- data/app/controllers/not_pressed/admin/base_controller.rb +21 -0
- data/app/controllers/not_pressed/admin/categories_controller.rb +53 -0
- data/app/controllers/not_pressed/admin/content_blocks_controller.rb +73 -0
- data/app/controllers/not_pressed/admin/dashboard_controller.rb +19 -0
- data/app/controllers/not_pressed/admin/forms_controller.rb +86 -0
- data/app/controllers/not_pressed/admin/media_attachments_controller.rb +94 -0
- data/app/controllers/not_pressed/admin/pages_controller.rb +122 -0
- data/app/controllers/not_pressed/admin/plugins_controller.rb +121 -0
- data/app/controllers/not_pressed/admin/settings_controller.rb +19 -0
- data/app/controllers/not_pressed/admin/tags_controller.rb +37 -0
- data/app/controllers/not_pressed/admin/themes_controller.rb +104 -0
- data/app/controllers/not_pressed/application_controller.rb +6 -0
- data/app/controllers/not_pressed/blog_controller.rb +83 -0
- data/app/controllers/not_pressed/form_submissions_controller.rb +70 -0
- data/app/controllers/not_pressed/pages_controller.rb +36 -0
- data/app/controllers/not_pressed/robots_controller.rb +34 -0
- data/app/controllers/not_pressed/sitemaps_controller.rb +12 -0
- data/app/helpers/not_pressed/admin_helper.rb +41 -0
- data/app/helpers/not_pressed/application_helper.rb +6 -0
- data/app/helpers/not_pressed/code_injection_helper.rb +29 -0
- data/app/helpers/not_pressed/content_helper.rb +13 -0
- data/app/helpers/not_pressed/form_helper.rb +80 -0
- data/app/helpers/not_pressed/media_helper.rb +28 -0
- data/app/helpers/not_pressed/seo_helper.rb +69 -0
- data/app/helpers/not_pressed/theme_helper.rb +42 -0
- data/app/mailers/not_pressed/application_mailer.rb +10 -0
- data/app/mailers/not_pressed/form_mailer.rb +15 -0
- data/app/models/concerns/not_pressed/sluggable.rb +43 -0
- data/app/models/not_pressed/category.rb +16 -0
- data/app/models/not_pressed/content_block.rb +46 -0
- data/app/models/not_pressed/form.rb +55 -0
- data/app/models/not_pressed/form_field.rb +23 -0
- data/app/models/not_pressed/form_submission.rb +19 -0
- data/app/models/not_pressed/media_attachment.rb +68 -0
- data/app/models/not_pressed/page.rb +182 -0
- data/app/models/not_pressed/page_version.rb +15 -0
- data/app/models/not_pressed/setting.rb +20 -0
- data/app/models/not_pressed/tag.rb +15 -0
- data/app/models/not_pressed/tagging.rb +12 -0
- data/app/plugins/not_pressed/analytics_plugin.rb +106 -0
- data/app/plugins/not_pressed/callout_block_plugin.rb +43 -0
- data/app/themes/not_pressed/starter_theme.rb +26 -0
- data/app/views/layouts/not_pressed/admin.html.erb +745 -0
- data/app/views/layouts/not_pressed/application.html.erb +12 -0
- data/app/views/layouts/not_pressed/page.html.erb +22 -0
- data/app/views/not_pressed/admin/categories/index.html.erb +58 -0
- data/app/views/not_pressed/admin/content_blocks/_block.html.erb +18 -0
- data/app/views/not_pressed/admin/content_blocks/_block_picker.html.erb +32 -0
- data/app/views/not_pressed/admin/content_blocks/create.turbo_stream.erb +3 -0
- data/app/views/not_pressed/admin/content_blocks/destroy.turbo_stream.erb +1 -0
- data/app/views/not_pressed/admin/content_blocks/editors/_callout.html.erb +38 -0
- data/app/views/not_pressed/admin/content_blocks/editors/_code.html.erb +26 -0
- data/app/views/not_pressed/admin/content_blocks/editors/_divider.html.erb +4 -0
- data/app/views/not_pressed/admin/content_blocks/editors/_form.html.erb +16 -0
- data/app/views/not_pressed/admin/content_blocks/editors/_gallery.html.erb +75 -0
- data/app/views/not_pressed/admin/content_blocks/editors/_heading.html.erb +26 -0
- data/app/views/not_pressed/admin/content_blocks/editors/_html.html.erb +13 -0
- data/app/views/not_pressed/admin/content_blocks/editors/_image.html.erb +56 -0
- data/app/views/not_pressed/admin/content_blocks/editors/_quote.html.erb +24 -0
- data/app/views/not_pressed/admin/content_blocks/editors/_text.html.erb +28 -0
- data/app/views/not_pressed/admin/content_blocks/editors/_video.html.erb +25 -0
- data/app/views/not_pressed/admin/dashboard/index.html.erb +60 -0
- data/app/views/not_pressed/admin/forms/_field_row.html.erb +33 -0
- data/app/views/not_pressed/admin/forms/_form.html.erb +75 -0
- data/app/views/not_pressed/admin/forms/edit.html.erb +1 -0
- data/app/views/not_pressed/admin/forms/index.html.erb +32 -0
- data/app/views/not_pressed/admin/forms/new.html.erb +1 -0
- data/app/views/not_pressed/admin/forms/submissions.html.erb +34 -0
- data/app/views/not_pressed/admin/media_attachments/_media_card.html.erb +21 -0
- data/app/views/not_pressed/admin/media_attachments/_picker.html.erb +19 -0
- data/app/views/not_pressed/admin/media_attachments/edit.html.erb +57 -0
- data/app/views/not_pressed/admin/media_attachments/index.html.erb +48 -0
- data/app/views/not_pressed/admin/pages/_form.html.erb +177 -0
- data/app/views/not_pressed/admin/pages/_page_tree_node.html.erb +32 -0
- data/app/views/not_pressed/admin/pages/edit.html.erb +69 -0
- data/app/views/not_pressed/admin/pages/index.html.erb +21 -0
- data/app/views/not_pressed/admin/pages/new.html.erb +1 -0
- data/app/views/not_pressed/admin/pages/preview.html.erb +17 -0
- data/app/views/not_pressed/admin/plugins/_settings_form.html.erb +59 -0
- data/app/views/not_pressed/admin/plugins/index.html.erb +48 -0
- data/app/views/not_pressed/admin/plugins/show.html.erb +54 -0
- data/app/views/not_pressed/admin/settings/code_injection.html.erb +21 -0
- data/app/views/not_pressed/admin/shared/_breadcrumbs.html.erb +14 -0
- data/app/views/not_pressed/admin/shared/_flash.html.erb +7 -0
- data/app/views/not_pressed/admin/shared/_modal.html.erb +9 -0
- data/app/views/not_pressed/admin/shared/_sidebar.html.erb +18 -0
- data/app/views/not_pressed/admin/tags/index.html.erb +52 -0
- data/app/views/not_pressed/admin/themes/index.html.erb +60 -0
- data/app/views/not_pressed/admin/themes/show.html.erb +66 -0
- data/app/views/not_pressed/blog/_post_card.html.erb +24 -0
- data/app/views/not_pressed/blog/feed.rss.builder +22 -0
- data/app/views/not_pressed/blog/index.html.erb +56 -0
- data/app/views/not_pressed/blog/show.html.erb +41 -0
- data/app/views/not_pressed/form_mailer/submission_notification.text.erb +8 -0
- data/app/views/not_pressed/pages/show.html.erb +4 -0
- data/app/views/themes/starter/layouts/not_pressed/default.html.erb +36 -0
- data/app/views/themes/starter/layouts/not_pressed/full_width.html.erb +36 -0
- data/app/views/themes/starter/layouts/not_pressed/sidebar.html.erb +41 -0
- data/config/routes.rb +81 -0
- data/db/migrate/20260310000001_create_not_pressed_pages.rb +20 -0
- data/db/migrate/20260310000002_create_not_pressed_content_blocks.rb +17 -0
- data/db/migrate/20260310000003_create_not_pressed_media_attachments.rb +14 -0
- data/db/migrate/20260310000004_add_content_type_to_not_pressed_pages.rb +8 -0
- data/db/migrate/20260310000005_add_publishing_fields_to_not_pressed_pages.rb +8 -0
- data/db/migrate/20260310000006_create_not_pressed_page_versions.rb +16 -0
- data/db/migrate/20260310000007_add_settings_fields_to_not_pressed_pages.rb +11 -0
- data/db/migrate/20260311000001_create_not_pressed_forms.rb +42 -0
- data/db/migrate/20260311000002_add_seo_fields_to_not_pressed_pages.rb +10 -0
- data/db/migrate/20260311000003_add_code_injection_to_not_pressed_pages.rb +8 -0
- data/db/migrate/20260311000004_create_not_pressed_settings.rb +14 -0
- data/db/migrate/20260312000001_create_not_pressed_categories.rb +16 -0
- data/db/migrate/20260312000002_create_not_pressed_tags.rb +15 -0
- data/db/migrate/20260312000003_create_not_pressed_taggings.rb +14 -0
- data/db/migrate/20260312000004_add_category_id_to_not_pressed_pages.rb +7 -0
- data/lib/generators/not_pressed/install/install_generator.rb +52 -0
- data/lib/generators/not_pressed/install/templates/initializer.rb.tt +89 -0
- data/lib/generators/not_pressed/install/templates/seeds.rb.tt +131 -0
- data/lib/generators/not_pressed/plugin/plugin_generator.rb +37 -0
- data/lib/generators/not_pressed/plugin/templates/plugin.rb.tt +23 -0
- data/lib/not_pressed/admin/authentication.rb +48 -0
- data/lib/not_pressed/admin/menu_registry.rb +100 -0
- data/lib/not_pressed/configuration.rb +77 -0
- data/lib/not_pressed/content_type.rb +23 -0
- data/lib/not_pressed/content_type_builder.rb +51 -0
- data/lib/not_pressed/content_type_registry.rb +45 -0
- data/lib/not_pressed/engine.rb +132 -0
- data/lib/not_pressed/hooks.rb +166 -0
- data/lib/not_pressed/navigation/builder.rb +148 -0
- data/lib/not_pressed/navigation/menu.rb +54 -0
- data/lib/not_pressed/navigation/menu_item.rb +33 -0
- data/lib/not_pressed/navigation/node.rb +45 -0
- data/lib/not_pressed/navigation/partial_parser.rb +96 -0
- data/lib/not_pressed/navigation/route_inspector.rb +98 -0
- data/lib/not_pressed/navigation.rb +6 -0
- data/lib/not_pressed/plugin.rb +354 -0
- data/lib/not_pressed/plugin_importer.rb +133 -0
- data/lib/not_pressed/plugin_manager.rb +196 -0
- data/lib/not_pressed/plugin_packager.rb +129 -0
- data/lib/not_pressed/rendering/block_renderer.rb +222 -0
- data/lib/not_pressed/rendering/renderer_registry.rb +154 -0
- data/lib/not_pressed/rendering.rb +8 -0
- data/lib/not_pressed/seo/sitemap_builder.rb +61 -0
- data/lib/not_pressed/theme.rb +191 -0
- data/lib/not_pressed/theme_importer.rb +133 -0
- data/lib/not_pressed/theme_packager.rb +180 -0
- data/lib/not_pressed/theme_registry.rb +123 -0
- data/lib/not_pressed/version.rb +5 -0
- data/lib/not_pressed.rb +65 -0
- metadata +258 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
<%= form_tag(update_settings_admin_plugin_path(plugin_name: plugin.plugin_name), method: :patch) do %>
|
|
2
|
+
<% instance = plugin_info[:instance] || plugin.new %>
|
|
3
|
+
<% values = instance.settings_values %>
|
|
4
|
+
|
|
5
|
+
<% plugin.plugin_settings_schema.each do |field| %>
|
|
6
|
+
<div style="margin-bottom: 1rem;">
|
|
7
|
+
<label for="plugin_settings_<%= field[:key] %>">
|
|
8
|
+
<%= field[:label] || field[:key].to_s.humanize %>
|
|
9
|
+
<% if field[:required] %><span style="color: red;">*</span><% end %>
|
|
10
|
+
</label>
|
|
11
|
+
|
|
12
|
+
<% current_value = values[field[:key].to_s] %>
|
|
13
|
+
<% default_value = field[:default] %>
|
|
14
|
+
<% display_value = current_value.nil? ? default_value : current_value %>
|
|
15
|
+
|
|
16
|
+
<% case field[:type] %>
|
|
17
|
+
<% when :string %>
|
|
18
|
+
<%= text_field_tag "plugin_settings[#{field[:key]}]", display_value,
|
|
19
|
+
id: "plugin_settings_#{field[:key]}",
|
|
20
|
+
class: "np-input",
|
|
21
|
+
style: "width: 100%; padding: 0.5rem;" %>
|
|
22
|
+
|
|
23
|
+
<% when :text %>
|
|
24
|
+
<%= text_area_tag "plugin_settings[#{field[:key]}]", display_value,
|
|
25
|
+
id: "plugin_settings_#{field[:key]}",
|
|
26
|
+
class: "np-input",
|
|
27
|
+
rows: 4,
|
|
28
|
+
style: "width: 100%; padding: 0.5rem;" %>
|
|
29
|
+
|
|
30
|
+
<% when :boolean %>
|
|
31
|
+
<%= hidden_field_tag "plugin_settings[#{field[:key]}]", "0" %>
|
|
32
|
+
<%= check_box_tag "plugin_settings[#{field[:key]}]", "1",
|
|
33
|
+
display_value.to_s == "true" || display_value == true,
|
|
34
|
+
id: "plugin_settings_#{field[:key]}" %>
|
|
35
|
+
|
|
36
|
+
<% when :select %>
|
|
37
|
+
<%= select_tag "plugin_settings[#{field[:key]}]",
|
|
38
|
+
options_for_select(field[:options] || [], display_value),
|
|
39
|
+
id: "plugin_settings_#{field[:key]}",
|
|
40
|
+
class: "np-input",
|
|
41
|
+
style: "width: 100%; padding: 0.5rem;" %>
|
|
42
|
+
|
|
43
|
+
<% when :integer %>
|
|
44
|
+
<%= number_field_tag "plugin_settings[#{field[:key]}]", display_value,
|
|
45
|
+
id: "plugin_settings_#{field[:key]}",
|
|
46
|
+
class: "np-input",
|
|
47
|
+
style: "width: 100%; padding: 0.5rem;" %>
|
|
48
|
+
<% end %>
|
|
49
|
+
|
|
50
|
+
<% if default_value.present? && current_value.nil? %>
|
|
51
|
+
<small style="color: #666;">Default: <%= default_value %></small>
|
|
52
|
+
<% end %>
|
|
53
|
+
</div>
|
|
54
|
+
<% end %>
|
|
55
|
+
|
|
56
|
+
<div style="margin-top: 1rem;">
|
|
57
|
+
<%= submit_tag "Save Settings", class: "np-btn np-btn--primary" %>
|
|
58
|
+
</div>
|
|
59
|
+
<% end %>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<div class="np-card np-card--form" style="margin-bottom: 2rem;">
|
|
2
|
+
<h3>Import Plugin</h3>
|
|
3
|
+
<%= form_tag(admin_import_plugin_path, method: :post, multipart: true, class: "np-form") do %>
|
|
4
|
+
<div class="np-form-group">
|
|
5
|
+
<%= file_field_tag :plugin_archive, accept: ".zip", class: "np-input" %>
|
|
6
|
+
</div>
|
|
7
|
+
<%= submit_tag "Import Plugin", class: "np-btn np-btn--primary" %>
|
|
8
|
+
<% end %>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<% if @plugins.any? %>
|
|
12
|
+
<table class="np-table">
|
|
13
|
+
<thead>
|
|
14
|
+
<tr>
|
|
15
|
+
<th>Plugin</th>
|
|
16
|
+
<th>Version</th>
|
|
17
|
+
<th>Author</th>
|
|
18
|
+
<th>Status</th>
|
|
19
|
+
<th>Actions</th>
|
|
20
|
+
</tr>
|
|
21
|
+
</thead>
|
|
22
|
+
<tbody>
|
|
23
|
+
<% @plugins.each do |name, info| %>
|
|
24
|
+
<tr>
|
|
25
|
+
<td>
|
|
26
|
+
<%= link_to info[:klass].plugin_name, admin_plugin_path(plugin_name: name) %>
|
|
27
|
+
<% if info[:klass].plugin_description.present? %>
|
|
28
|
+
<br><small><%= info[:klass].plugin_description %></small>
|
|
29
|
+
<% end %>
|
|
30
|
+
</td>
|
|
31
|
+
<td><%= info[:klass].plugin_version || "—" %></td>
|
|
32
|
+
<td><%= info[:klass].plugin_author || "—" %></td>
|
|
33
|
+
<td><%= status_badge(info[:status]) %></td>
|
|
34
|
+
<td>
|
|
35
|
+
<%= link_to "Settings", admin_plugin_path(plugin_name: name), class: "np-btn np-btn--small" %>
|
|
36
|
+
<%= link_to "Export", admin_export_plugin_path(id: name), class: "np-btn np-btn--small np-btn--secondary", download: "" %>
|
|
37
|
+
<%= button_to(info[:status] == :active ? "Disable" : "Enable",
|
|
38
|
+
toggle_admin_plugin_path(plugin_name: name),
|
|
39
|
+
method: :post,
|
|
40
|
+
class: "np-btn np-btn--small#{info[:status] == :active ? ' np-btn--danger' : ''}") %>
|
|
41
|
+
</td>
|
|
42
|
+
</tr>
|
|
43
|
+
<% end %>
|
|
44
|
+
</tbody>
|
|
45
|
+
</table>
|
|
46
|
+
<% else %>
|
|
47
|
+
<p>No plugins installed. Plugins will appear here once registered.</p>
|
|
48
|
+
<% end %>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<div class="np-actions" style="margin-bottom: 1.5rem;">
|
|
2
|
+
<%= link_to "Back to Plugins", admin_plugins_path, class: "np-btn" %>
|
|
3
|
+
<%= button_to(@plugin_info[:status] == :active ? "Disable Plugin" : "Enable Plugin",
|
|
4
|
+
toggle_admin_plugin_path(plugin_name: @plugin_class.plugin_name),
|
|
5
|
+
method: :post,
|
|
6
|
+
class: "np-btn#{@plugin_info[:status] == :active ? ' np-btn--danger' : ' np-btn--primary'}") %>
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
<div class="np-card" style="margin-bottom: 1.5rem; padding: 1.5rem;">
|
|
10
|
+
<h2><%= @plugin_class.plugin_name %></h2>
|
|
11
|
+
<p><%= status_badge(@plugin_info[:status]) %></p>
|
|
12
|
+
|
|
13
|
+
<% if @plugin_class.plugin_description.present? %>
|
|
14
|
+
<p><%= @plugin_class.plugin_description %></p>
|
|
15
|
+
<% end %>
|
|
16
|
+
|
|
17
|
+
<table class="np-table">
|
|
18
|
+
<tbody>
|
|
19
|
+
<% if @plugin_class.plugin_version.present? %>
|
|
20
|
+
<tr><td><strong>Version</strong></td><td><%= @plugin_class.plugin_version %></td></tr>
|
|
21
|
+
<% end %>
|
|
22
|
+
<% if @plugin_class.plugin_author.present? %>
|
|
23
|
+
<tr><td><strong>Author</strong></td><td><%= @plugin_class.plugin_author %></td></tr>
|
|
24
|
+
<% end %>
|
|
25
|
+
<% if @plugin_class.plugin_url.present? %>
|
|
26
|
+
<tr><td><strong>URL</strong></td><td><%= link_to @plugin_class.plugin_url, @plugin_class.plugin_url, target: "_blank", rel: "noopener" %></td></tr>
|
|
27
|
+
<% end %>
|
|
28
|
+
</tbody>
|
|
29
|
+
</table>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<% if @plugin_class.plugin_dependencies.present? %>
|
|
33
|
+
<div class="np-card" style="margin-bottom: 1.5rem; padding: 1.5rem;">
|
|
34
|
+
<h3>Dependencies</h3>
|
|
35
|
+
<ul>
|
|
36
|
+
<% @plugin_class.plugin_dependencies.each do |dep| %>
|
|
37
|
+
<li>
|
|
38
|
+
<%= dep[:name] %>
|
|
39
|
+
<% if dep[:constraint] %> (<%= dep[:constraint] %>)<% end %>
|
|
40
|
+
— <%= NotPressed::PluginManager.enabled?(dep[:name]) ? status_badge(:active) : status_badge(:inactive) %>
|
|
41
|
+
</li>
|
|
42
|
+
<% end %>
|
|
43
|
+
</ul>
|
|
44
|
+
</div>
|
|
45
|
+
<% end %>
|
|
46
|
+
|
|
47
|
+
<% if @plugin_class.plugin_settings_schema.present? %>
|
|
48
|
+
<div class="np-card" style="padding: 1.5rem;">
|
|
49
|
+
<h3>Settings</h3>
|
|
50
|
+
<%= render "not_pressed/admin/plugins/settings_form",
|
|
51
|
+
plugin: @plugin_class,
|
|
52
|
+
plugin_info: @plugin_info %>
|
|
53
|
+
</div>
|
|
54
|
+
<% end %>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<%= form_with url: code_injection_admin_settings_path, method: :patch, class: "np-form" do |f| %>
|
|
2
|
+
<fieldset class="np-fieldset">
|
|
3
|
+
<legend class="np-legend">Global Code Injection</legend>
|
|
4
|
+
|
|
5
|
+
<div class="np-form-group">
|
|
6
|
+
<%= f.label :global_head_code, "Head Code", class: "np-label" %>
|
|
7
|
+
<p class="np-hint">Injected before <code></head></code> on every page. Useful for analytics, custom fonts, or meta tags.</p>
|
|
8
|
+
<%= text_area_tag :global_head_code, @global_head_code, class: "np-input", rows: 8, style: "font-family: monospace;" %>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<div class="np-form-group">
|
|
12
|
+
<%= f.label :global_body_code, "Body Code", class: "np-label" %>
|
|
13
|
+
<p class="np-hint">Injected before <code></body></code> on every page. Useful for tracking scripts or chat widgets.</p>
|
|
14
|
+
<%= text_area_tag :global_body_code, @global_body_code, class: "np-input", rows: 8, style: "font-family: monospace;" %>
|
|
15
|
+
</div>
|
|
16
|
+
</fieldset>
|
|
17
|
+
|
|
18
|
+
<div class="np-form-actions">
|
|
19
|
+
<%= f.submit "Save", class: "np-btn np-btn--primary" %>
|
|
20
|
+
</div>
|
|
21
|
+
<% end %>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<% if @breadcrumbs.present? %>
|
|
2
|
+
<nav aria-label="Breadcrumb" class="np-breadcrumbs">
|
|
3
|
+
<% @breadcrumbs.each_with_index do |crumb, index| %>
|
|
4
|
+
<% if index > 0 %>
|
|
5
|
+
<span class="np-breadcrumb-separator">/</span>
|
|
6
|
+
<% end %>
|
|
7
|
+
<% if crumb[:path] && index < @breadcrumbs.size - 1 %>
|
|
8
|
+
<%= link_to crumb[:label], crumb[:path] %>
|
|
9
|
+
<% else %>
|
|
10
|
+
<span><%= crumb[:label] %></span>
|
|
11
|
+
<% end %>
|
|
12
|
+
<% end %>
|
|
13
|
+
</nav>
|
|
14
|
+
<% end %>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<% flash.each do |type, message| %>
|
|
2
|
+
<% next unless %w[notice alert].include?(type) %>
|
|
3
|
+
<div class="np-flash np-flash--<%= type %>" data-controller="np-flash">
|
|
4
|
+
<span><%= message %></span>
|
|
5
|
+
<button class="np-flash-close" data-action="np-flash#dismiss" aria-label="Dismiss">×</button>
|
|
6
|
+
</div>
|
|
7
|
+
<% end %>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<dialog id="<%= id %>" class="np-modal" data-controller="np-modal">
|
|
2
|
+
<div class="np-modal-header">
|
|
3
|
+
<h3><%= title %></h3>
|
|
4
|
+
<button class="np-modal-close" data-action="np-modal#close" aria-label="Close">×</button>
|
|
5
|
+
</div>
|
|
6
|
+
<div class="np-modal-body">
|
|
7
|
+
<%= yield %>
|
|
8
|
+
</div>
|
|
9
|
+
</dialog>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<aside id="admin-sidebar" data-np-sidebar-target="panel">
|
|
2
|
+
<div class="sidebar-header">
|
|
3
|
+
<h1><%= NotPressed.configuration.site_name %></h1>
|
|
4
|
+
</div>
|
|
5
|
+
<nav>
|
|
6
|
+
<ul>
|
|
7
|
+
<% NotPressed::Admin::MenuRegistry.items(section: :main).each do |item| %>
|
|
8
|
+
<li><%= admin_nav_item item[:label], item[:path].is_a?(Symbol) ? not_pressed.send(item[:path]) : item[:path], icon: item[:icon] %></li>
|
|
9
|
+
<% end %>
|
|
10
|
+
</ul>
|
|
11
|
+
<h3 class="sidebar-section-title">Settings</h3>
|
|
12
|
+
<ul>
|
|
13
|
+
<% NotPressed::Admin::MenuRegistry.items(section: :settings).each do |item| %>
|
|
14
|
+
<li><%= admin_nav_item item[:label], item[:path].is_a?(Symbol) ? not_pressed.send(item[:path]) : item[:path], icon: item[:icon] %></li>
|
|
15
|
+
<% end %>
|
|
16
|
+
</ul>
|
|
17
|
+
</nav>
|
|
18
|
+
</aside>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<div class="np-actions" style="margin-bottom: 1.5rem;">
|
|
2
|
+
<h2 style="margin: 0;">Add Tag</h2>
|
|
3
|
+
</div>
|
|
4
|
+
|
|
5
|
+
<%= form_with model: @tag, url: admin_tags_path, class: "np-form", style: "margin-bottom: 2rem;" do |f| %>
|
|
6
|
+
<% if @tag.errors.any? %>
|
|
7
|
+
<div class="np-form-errors">
|
|
8
|
+
<ul>
|
|
9
|
+
<% @tag.errors.full_messages.each do |message| %>
|
|
10
|
+
<li><%= message %></li>
|
|
11
|
+
<% end %>
|
|
12
|
+
</ul>
|
|
13
|
+
</div>
|
|
14
|
+
<% end %>
|
|
15
|
+
|
|
16
|
+
<div style="display: flex; gap: 0.5rem; align-items: flex-end;">
|
|
17
|
+
<div class="np-form-group" style="margin-bottom: 0; flex: 1;">
|
|
18
|
+
<%= f.label :name, class: "np-label" %>
|
|
19
|
+
<%= f.text_field :name, class: "np-input", placeholder: "Tag name" %>
|
|
20
|
+
</div>
|
|
21
|
+
<div>
|
|
22
|
+
<%= f.submit "Add", class: "np-btn np-btn--primary" %>
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
<% end %>
|
|
26
|
+
|
|
27
|
+
<% if @tags.any? %>
|
|
28
|
+
<table class="np-table">
|
|
29
|
+
<thead>
|
|
30
|
+
<tr>
|
|
31
|
+
<th>Name</th>
|
|
32
|
+
<th>Slug</th>
|
|
33
|
+
<th>Posts</th>
|
|
34
|
+
<th>Actions</th>
|
|
35
|
+
</tr>
|
|
36
|
+
</thead>
|
|
37
|
+
<tbody>
|
|
38
|
+
<% @tags.each do |tag| %>
|
|
39
|
+
<tr>
|
|
40
|
+
<td><%= tag.name %></td>
|
|
41
|
+
<td><code><%= tag.slug %></code></td>
|
|
42
|
+
<td><%= tag.pages.count %></td>
|
|
43
|
+
<td>
|
|
44
|
+
<%= link_to "Delete", admin_tag_path(tag), data: { turbo_method: :delete, turbo_confirm: "Are you sure you want to delete this tag?" }, class: "np-btn np-btn--small np-btn--danger" %>
|
|
45
|
+
</td>
|
|
46
|
+
</tr>
|
|
47
|
+
<% end %>
|
|
48
|
+
</tbody>
|
|
49
|
+
</table>
|
|
50
|
+
<% else %>
|
|
51
|
+
<p>No tags yet. Add one above.</p>
|
|
52
|
+
<% end %>
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<div class="np-card np-card--form" style="margin-bottom: 2rem;">
|
|
2
|
+
<h3>Import Theme</h3>
|
|
3
|
+
<%= form_tag(admin_import_theme_path, method: :post, multipart: true, class: "np-form") do %>
|
|
4
|
+
<div class="np-form-group">
|
|
5
|
+
<%= file_field_tag :theme_archive, accept: ".zip", class: "np-input" %>
|
|
6
|
+
</div>
|
|
7
|
+
<%= submit_tag "Import Theme", class: "np-btn np-btn--primary" %>
|
|
8
|
+
<% end %>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<% if @themes.any? %>
|
|
12
|
+
<div class="np-theme-grid" style="display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1.5rem;">
|
|
13
|
+
<% @themes.each do |name, info| %>
|
|
14
|
+
<div class="np-card" style="padding: 1.5rem;">
|
|
15
|
+
<div style="display: flex; justify-content: space-between; align-items: start; margin-bottom: 0.75rem;">
|
|
16
|
+
<h3 style="margin: 0;"><%= link_to info[:klass].plugin_name, admin_theme_path(theme_name: name) %></h3>
|
|
17
|
+
<% if @active_theme == info[:klass] %>
|
|
18
|
+
<span class="np-badge np-badge--active">Active</span>
|
|
19
|
+
<% end %>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<% if info[:klass].plugin_description.present? %>
|
|
23
|
+
<p style="color: #64748b; margin: 0 0 0.75rem;"><%= info[:klass].plugin_description %></p>
|
|
24
|
+
<% end %>
|
|
25
|
+
|
|
26
|
+
<table class="np-table" style="margin-bottom: 1rem;">
|
|
27
|
+
<tbody>
|
|
28
|
+
<% if info[:klass].plugin_version.present? %>
|
|
29
|
+
<tr><td><strong>Version</strong></td><td><%= info[:klass].plugin_version %></td></tr>
|
|
30
|
+
<% end %>
|
|
31
|
+
<% if info[:klass].plugin_author.present? %>
|
|
32
|
+
<tr><td><strong>Author</strong></td><td><%= info[:klass].plugin_author %></td></tr>
|
|
33
|
+
<% end %>
|
|
34
|
+
</tbody>
|
|
35
|
+
</table>
|
|
36
|
+
|
|
37
|
+
<% if info[:klass].theme_layouts.any? %>
|
|
38
|
+
<div style="margin-bottom: 1rem;">
|
|
39
|
+
<strong>Layouts:</strong>
|
|
40
|
+
<% info[:klass].theme_layouts.each do |layout| %>
|
|
41
|
+
<span class="np-badge"><%= layout[:label] %></span>
|
|
42
|
+
<% end %>
|
|
43
|
+
</div>
|
|
44
|
+
<% end %>
|
|
45
|
+
|
|
46
|
+
<div class="np-actions">
|
|
47
|
+
<% if @active_theme == info[:klass] %>
|
|
48
|
+
<%= button_to "Deactivate", deactivate_admin_theme_path(theme_name: name), method: :post, class: "np-btn np-btn--danger np-btn--small" %>
|
|
49
|
+
<% else %>
|
|
50
|
+
<%= button_to "Activate", activate_admin_theme_path(theme_name: name), method: :post, class: "np-btn np-btn--primary np-btn--small" %>
|
|
51
|
+
<% end %>
|
|
52
|
+
<%= link_to "Customize", admin_theme_path(theme_name: name), class: "np-btn np-btn--small" %>
|
|
53
|
+
<%= link_to "Export", admin_export_theme_path(id: name), class: "np-btn np-btn--small np-btn--secondary", download: "" %>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
<% end %>
|
|
57
|
+
</div>
|
|
58
|
+
<% else %>
|
|
59
|
+
<p>No themes installed. Themes will appear here once registered.</p>
|
|
60
|
+
<% end %>
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<div class="np-actions" style="margin-bottom: 1.5rem;">
|
|
2
|
+
<%= link_to "Back to Themes", admin_themes_path, class: "np-btn" %>
|
|
3
|
+
<% if NotPressed::ThemeRegistry.active == @theme_class %>
|
|
4
|
+
<%= button_to "Deactivate", deactivate_admin_theme_path(theme_name: @theme_class.plugin_name), method: :post, class: "np-btn np-btn--danger" %>
|
|
5
|
+
<% else %>
|
|
6
|
+
<%= button_to "Activate", activate_admin_theme_path(theme_name: @theme_class.plugin_name), method: :post, class: "np-btn np-btn--primary" %>
|
|
7
|
+
<% end %>
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<div class="np-card" style="margin-bottom: 1.5rem; padding: 1.5rem;">
|
|
11
|
+
<h2><%= @theme_class.plugin_name %></h2>
|
|
12
|
+
<% if NotPressed::ThemeRegistry.active == @theme_class %>
|
|
13
|
+
<p><span class="np-badge np-badge--active">Active</span></p>
|
|
14
|
+
<% end %>
|
|
15
|
+
|
|
16
|
+
<% if @theme_class.plugin_description.present? %>
|
|
17
|
+
<p><%= @theme_class.plugin_description %></p>
|
|
18
|
+
<% end %>
|
|
19
|
+
|
|
20
|
+
<table class="np-table">
|
|
21
|
+
<tbody>
|
|
22
|
+
<% if @theme_class.plugin_version.present? %>
|
|
23
|
+
<tr><td><strong>Version</strong></td><td><%= @theme_class.plugin_version %></td></tr>
|
|
24
|
+
<% end %>
|
|
25
|
+
<% if @theme_class.plugin_author.present? %>
|
|
26
|
+
<tr><td><strong>Author</strong></td><td><%= @theme_class.plugin_author %></td></tr>
|
|
27
|
+
<% end %>
|
|
28
|
+
</tbody>
|
|
29
|
+
</table>
|
|
30
|
+
</div>
|
|
31
|
+
|
|
32
|
+
<% if @theme_class.theme_layouts.any? %>
|
|
33
|
+
<div class="np-card" style="margin-bottom: 1.5rem; padding: 1.5rem;">
|
|
34
|
+
<h3>Layouts</h3>
|
|
35
|
+
<ul>
|
|
36
|
+
<% @theme_class.theme_layouts.each do |layout| %>
|
|
37
|
+
<li>
|
|
38
|
+
<strong><%= layout[:label] %></strong> (<code><%= layout[:name] %></code>)
|
|
39
|
+
<% if layout[:primary] %>
|
|
40
|
+
<span class="np-badge np-badge--active">Primary</span>
|
|
41
|
+
<% end %>
|
|
42
|
+
</li>
|
|
43
|
+
<% end %>
|
|
44
|
+
</ul>
|
|
45
|
+
</div>
|
|
46
|
+
<% end %>
|
|
47
|
+
|
|
48
|
+
<% if @colors.any? %>
|
|
49
|
+
<div class="np-card" style="padding: 1.5rem;">
|
|
50
|
+
<h3>Color Customization</h3>
|
|
51
|
+
<%= form_with url: update_colors_admin_theme_path(theme_name: @theme_class.plugin_name), method: :patch, class: "np-form" do |f| %>
|
|
52
|
+
<% @colors.each do |color| %>
|
|
53
|
+
<div class="np-form-group" style="display: flex; align-items: center; gap: 1rem;">
|
|
54
|
+
<input type="color" name="theme_colors[<%= color[:key] %>]" value="<%= @color_values[color[:key]] %>" style="width: 50px; height: 36px; padding: 2px; border: 1px solid #e2e8f0; border-radius: 4px; cursor: pointer;">
|
|
55
|
+
<div>
|
|
56
|
+
<label class="np-label" style="margin-bottom: 0;"><%= color[:label] || color[:key].to_s.humanize %></label>
|
|
57
|
+
<small style="color: #64748b;"><%= @color_values[color[:key]] %></small>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
<% end %>
|
|
61
|
+
<div class="np-form-actions" style="margin-top: 1rem;">
|
|
62
|
+
<%= f.submit "Save Colors", class: "np-btn np-btn--primary" %>
|
|
63
|
+
</div>
|
|
64
|
+
<% end %>
|
|
65
|
+
</div>
|
|
66
|
+
<% end %>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<article class="np-post-card">
|
|
2
|
+
<h2 class="np-post-card__title">
|
|
3
|
+
<%= link_to post.title, not_pressed.blog_post_path(slug: post.slug) %>
|
|
4
|
+
</h2>
|
|
5
|
+
<div class="np-post-card__meta">
|
|
6
|
+
<time datetime="<%= post.published_at&.iso8601 %>"><%= post.published_at&.strftime("%B %-d, %Y") %></time>
|
|
7
|
+
<% if post.category.present? %>
|
|
8
|
+
<span class="np-post-card__category">
|
|
9
|
+
in <%= link_to post.category.name, not_pressed.blog_category_path(slug: post.category.slug) %>
|
|
10
|
+
</span>
|
|
11
|
+
<% end %>
|
|
12
|
+
</div>
|
|
13
|
+
<% first_text = post.content_blocks.ordered.find { |b| b.block_type == "text" } %>
|
|
14
|
+
<% if first_text %>
|
|
15
|
+
<p class="np-post-card__excerpt"><%= truncate(first_text.content["body"].to_s.gsub(/<[^>]+>/, ""), length: 150) %></p>
|
|
16
|
+
<% end %>
|
|
17
|
+
<% if post.tags.any? %>
|
|
18
|
+
<div class="np-post-card__tags">
|
|
19
|
+
<% post.tags.each do |tag| %>
|
|
20
|
+
<%= link_to tag.name, not_pressed.blog_tag_path(slug: tag.slug), class: "np-post-card__tag" %>
|
|
21
|
+
<% end %>
|
|
22
|
+
</div>
|
|
23
|
+
<% end %>
|
|
24
|
+
</article>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
xml.instruct! :xml, version: "1.0"
|
|
2
|
+
xml.rss version: "2.0" do
|
|
3
|
+
xml.channel do
|
|
4
|
+
xml.title NotPressed::Setting.get("site_title") || "Blog"
|
|
5
|
+
xml.description NotPressed::Setting.get("site_description") || ""
|
|
6
|
+
xml.link not_pressed.blog_url
|
|
7
|
+
|
|
8
|
+
@posts.each do |post|
|
|
9
|
+
xml.item do
|
|
10
|
+
xml.title post.title
|
|
11
|
+
xml.link not_pressed.blog_post_url(slug: post.slug)
|
|
12
|
+
xml.guid not_pressed.blog_post_url(slug: post.slug)
|
|
13
|
+
xml.pubDate post.published_at&.rfc822
|
|
14
|
+
xml.description do
|
|
15
|
+
first_text = post.content_blocks.ordered.find { |b| b.block_type == "text" }
|
|
16
|
+
xml.cdata!(first_text ? truncate(first_text.content["body"].to_s.gsub(/<[^>]+>/, ""), length: 300) : post.title)
|
|
17
|
+
end
|
|
18
|
+
xml.category post.category.name if post.category.present?
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<div class="np-blog">
|
|
2
|
+
<h1 class="np-blog__heading">
|
|
3
|
+
<% if @category %>
|
|
4
|
+
Category: <%= @category.name %>
|
|
5
|
+
<% elsif @tag %>
|
|
6
|
+
Tag: <%= @tag.name %>
|
|
7
|
+
<% elsif @year %>
|
|
8
|
+
Archive: <%= @year %><%= @month ? " / #{Date::MONTHNAMES[@month]}" : "" %>
|
|
9
|
+
<% else %>
|
|
10
|
+
Blog
|
|
11
|
+
<% end %>
|
|
12
|
+
</h1>
|
|
13
|
+
|
|
14
|
+
<% if @posts.any? %>
|
|
15
|
+
<div class="np-blog__posts">
|
|
16
|
+
<% @posts.each do |post| %>
|
|
17
|
+
<%= render partial: "not_pressed/blog/post_card", locals: { post: post } %>
|
|
18
|
+
<% end %>
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
<% total_pages = (@total_count / 12.0).ceil %>
|
|
22
|
+
<% if total_pages > 1 %>
|
|
23
|
+
<nav class="np-blog__pagination">
|
|
24
|
+
<% if @page_num > 1 %>
|
|
25
|
+
<% pagination_params = { page: @page_num - 1 } %>
|
|
26
|
+
<% if @category %>
|
|
27
|
+
<%= link_to "Newer", not_pressed.blog_category_path(slug: @category.slug, **pagination_params), class: "np-btn" %>
|
|
28
|
+
<% elsif @tag %>
|
|
29
|
+
<%= link_to "Newer", not_pressed.blog_tag_path(slug: @tag.slug, **pagination_params), class: "np-btn" %>
|
|
30
|
+
<% elsif @year %>
|
|
31
|
+
<%= link_to "Newer", not_pressed.blog_archive_path(year: @year, month: @month, **pagination_params), class: "np-btn" %>
|
|
32
|
+
<% else %>
|
|
33
|
+
<%= link_to "Newer", not_pressed.blog_path(**pagination_params), class: "np-btn" %>
|
|
34
|
+
<% end %>
|
|
35
|
+
<% end %>
|
|
36
|
+
|
|
37
|
+
<span class="np-blog__page-info">Page <%= @page_num %> of <%= total_pages %></span>
|
|
38
|
+
|
|
39
|
+
<% if @page_num < total_pages %>
|
|
40
|
+
<% pagination_params = { page: @page_num + 1 } %>
|
|
41
|
+
<% if @category %>
|
|
42
|
+
<%= link_to "Older", not_pressed.blog_category_path(slug: @category.slug, **pagination_params), class: "np-btn" %>
|
|
43
|
+
<% elsif @tag %>
|
|
44
|
+
<%= link_to "Older", not_pressed.blog_tag_path(slug: @tag.slug, **pagination_params), class: "np-btn" %>
|
|
45
|
+
<% elsif @year %>
|
|
46
|
+
<%= link_to "Older", not_pressed.blog_archive_path(year: @year, month: @month, **pagination_params), class: "np-btn" %>
|
|
47
|
+
<% else %>
|
|
48
|
+
<%= link_to "Older", not_pressed.blog_path(**pagination_params), class: "np-btn" %>
|
|
49
|
+
<% end %>
|
|
50
|
+
<% end %>
|
|
51
|
+
</nav>
|
|
52
|
+
<% end %>
|
|
53
|
+
<% else %>
|
|
54
|
+
<p>No posts found.</p>
|
|
55
|
+
<% end %>
|
|
56
|
+
</div>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<article class="np-blog-post">
|
|
2
|
+
<header class="np-blog-post__header">
|
|
3
|
+
<h1><%= @post.title %></h1>
|
|
4
|
+
<div class="np-blog-post__meta">
|
|
5
|
+
<time datetime="<%= @post.published_at&.iso8601 %>"><%= @post.published_at&.strftime("%B %-d, %Y") %></time>
|
|
6
|
+
<% if @post.category.present? %>
|
|
7
|
+
<span>in <%= link_to @post.category.name, not_pressed.blog_category_path(slug: @post.category.slug) %></span>
|
|
8
|
+
<% end %>
|
|
9
|
+
</div>
|
|
10
|
+
<% if @post.tags.any? %>
|
|
11
|
+
<div class="np-blog-post__tags">
|
|
12
|
+
<% @post.tags.each do |tag| %>
|
|
13
|
+
<%= link_to tag.name, not_pressed.blog_tag_path(slug: tag.slug), class: "np-blog-post__tag" %>
|
|
14
|
+
<% end %>
|
|
15
|
+
</div>
|
|
16
|
+
<% end %>
|
|
17
|
+
</header>
|
|
18
|
+
|
|
19
|
+
<div class="np-blog-post__content">
|
|
20
|
+
<%= render_page_content(@post) %>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<nav class="np-blog-post__nav">
|
|
24
|
+
<% if @prev_post %>
|
|
25
|
+
<div class="np-blog-post__nav-prev">
|
|
26
|
+
<%= link_to not_pressed.blog_post_path(slug: @prev_post.slug) do %>
|
|
27
|
+
<span>← Previous</span>
|
|
28
|
+
<span><%= @prev_post.title %></span>
|
|
29
|
+
<% end %>
|
|
30
|
+
</div>
|
|
31
|
+
<% end %>
|
|
32
|
+
<% if @next_post %>
|
|
33
|
+
<div class="np-blog-post__nav-next">
|
|
34
|
+
<%= link_to not_pressed.blog_post_path(slug: @next_post.slug) do %>
|
|
35
|
+
<span>Next →</span>
|
|
36
|
+
<span><%= @next_post.title %></span>
|
|
37
|
+
<% end %>
|
|
38
|
+
</div>
|
|
39
|
+
<% end %>
|
|
40
|
+
</nav>
|
|
41
|
+
</article>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<%= seo_meta_tags(@page, request) %>
|
|
7
|
+
<%= stylesheet_link_tag "not_pressed/content", media: "all" %>
|
|
8
|
+
<%= stylesheet_link_tag "not_pressed/gallery", media: "all" %>
|
|
9
|
+
<%= theme_stylesheet_tag %>
|
|
10
|
+
<%= theme_color_overrides %>
|
|
11
|
+
<%= csrf_meta_tags %>
|
|
12
|
+
<%= csp_meta_tag %>
|
|
13
|
+
<%= head_injection(@page) %>
|
|
14
|
+
</head>
|
|
15
|
+
<body class="np-page-body <%= active_theme_class %>">
|
|
16
|
+
<header class="np-theme-header">
|
|
17
|
+
<div class="np-theme-header-inner">
|
|
18
|
+
<a href="/" class="np-theme-site-name"><%= NotPressed.configuration.site_name %></a>
|
|
19
|
+
</div>
|
|
20
|
+
</header>
|
|
21
|
+
|
|
22
|
+
<main class="np-theme-main">
|
|
23
|
+
<div class="np-theme-content">
|
|
24
|
+
<%= yield %>
|
|
25
|
+
</div>
|
|
26
|
+
</main>
|
|
27
|
+
|
|
28
|
+
<footer class="np-theme-footer">
|
|
29
|
+
<div class="np-theme-footer-inner">
|
|
30
|
+
<p>© <%= Date.current.year %> <%= NotPressed.configuration.site_name %></p>
|
|
31
|
+
</div>
|
|
32
|
+
</footer>
|
|
33
|
+
<%= javascript_include_tag "not_pressed/lightbox" %>
|
|
34
|
+
<%= body_injection(@page) %>
|
|
35
|
+
</body>
|
|
36
|
+
</html>
|