plum-cms 0.1.2 → 0.2.1

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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +51 -0
  3. data/README.md +81 -3
  4. data/app/assets/builds/tailwind.css +1 -1
  5. data/app/assets/stylesheets/plum/control_panel.css +1 -1
  6. data/app/assets/tailwind/application.css +42 -0
  7. data/app/controllers/plum/api/v1/entries_controller.rb +48 -0
  8. data/app/controllers/plum/cp/assets_controller.rb +4 -1
  9. data/app/controllers/plum/cp/content_types_controller.rb +25 -2
  10. data/app/controllers/plum/cp/entries_controller.rb +119 -9
  11. data/app/controllers/plum/cp/entry_revisions_controller.rb +27 -0
  12. data/app/controllers/plum/cp/fieldsets_controller.rb +37 -0
  13. data/app/controllers/plum/cp/site_settings_controller.rb +20 -1
  14. data/app/controllers/plum/pages_controller.rb +26 -1
  15. data/app/javascript/controllers/plum/asset_collection_controller.js +18 -0
  16. data/app/javascript/controllers/plum/blueprint_controller.js +202 -25
  17. data/app/javascript/controllers/plum/conditional_fields_controller.js +43 -0
  18. data/app/javascript/controllers/plum/focal_point_controller.js +16 -0
  19. data/app/javascript/controllers/plum/structured_field_controller.js +133 -0
  20. data/app/models/plum/asset.rb +5 -1
  21. data/app/models/plum/content_type.rb +63 -1
  22. data/app/models/plum/entry.rb +225 -1
  23. data/app/models/plum/entry_revision.rb +14 -0
  24. data/app/models/plum/fieldset.rb +17 -0
  25. data/app/models/plum/site.rb +15 -0
  26. data/app/models/plum/user.rb +1 -0
  27. data/app/services/plum/entry_serializer.rb +36 -0
  28. data/app/services/plum/field_expander.rb +12 -1
  29. data/app/services/plum/field_options.rb +21 -0
  30. data/app/services/plum/field_type_registry.rb +88 -0
  31. data/app/services/plum/liquid_context.rb +7 -1
  32. data/app/services/plum/site_archive.rb +367 -0
  33. data/app/views/layouts/plum/cp.html.erb +2 -0
  34. data/app/views/plum/cp/assets/_form.html.erb +13 -1
  35. data/app/views/plum/cp/content_types/_form.html.erb +81 -24
  36. data/app/views/plum/cp/custom_fields/_input.html.erb +5 -0
  37. data/app/views/plum/cp/entries/_form.html.erb +108 -31
  38. data/app/views/plum/cp/entries/edit.html.erb +16 -0
  39. data/app/views/plum/cp/entry_revisions/index.html.erb +25 -0
  40. data/app/views/plum/cp/fieldsets/index.html.erb +30 -0
  41. data/app/views/plum/cp/site_settings/edit.html.erb +12 -0
  42. data/config/plum_routes.rb +15 -0
  43. data/db/engine_migrate/20260807130000_create_plum_entry_revisions.rb +16 -0
  44. data/db/engine_migrate/20260807140000_create_plum_fieldsets.rb +13 -0
  45. data/db/engine_migrate/20260807150000_add_focal_point_to_plum_assets.rb +6 -0
  46. data/db/engine_migrate/20260807160000_add_localization_to_plum_entries.rb +9 -0
  47. data/docs/blueprint-fields.md +55 -0
  48. data/docs/extensions.md +32 -0
  49. data/docs/portability.md +40 -0
  50. data/docs/product-principles.md +73 -0
  51. data/docs/roadmap.md +100 -0
  52. data/docs/site/homepage.md +104 -0
  53. data/docs/site/information-architecture.md +176 -0
  54. data/docs/statamic-parity.md +28 -0
  55. data/docs/vision.md +82 -0
  56. data/lib/plum/engine.rb +3 -1
  57. data/lib/plum/version.rb +1 -1
  58. data/lib/plum.rb +4 -0
  59. data/lib/tasks/plum_portability.rake +37 -0
  60. data/lib/tasks/plum_styles.rake +12 -0
  61. metadata +36 -8
data/docs/roadmap.md ADDED
@@ -0,0 +1,100 @@
1
+ # Roadmap
2
+
3
+ Plum's roadmap is organized by outcomes rather than promised dates. Priorities
4
+ move as the product is exercised in real Rails applications.
5
+
6
+ ## Shipped: Plum 0.2.0 — Authoring Foundation
7
+
8
+ Plum 0.2.0 established the practical authoring surface:
9
+
10
+ - a visual blueprint builder with 21 field types, reusable fieldsets, nested
11
+ structures, validation, field widths, sections, and conditions;
12
+ - assets with single and multiple image fields, metadata, focal points, and
13
+ responsive variants;
14
+ - relationships, taxonomies, navigation, globals, forms, and Liquid themes;
15
+ - drafts, scheduled publishing, immutable revisions, and rollback;
16
+ - localized entries, locale-aware public routes, and a live-only content API;
17
+ - registry-backed custom field types and packaged Tailwind control-panel styles.
18
+
19
+ See [the Statamic parity matrix](statamic-parity.md) for the supported surface.
20
+
21
+ ## Now: Plum 0.3.0 — Production Readiness
22
+
23
+ The 0.3.0 milestone makes Plum safe to adopt, move, recover, and operate outside
24
+ its development repository.
25
+
26
+ ### 1. Portability and recovery
27
+
28
+ - Versioned site export/import covering schemas, entries, relationships,
29
+ taxonomies, navigation, globals, forms, settings, and assets.
30
+ - Tested backup and restore commands with integrity checks and clear failure
31
+ behavior.
32
+ - A documented archive format that remains readable across compatible releases.
33
+
34
+ ### 2. Real-world installation
35
+
36
+ - Build `plumcms.org` as a standalone Rails application using the released gem.
37
+ - Test fresh external installations and 0.2.x upgrades in CI.
38
+ - Publish a production Docker contract and SQLite deployment example.
39
+ - Exercise health checks, upgrades, persistence, backup, and restore on a VM.
40
+
41
+ ### 3. Publishing and discovery
42
+
43
+ - SEO metadata, canonical URLs, redirects, XML sitemaps, and feeds.
44
+ - Document hierarchy, breadcrumbs, generated tables of contents, and site search.
45
+ - Secure, shareable preview links for draft and scheduled content.
46
+
47
+ ### 4. Editorial operations
48
+
49
+ - Asset folders, search, replacement, cropping, and richer transformations.
50
+ - Granular editorial roles, approvals, and publish permissions.
51
+ - Form spam protection and improved submission review/export workflows.
52
+
53
+ ### 5. Documentation
54
+
55
+ - Complete installation and first-page guides.
56
+ - Document every supported field and content primitive.
57
+ - Document standalone SQLite and embedded PostgreSQL operation.
58
+ - Publish configuration, troubleshooting, extension, upgrade, backup, and
59
+ restore references.
60
+
61
+ ## Next: Plum 0.4.0 — Repeatable Adoption
62
+
63
+ - A thin `plum` CLI for diagnostics, export/import, backup/restore, upgrades,
64
+ themes, and packaging.
65
+ - Starter applications for common publishing use cases.
66
+ - Theme scaffolding, validation, packaging, and distribution tools.
67
+ - A collection of high-quality open themes and blocks.
68
+ - Importers for common CMS and structured-data formats.
69
+ - Addon discovery and a documented compatibility contract.
70
+
71
+ ## Later: The Rails Content Ecosystem
72
+
73
+ - Translation-service integrations and richer localization workflows.
74
+ - Agency-oriented multisite operations and reusable project recipes.
75
+ - Community examples, case studies, talks, and contribution programs.
76
+ - Broader content APIs where real applications demonstrate the need.
77
+
78
+ ## Plum 1.0
79
+
80
+ Plum 1.0 means another Rails developer can reproduce what powers
81
+ `plumcms.org` without private knowledge or site-specific patches.
82
+
83
+ It requires:
84
+
85
+ - a published, versioned gem;
86
+ - an editable page within ten minutes of installation;
87
+ - dependable standalone and embedded installation paths;
88
+ - a documented SQLite production deployment;
89
+ - clean host authentication, authorization, and tenancy integration;
90
+ - preview, revisions, export, backup, and restore;
91
+ - complete documentation for the supported public surface;
92
+ - a tested upgrade path;
93
+ - at least one production standalone site and one production embedded use; and
94
+ - a public example application that agencies can study and adapt.
95
+
96
+ ## Not on the Near-Term Roadmap
97
+
98
+ Plum is not trying to become a general-purpose admin framework, a freeform
99
+ visual design tool, an ecommerce platform, or a hosted headless CMS. Plum's
100
+ focus is managed content that belongs inside Rails.
@@ -0,0 +1,104 @@
1
+ # Homepage Copy
2
+
3
+ ## Hero
4
+
5
+ ### Plum
6
+
7
+ **The Rails-native CMS.**
8
+
9
+ Add managed content to an existing Rails application or build a complete
10
+ content-first site—without leaving the Rails stack.
11
+
12
+ Primary action: **Get started**
13
+
14
+ Secondary action: **View on GitHub**
15
+
16
+ Supporting note: Open source. Self-hosted. SQLite and PostgreSQL.
17
+
18
+ ## One Stack, Complete Control
19
+
20
+ Plum uses the Rails application you already understand: its database, users,
21
+ authorization, jobs, mail, storage, and deployment. There is no external CMS to
22
+ synchronize and no second frontend to maintain.
23
+
24
+ ```ruby
25
+ gem "plum"
26
+ ```
27
+
28
+ ```bash
29
+ bin/rails generate plum:install --mount-path=/website
30
+ bin/rails db:migrate
31
+ ```
32
+
33
+ ## Two Ways to Use Plum
34
+
35
+ ### Add content to your application
36
+
37
+ Mount Plum in an existing Rails product. Let customers or editors manage pages,
38
+ navigation, documentation, announcements, and structured content while the host
39
+ application continues to own identity and business data.
40
+
41
+ Action: **Embed Plum**
42
+
43
+ ### Build the whole site with Plum
44
+
45
+ Start with Rails, SQLite, and a Plum theme. Ship a fast, portable content site
46
+ that can grow into a custom Rails application whenever the project demands it.
47
+
48
+ Action: **Build a Plum site**
49
+
50
+ ## Application Data Meets Editorial Content
51
+
52
+ Expose host application data safely to Plum templates without copying it into a
53
+ remote CMS.
54
+
55
+ ```ruby
56
+ Plum.configure do |config|
57
+ config.current_site_resolver = ->(_) { Current.account.plum_site }
58
+ config.current_user_resolver = ->(_) { Current.user }
59
+
60
+ config.register_content_source :products do |context|
61
+ context.owner.products.published
62
+ end
63
+ end
64
+ ```
65
+
66
+ Editors manage the story. Rails remains the source of truth for the application.
67
+
68
+ ## Familiar Rails Foundations
69
+
70
+ - Rails 8 engine
71
+ - Hotwire control panel
72
+ - Active Record content
73
+ - Active Storage assets
74
+ - Active Job notifications
75
+ - Liquid themes
76
+ - SQLite and PostgreSQL
77
+ - Host-owned authentication and authorization
78
+
79
+ ## For Independent Developers and Agencies
80
+
81
+ Package each client site as an independent Rails application with its own
82
+ SQLite database, assets, domain, and backup. Run several sites economically on
83
+ one VM with an ONCE-compatible container, and move any client without untangling
84
+ a shared CMS installation.
85
+
86
+ Action: **See the agency model**
87
+
88
+ ## Built in Public, Used for Real
89
+
90
+ This website is a Rails application powered by Plum and SQLite. The same public
91
+ engine, theme system, and deployment path are available to every Plum project.
92
+
93
+ Action: **How this site works**
94
+
95
+ ## Closing Call to Action
96
+
97
+ ### Keep content in Rails.
98
+
99
+ Give editors the tools they need without giving up the application stack you
100
+ want.
101
+
102
+ Primary action: **Read the getting-started guide**
103
+
104
+ Secondary action: **Explore the roadmap**
@@ -0,0 +1,176 @@
1
+ # plumcms.org Information Architecture
2
+
3
+ The site serves three audiences: developers adding content to an existing Rails
4
+ application, developers building a content-first site, and agencies operating
5
+ multiple client sites.
6
+
7
+ ## Primary Navigation
8
+
9
+ - Why Plum
10
+ - Use Cases
11
+ - Documentation
12
+ - Roadmap
13
+ - GitHub
14
+
15
+ The persistent primary action is **Get started**.
16
+
17
+ ## Routes
18
+
19
+ ```text
20
+ /
21
+ /why-plum
22
+ /features
23
+ /use-cases
24
+ /existing-rails-apps
25
+ /content-sites
26
+ /agencies
27
+ /docs
28
+ /getting-started
29
+ /concepts
30
+ /content-modeling
31
+ /themes
32
+ /embedding
33
+ /deployment
34
+ /reference
35
+ /roadmap
36
+ /changelog
37
+ /demo
38
+ ```
39
+
40
+ ## Homepage Story
41
+
42
+ The homepage should answer five questions in order:
43
+
44
+ 1. What is Plum?
45
+ 2. Why would a Rails developer use it instead of another CMS?
46
+ 3. Can it work in my kind of project?
47
+ 4. What does the code and editing experience look like?
48
+ 5. Can I trust and try it?
49
+
50
+ ## Documentation Structure
51
+
52
+ ### Start
53
+
54
+ - Introduction
55
+ - Installation
56
+ - Your first editable page
57
+ - Build a small content site
58
+
59
+ ### Core concepts
60
+
61
+ - Sites
62
+ - Content types and blueprints
63
+ - Entries and publishing
64
+ - Fields
65
+ - Liquid rendering
66
+
67
+ ### Content features
68
+
69
+ - Blocks
70
+ - Rich text
71
+ - Assets and images
72
+ - Relationships
73
+ - Taxonomies
74
+ - Navigation
75
+ - Globals
76
+ - Forms
77
+
78
+ ### Themes
79
+
80
+ - Theme anatomy
81
+ - Templates and layouts
82
+ - Theme manifests
83
+ - Settings
84
+ - Assets
85
+ - Blocks
86
+ - Packaging and installation
87
+
88
+ ### Embed Plum
89
+
90
+ - Mounting the engine
91
+ - Host authentication
92
+ - Authorization
93
+ - Site resolution and tenancy
94
+ - Host content sources
95
+ - Routes and URLs
96
+ - White labelling
97
+
98
+ ### Operate
99
+
100
+ - SQLite deployment
101
+ - PostgreSQL deployment
102
+ - Active Storage
103
+ - Jobs and email
104
+ - Docker and ONCE
105
+ - Backups and restore
106
+ - Upgrading
107
+
108
+ ### Reference
109
+
110
+ - Configuration
111
+ - Blueprint field contracts
112
+ - Liquid objects and filters
113
+ - Theme manifest
114
+ - Generators
115
+ - Troubleshooting
116
+
117
+ ## Content Types
118
+
119
+ ### Pages
120
+
121
+ - Title
122
+ - Slug
123
+ - Summary
124
+ - Sections (`blocks`)
125
+ - SEO title
126
+ - SEO description
127
+
128
+ ### Documentation pages
129
+
130
+ - Title
131
+ - Slug
132
+ - Section taxonomy
133
+ - Parent relationship
134
+ - Position
135
+ - Summary
136
+ - Body
137
+
138
+ ### Releases
139
+
140
+ - Version
141
+ - Published date
142
+ - Summary
143
+ - Body
144
+
145
+ ### Roadmap items
146
+
147
+ - Title
148
+ - Horizon (`now`, `next`, or `later`)
149
+ - Status
150
+ - Problem
151
+ - Intended outcome
152
+
153
+ ## Initial Blocks
154
+
155
+ - Hero
156
+ - Prose
157
+ - Code example
158
+ - Feature grid
159
+ - Use-case cards
160
+ - Steps
161
+ - Comparison
162
+ - Quote
163
+ - Call to action
164
+
165
+ Blocks should be general enough to ship as examples or reusable base blocks.
166
+ Site-specific styling belongs in the plumcms.org theme.
167
+
168
+ ## Proof the Site Must Provide
169
+
170
+ - The homepage is editable through Plum.
171
+ - Documentation is navigable and pleasant to read.
172
+ - A visitor can see real installation code immediately.
173
+ - The public roadmap distinguishes current capability from future intent.
174
+ - The application runs on Rails and SQLite in production.
175
+ - Its container, persistence, backup, and restore approach are documented.
176
+ - No private Plum features or site-specific engine patches are required.
@@ -0,0 +1,28 @@
1
+ # Statamic capability parity
2
+
3
+ This matrix tracks practical authoring parity rather than matching Statamic's
4
+ internal architecture or naming.
5
+
6
+ | Capability | Plum status | Notes |
7
+ |---|---|---|
8
+ | Blueprint field builder | Supported | Visual, nested, typed configuration |
9
+ | Reusable fieldsets | Supported | Site-scoped snapshots with collision-safe insertion |
10
+ | Field instructions/defaults/required | Supported | Client and server validation |
11
+ | Field widths and sections | Supported | Twelve-column responsive editor |
12
+ | Conditional fields | Supported | Five common operators |
13
+ | Text, rich text, numbers, dates | Supported | Bounds and modes included |
14
+ | Choice controls | Supported | Select, radio, buttons, checkboxes |
15
+ | Assets | Supported | Single/multi-image fields, metadata, focal points, variants |
16
+ | Relationships | Supported | Single/multiple, type-filtered, site-scoped |
17
+ | Structured content | Supported | Lists, groups, repeaters, blocks |
18
+ | Taxonomies | Supported | Managed terms and public archives |
19
+ | Globals and navigation | Supported | Liquid-accessible content |
20
+ | Forms | Supported | Definitions, submissions, notifications |
21
+ | Themes | Supported | Liquid packages, settings, blocks |
22
+ | Revisions and publishing workflow | Supported | Attributed snapshots, restoration, drafts, scheduling |
23
+ | Localization/multisite | Supported | Site locales, translation groups, localized URLs/API |
24
+ | Content API | Supported | Public, site-scoped, live-only JSON collections |
25
+ | Addon field types | Supported | Registry-backed editor and value pipeline |
26
+
27
+ Longer-term ecosystem work can add commercial-style addon discovery, more
28
+ workflow roles, and translation services without changing these authoring APIs.
data/docs/vision.md ADDED
@@ -0,0 +1,82 @@
1
+ # Plum's Vision
2
+
3
+ Plum is the Rails-native CMS.
4
+
5
+ It gives Rails developers a default way to add managed content to an existing
6
+ application or build a complete content-first site without introducing another
7
+ application stack.
8
+
9
+ ## Why Plum Exists
10
+
11
+ Rails is excellent at building applications, but content management is still
12
+ usually assembled from bespoke admin screens, delegated to a remote headless
13
+ CMS, or moved into a separate publishing platform. Each choice adds work or
14
+ pulls content away from the application that uses it.
15
+
16
+ Plum makes content a native part of Rails. It uses the application's database,
17
+ models, users, authorization, jobs, mail, storage, and deployment environment.
18
+ Developers keep the flexibility of Ruby and Rails. Editors get a focused,
19
+ polished place to manage content.
20
+
21
+ ## Who Plum Is For
22
+
23
+ ### Rails application teams
24
+
25
+ Mount Plum inside an existing application to manage marketing pages,
26
+ documentation, announcements, navigation, help content, and other editorial
27
+ material. Application records can be exposed safely alongside managed content
28
+ without copying them into an external CMS.
29
+
30
+ ### Independent developers and agencies
31
+
32
+ Use Plum as the foundation of a complete client site. Start with Rails, SQLite,
33
+ a Plum theme, and one deployable container. Retain the ability to add ordinary
34
+ Rails features when the project grows beyond a brochure site.
35
+
36
+ ### SaaS products
37
+
38
+ Give each account a site-scoped, white-labelled editing experience while the
39
+ host application continues to own identity, authorization, tenancy, and
40
+ business data.
41
+
42
+ ## The Promise
43
+
44
+ A developer should be able to add Plum to a Rails application and publish an
45
+ editable page in less than ten minutes.
46
+
47
+ A small content site should be able to run as one Rails application with SQLite
48
+ and persistent storage. An agency should be able to operate several independent
49
+ Plum sites on one VM as portable containers. A larger application should be
50
+ able to use PostgreSQL and embed Plum without changing its content model.
51
+
52
+ Content must remain portable. Plum should never require a hosted Plum account,
53
+ a proprietary runtime, or a second frontend application.
54
+
55
+ ## What Makes Plum Different
56
+
57
+ - It is Rails infrastructure, not a remote content service.
58
+ - It works both as a mountable engine and as the center of a standalone site.
59
+ - It lets editorial content and host application data participate in the same
60
+ rendering context.
61
+ - It follows the Rails approach: strong conventions, ordinary Ruby extension
62
+ points, and ownership of the complete application.
63
+ - It supports a low-operations SQLite path without limiting applications that
64
+ need PostgreSQL.
65
+ - It treats themes, content, assets, backups, and deployments as portable parts
66
+ of a site rather than features of a vendor account.
67
+
68
+ ## The Long-Term Goal
69
+
70
+ When a Rails developer asks, "How do I let someone edit this content?", Plum
71
+ should be the obvious answer.
72
+
73
+ Plum succeeds when it becomes normal to:
74
+
75
+ - mount Plum in a Rails product;
76
+ - start a client content site with Plum;
77
+ - publish and share Plum themes and blocks;
78
+ - run a collection of independent Plum sites economically; and
79
+ - extend content workflows with familiar Rails code.
80
+
81
+ The goal is not to reproduce every feature of every CMS. The goal is to make
82
+ content management feel like it has always belonged in Rails.
data/lib/plum/engine.rb CHANGED
@@ -8,7 +8,9 @@ module Plum
8
8
 
9
9
  initializer "plum.assets" do |app|
10
10
  app.config.assets.paths << root.join("app/assets/javascripts")
11
- app.config.assets.paths << root.join("app/javascript/controllers/plum")
11
+ # Importmap exposes these files as `plum/*`, so Propshaft must resolve
12
+ # them relative to the parent controllers directory.
13
+ app.config.assets.paths << root.join("app/javascript/controllers")
12
14
  app.config.assets.paths << root.join("vendor/javascript")
13
15
 
14
16
  lexxy_spec = Gem.loaded_specs["lexxy"]
data/lib/plum/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Plum
2
2
  module Version
3
- STRING = "0.1.2"
3
+ STRING = "0.2.1"
4
4
  end
5
5
 
6
6
  VERSION = Version::STRING
data/lib/plum.rb CHANGED
@@ -6,6 +6,10 @@ module Plum
6
6
  def self.table_name_prefix
7
7
  "plum_"
8
8
  end
9
+
10
+ def self.register_field_type(**options)
11
+ FieldTypeRegistry.register(**options)
12
+ end
9
13
  end
10
14
 
11
15
  require_relative "plum/engine" if defined?(Rails::Engine)
@@ -0,0 +1,37 @@
1
+ namespace :plum do
2
+ namespace :site do
3
+ desc "Export a complete Plum site archive (SITE_ID or first site; ARCHIVE required)"
4
+ task export: :environment do
5
+ path = ENV.fetch("ARCHIVE") { abort "ARCHIVE is required" }
6
+ site = ENV["SITE_ID"].present? ? Plum::Site.find(ENV["SITE_ID"]) : Plum::Site.first
7
+ abort "No Plum site exists" unless site
8
+
9
+ archive = Plum::SiteArchive.dump(site: site, path: path)
10
+ puts "Exported #{site.name} to #{archive}"
11
+ end
12
+
13
+ desc "Import a Plum site archive as a new site (ARCHIVE required; NAME and DOMAIN optional)"
14
+ task import: :environment do
15
+ path = ENV.fetch("ARCHIVE") { abort "ARCHIVE is required" }
16
+ site = Plum::SiteArchive.load(path: path, name: ENV["NAME"], domain: ENV["DOMAIN"])
17
+ puts "Imported #{site.name} as site #{site.id}"
18
+ end
19
+ end
20
+
21
+ namespace :backup do
22
+ desc "Create a timestamped Plum site backup (SITE_ID optional; DIRECTORY defaults to backups/plum)"
23
+ task create: :environment do
24
+ site = ENV["SITE_ID"].present? ? Plum::Site.find(ENV["SITE_ID"]) : Plum::Site.first
25
+ abort "No Plum site exists" unless site
26
+ directory = Rails.root.join(ENV.fetch("DIRECTORY", "backups/plum"))
27
+ filename = "plum-site-#{site.id}-#{Time.current.utc.strftime('%Y%m%d%H%M%S')}.plum.zip"
28
+ archive = Plum::SiteArchive.dump(site: site, path: directory.join(filename))
29
+ puts "Backed up #{site.name} to #{archive}"
30
+ end
31
+
32
+ desc "Restore a Plum backup as a new site (ARCHIVE required; NAME and DOMAIN optional)"
33
+ task restore: :environment do
34
+ Rake::Task["plum:site:import"].invoke
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,12 @@
1
+ require "fileutils"
2
+
3
+ namespace :plum do
4
+ desc "Build Tailwind and copy the result into Plum's packaged stylesheet"
5
+ task build_styles: :environment do
6
+ system(Rails.root.join("bin/rails").to_s, "tailwindcss:build", exception: true)
7
+ source = Rails.root.join("app/assets/builds/tailwind.css")
8
+ destination = Rails.root.join("app/assets/stylesheets/plum/control_panel.css")
9
+ FileUtils.cp(source, destination)
10
+ puts "Packaged #{destination.relative_path_from(Rails.root)}"
11
+ end
12
+ end