panda_cms 0.5.0 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +7 -6
- data/app/controllers/panda_cms/pages_controller.rb +4 -2
- data/app/lib/panda_cms/demo_site_generator.rb +2 -18
- data/app/models/panda_cms/template.rb +31 -33
- data/app/views/panda_cms/admin/settings/index.html.erb +4 -2
- data/app/views/panda_cms/admin/settings/insta.html +6 -0
- data/lib/panda_cms/version.rb +1 -1
- metadata +137 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 66117a36fa0ee06ce08670baa4b54eae990054f9bc0c80091ca6e97a67b6ce28
|
4
|
+
data.tar.gz: a7d7c50fd4a0c65f157bde152fef22c6a632c8878f67de9c73fbeb91fa02acf5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d7f66d163bbde65c92bf600bbd21432f7083b0ff302adef3284b99ea7e233b8309f7e8a022d4b06f5dc513d0e38b795a37aac47691d97fc50ad603f8f8efb9b5
|
7
|
+
data.tar.gz: b9cbbcc92f2774f780f50e7faf0b03950a3d87b1f643b783c33bc2514e445be240a090f9b985a7600ec31253b25a79942f4a8c72cf4e7a23703fdbe765f7968a
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Panda CMS
|
2
2
|
|
3
3
|
> [!CAUTION]
|
4
|
-
> This application is being developed in public. It is not ready for production use. If you'd like to try it out (or help with documentation), please contact [@jfi](https://github.com/jfi).
|
4
|
+
> This application is being developed in public. It is not ready for production use. If you'd like to try it out (or help with documentation), please contact [@jfi](https://github.com/jfi) by emailing [bamboo@pandacms.io](mailto:bamboo@pandacms.io).
|
5
5
|
|
6
6
|
## Panda CMS is the CMS we always wanted. 🐼
|
7
7
|
|
@@ -9,8 +9,9 @@ Better websites, on Rails.
|
|
9
9
|
|
10
10
|
[Read more about the project...](https://github.com/pandacms/.github/blob/main/profile/README.md) ✨
|
11
11
|
|
12
|
-
|
12
|
+
🐼 is grown from our work at [Otaina](https://www.otaina.co.uk), a small group of freelancers. We needed something that could handle websites large and small – but where we could expand it too. We sent our first websites live in March 2024.
|
13
13
|
|
14
|
+
![Gem Version](https://img.shields.io/gem/v/panda_cms) ![Build Status](https://img.shields.io/github/actions/workflow/status/pandacms/panda_cms/ci.yml)
|
14
15
|
![GitHub Last Commit](https://img.shields.io/github/last-commit/pandacms/panda_cms) [![Ruby Code Style](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://github.com/standardrb/standard)
|
15
16
|
|
16
17
|
## Usage
|
@@ -30,9 +31,7 @@ The easiest way for you to get started is to visit http://localhost:3000/admin a
|
|
30
31
|
Add the following to `Gemfile`:
|
31
32
|
|
32
33
|
```ruby
|
33
|
-
|
34
|
-
gem "panda_cms"
|
35
|
-
end
|
34
|
+
gem "panda_cms"
|
36
35
|
```
|
37
36
|
|
38
37
|
For initial setup, run:
|
@@ -44,6 +43,8 @@ rails db:migrate
|
|
44
43
|
rails db:seed
|
45
44
|
```
|
46
45
|
|
46
|
+
You may want to check this does not re-run any of your existing seeds!
|
47
|
+
|
47
48
|
If you don't want to use GitHub to login, you'll need to configure a user provider (in `config/initializers/panda_cms.rb`), and then set your user's `admin` attribute to `true` once you've first tried to login. (And yes, there should be a better first-time setup experience than this. We're working on it!)
|
48
49
|
|
49
50
|
## Gotchas
|
@@ -51,7 +52,7 @@ If you don't want to use GitHub to login, you'll need to configure a user provid
|
|
51
52
|
This is a non-exhuastive list (there will be many more):
|
52
53
|
|
53
54
|
* To date, this has only been tested with Rails 7.1 and 7.2.
|
54
|
-
*
|
55
|
+
* There may be conflicts if you're not using Tailwind CSS on the frontend. Please report this.
|
55
56
|
* If you change your login path from `/admin` the GitHub application we supply won't work on first login, so probably don't do that until you're setup!
|
56
57
|
|
57
58
|
## Contributing
|
@@ -15,8 +15,10 @@ module PandaCms
|
|
15
15
|
path_to_find = "/" + params[:path].to_s
|
16
16
|
page = Page.find_by(path: path_to_find) || Page.find_by(path: "/404")
|
17
17
|
PandaCms::Current.page = page
|
18
|
+
layout = page&.template&.file_path
|
18
19
|
|
19
|
-
|
20
|
+
# TODO: If page is active?
|
21
|
+
if page && layout
|
20
22
|
globals = {
|
21
23
|
page: page,
|
22
24
|
title: page.title
|
@@ -35,7 +37,7 @@ module PandaCms
|
|
35
37
|
)
|
36
38
|
end
|
37
39
|
|
38
|
-
render inline: "", assigns: globals, status: :ok, layout:
|
40
|
+
render inline: "", assigns: globals, status: :ok, layout: layout
|
39
41
|
else
|
40
42
|
# This works for now, but we may want to override in future (e.g. custom 404s)
|
41
43
|
render file: "#{Rails.root}/public/404.html", layout: false, status: :not_found
|
@@ -20,26 +20,10 @@ module PandaCms
|
|
20
20
|
]
|
21
21
|
|
22
22
|
initial_templates.each do |template|
|
23
|
-
|
23
|
+
PandaCms::Template.find_or_create_by!(template)
|
24
24
|
end
|
25
25
|
|
26
|
-
|
27
|
-
initial_blocks = [
|
28
|
-
{kind: "rich_text", name: "Introduction Text", key: "introduction_text", template: @templates[:homepage]},
|
29
|
-
{kind: "rich_text", name: "Main Content", key: "main_content", template: @templates[:homepage]},
|
30
|
-
{kind: "rich_text", name: "Main Content", key: "main_content", template: @templates[:page]}
|
31
|
-
]
|
32
|
-
|
33
|
-
initial_blocks.each do |block_data|
|
34
|
-
PandaCms::Block.find_or_create_by!(block_data)
|
35
|
-
end
|
36
|
-
|
37
|
-
# Empty block contents
|
38
|
-
PandaCms::Block.find_each do |block|
|
39
|
-
block.template.pages.each do |page|
|
40
|
-
PandaCms::BlockContent.find_or_create_by!(page: page, block: block, content: "")
|
41
|
-
end
|
42
|
-
end
|
26
|
+
PandaCms::Template.generate_missing_blocks
|
43
27
|
end
|
44
28
|
|
45
29
|
#
|
@@ -27,38 +27,6 @@ module PandaCms
|
|
27
27
|
scope :ordered, -> { order(:sort_order) }
|
28
28
|
scope :available, -> { where("max_uses IS NULL OR (pages_count < max_uses)") }
|
29
29
|
|
30
|
-
private
|
31
|
-
|
32
|
-
# Custom validation method to check if the file_path is a valid layout file path
|
33
|
-
# NB: Currently only supports .html.erb templates, may want to expand in future?
|
34
|
-
# @return [void]
|
35
|
-
def validate_template_file_exists
|
36
|
-
# Remove any directory traversal attempts from the file_path
|
37
|
-
safe_file_path = file_path.to_s.gsub("../", "")
|
38
|
-
# Check if the file_path is an ERB template that exists in app/views
|
39
|
-
template_path = Rails.root.join("app", "views", "#{safe_file_path}.html.erb")
|
40
|
-
# NB: file? checks for files and excludes directories (unlike exist?)
|
41
|
-
errors.add(:file_path, "must be an existing layout file path") unless File.file?(template_path)
|
42
|
-
end
|
43
|
-
|
44
|
-
# Import templates from the filesystem into the database
|
45
|
-
# @return [void]
|
46
|
-
def self.load_from_filesystem
|
47
|
-
Rails.root.glob("app/views/layouts/**/*.html.erb").each do |file|
|
48
|
-
# Extract the file path from the Rails root
|
49
|
-
file_path = file.to_s.sub("#{Rails.root}/app/views/", "").sub(".html.erb", "")
|
50
|
-
|
51
|
-
next if file_path == "layouts/application" || file_path == "layouts/mailer"
|
52
|
-
|
53
|
-
# Find or create the template based on the file path
|
54
|
-
find_or_create_by(file_path: file_path) do |t|
|
55
|
-
t.name = file_path.sub("layouts/", "").titleize
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
private_class_method :load_from_filesystem
|
61
|
-
|
62
30
|
# Generate missing blocks for all templates
|
63
31
|
# @return [void]
|
64
32
|
def self.generate_missing_blocks
|
@@ -112,6 +80,36 @@ module PandaCms
|
|
112
80
|
end
|
113
81
|
end
|
114
82
|
|
115
|
-
|
83
|
+
private
|
84
|
+
|
85
|
+
# Custom validation method to check if the file_path is a valid layout file path
|
86
|
+
# NB: Currently only supports .html.erb templates, may want to expand in future?
|
87
|
+
# @return [void]
|
88
|
+
def validate_template_file_exists
|
89
|
+
# Remove any directory traversal attempts from the file_path
|
90
|
+
safe_file_path = file_path.to_s.gsub("../", "")
|
91
|
+
# Check if the file_path is an ERB template that exists in app/views
|
92
|
+
template_path = Rails.root.join("app", "views", "#{safe_file_path}.html.erb")
|
93
|
+
# NB: file? checks for files and excludes directories (unlike exist?)
|
94
|
+
errors.add(:file_path, "must be an existing layout file path") unless File.file?(template_path)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Import templates from the filesystem into the database
|
98
|
+
# @return [void]
|
99
|
+
def self.load_from_filesystem
|
100
|
+
Rails.root.glob("app/views/layouts/**/*.html.erb").each do |file|
|
101
|
+
# Extract the file path from the Rails root
|
102
|
+
file_path = file.to_s.sub("#{Rails.root}/app/views/", "").sub(".html.erb", "")
|
103
|
+
|
104
|
+
next if file_path == "layouts/application" || file_path == "layouts/mailer"
|
105
|
+
|
106
|
+
# Find or create the template based on the file path
|
107
|
+
find_or_create_by(file_path: file_path) do |t|
|
108
|
+
t.name = file_path.sub("layouts/", "").titleize
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
private_class_method :load_from_filesystem
|
116
114
|
end
|
117
115
|
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
<%= render PandaCms::Admin::ContainerComponent.new do |component| %>
|
2
2
|
<% component.with_heading(text: "Settings", level: 1) %>
|
3
3
|
|
4
|
-
<a href="https://api.instagram.com/oauth/authorize?client_id=1149927569456763&redirect_uri=http://localhost:3000/admin/integrations/instagram/callback&scope=user_profile,user_media">Login to Instagram</a>
|
5
|
-
|
6
4
|
<%= render PandaCms::Admin::PanelComponent.new do |panel| %>
|
7
5
|
<% panel.with_heading(text: "System Status") %>
|
8
6
|
|
@@ -12,6 +10,10 @@
|
|
12
10
|
<p class="text-base leading-loose"><i class="mr-2 text-active fa fa-check-circle"></i> <span class="font-medium">Environment:</span> <%= Rails.env.titleize %></p>
|
13
11
|
<% end %>
|
14
12
|
|
13
|
+
<%= render PandaCms::Admin::PanelComponent.new do |panel| %>
|
14
|
+
<% panel.with_heading(text: "Integrations") %>
|
15
|
+
<% end %>
|
16
|
+
|
15
17
|
<div class="text-center mt-6 space-y-2">
|
16
18
|
<p class="text-sm font-semibold">🐼 Panda CMS version: <%= PandaCms::VERSION %></p>
|
17
19
|
<p class="text-sm">© <%= Date.current.year %> Panda Software Limited. All rights reserved.</p>
|
@@ -0,0 +1,6 @@
|
|
1
|
+
|
2
|
+
<%= render PandaCms::Admin::ButtonComponent.new(
|
3
|
+
text: "Connect Instagram Feed",
|
4
|
+
link: "https://api.instagram.com/oauth/authorize?client_id=525993713271219&redirect_uri=https://localhost:3000/admin/integrations/instagram/callback&scope=user_profile,user_media&response_type=code&state=#{current_user.id}",
|
5
|
+
icon: "brands fa-instagram"
|
6
|
+
) %>
|
data/lib/panda_cms/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: panda_cms
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Panda Software Limited
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-09-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activestorage-office-previewer
|
@@ -280,16 +280,16 @@ dependencies:
|
|
280
280
|
name: rails
|
281
281
|
requirement: !ruby/object:Gem::Requirement
|
282
282
|
requirements:
|
283
|
-
- - "
|
283
|
+
- - "~>"
|
284
284
|
- !ruby/object:Gem::Version
|
285
|
-
version:
|
285
|
+
version: 7.2.1
|
286
286
|
type: :runtime
|
287
287
|
prerelease: false
|
288
288
|
version_requirements: !ruby/object:Gem::Requirement
|
289
289
|
requirements:
|
290
|
-
- - "
|
290
|
+
- - "~>"
|
291
291
|
- !ruby/object:Gem::Version
|
292
|
-
version:
|
292
|
+
version: 7.2.1
|
293
293
|
- !ruby/object:Gem::Dependency
|
294
294
|
name: redcarpet
|
295
295
|
requirement: !ruby/object:Gem::Requirement
|
@@ -500,6 +500,62 @@ dependencies:
|
|
500
500
|
- - "~>"
|
501
501
|
- !ruby/object:Gem::Version
|
502
502
|
version: '9.5'
|
503
|
+
- !ruby/object:Gem::Dependency
|
504
|
+
name: danger-reek
|
505
|
+
requirement: !ruby/object:Gem::Requirement
|
506
|
+
requirements:
|
507
|
+
- - "~>"
|
508
|
+
- !ruby/object:Gem::Version
|
509
|
+
version: '0.3'
|
510
|
+
type: :development
|
511
|
+
prerelease: false
|
512
|
+
version_requirements: !ruby/object:Gem::Requirement
|
513
|
+
requirements:
|
514
|
+
- - "~>"
|
515
|
+
- !ruby/object:Gem::Version
|
516
|
+
version: '0.3'
|
517
|
+
- !ruby/object:Gem::Dependency
|
518
|
+
name: danger-rubocop
|
519
|
+
requirement: !ruby/object:Gem::Requirement
|
520
|
+
requirements:
|
521
|
+
- - "~>"
|
522
|
+
- !ruby/object:Gem::Version
|
523
|
+
version: '0.13'
|
524
|
+
type: :development
|
525
|
+
prerelease: false
|
526
|
+
version_requirements: !ruby/object:Gem::Requirement
|
527
|
+
requirements:
|
528
|
+
- - "~>"
|
529
|
+
- !ruby/object:Gem::Version
|
530
|
+
version: '0.13'
|
531
|
+
- !ruby/object:Gem::Dependency
|
532
|
+
name: danger-simplecov_json
|
533
|
+
requirement: !ruby/object:Gem::Requirement
|
534
|
+
requirements:
|
535
|
+
- - "~>"
|
536
|
+
- !ruby/object:Gem::Version
|
537
|
+
version: '0.3'
|
538
|
+
type: :development
|
539
|
+
prerelease: false
|
540
|
+
version_requirements: !ruby/object:Gem::Requirement
|
541
|
+
requirements:
|
542
|
+
- - "~>"
|
543
|
+
- !ruby/object:Gem::Version
|
544
|
+
version: '0.3'
|
545
|
+
- !ruby/object:Gem::Dependency
|
546
|
+
name: danger-todoist
|
547
|
+
requirement: !ruby/object:Gem::Requirement
|
548
|
+
requirements:
|
549
|
+
- - "~>"
|
550
|
+
- !ruby/object:Gem::Version
|
551
|
+
version: '2.0'
|
552
|
+
type: :development
|
553
|
+
prerelease: false
|
554
|
+
version_requirements: !ruby/object:Gem::Requirement
|
555
|
+
requirements:
|
556
|
+
- - "~>"
|
557
|
+
- !ruby/object:Gem::Version
|
558
|
+
version: '2.0'
|
503
559
|
- !ruby/object:Gem::Dependency
|
504
560
|
name: erb_lint
|
505
561
|
requirement: !ruby/object:Gem::Requirement
|
@@ -588,16 +644,16 @@ dependencies:
|
|
588
644
|
name: lefthook
|
589
645
|
requirement: !ruby/object:Gem::Requirement
|
590
646
|
requirements:
|
591
|
-
- - "
|
647
|
+
- - "~>"
|
592
648
|
- !ruby/object:Gem::Version
|
593
|
-
version: '
|
649
|
+
version: '1.7'
|
594
650
|
type: :development
|
595
651
|
prerelease: false
|
596
652
|
version_requirements: !ruby/object:Gem::Requirement
|
597
653
|
requirements:
|
598
|
-
- - "
|
654
|
+
- - "~>"
|
599
655
|
- !ruby/object:Gem::Version
|
600
|
-
version: '
|
656
|
+
version: '1.7'
|
601
657
|
- !ruby/object:Gem::Dependency
|
602
658
|
name: puma
|
603
659
|
requirement: !ruby/object:Gem::Requirement
|
@@ -716,6 +772,62 @@ dependencies:
|
|
716
772
|
- - "~>"
|
717
773
|
- !ruby/object:Gem::Version
|
718
774
|
version: '0.22'
|
775
|
+
- !ruby/object:Gem::Dependency
|
776
|
+
name: simplecov-json
|
777
|
+
requirement: !ruby/object:Gem::Requirement
|
778
|
+
requirements:
|
779
|
+
- - "~>"
|
780
|
+
- !ruby/object:Gem::Version
|
781
|
+
version: '0.2'
|
782
|
+
type: :development
|
783
|
+
prerelease: false
|
784
|
+
version_requirements: !ruby/object:Gem::Requirement
|
785
|
+
requirements:
|
786
|
+
- - "~>"
|
787
|
+
- !ruby/object:Gem::Version
|
788
|
+
version: '0.2'
|
789
|
+
- !ruby/object:Gem::Dependency
|
790
|
+
name: simplecov_json_formatter
|
791
|
+
requirement: !ruby/object:Gem::Requirement
|
792
|
+
requirements:
|
793
|
+
- - "~>"
|
794
|
+
- !ruby/object:Gem::Version
|
795
|
+
version: '0.1'
|
796
|
+
type: :development
|
797
|
+
prerelease: false
|
798
|
+
version_requirements: !ruby/object:Gem::Requirement
|
799
|
+
requirements:
|
800
|
+
- - "~>"
|
801
|
+
- !ruby/object:Gem::Version
|
802
|
+
version: '0.1'
|
803
|
+
- !ruby/object:Gem::Dependency
|
804
|
+
name: simplecov-lcov
|
805
|
+
requirement: !ruby/object:Gem::Requirement
|
806
|
+
requirements:
|
807
|
+
- - "~>"
|
808
|
+
- !ruby/object:Gem::Version
|
809
|
+
version: '0.8'
|
810
|
+
type: :development
|
811
|
+
prerelease: false
|
812
|
+
version_requirements: !ruby/object:Gem::Requirement
|
813
|
+
requirements:
|
814
|
+
- - "~>"
|
815
|
+
- !ruby/object:Gem::Version
|
816
|
+
version: '0.8'
|
817
|
+
- !ruby/object:Gem::Dependency
|
818
|
+
name: simplecov_lcov_formatter
|
819
|
+
requirement: !ruby/object:Gem::Requirement
|
820
|
+
requirements:
|
821
|
+
- - "~>"
|
822
|
+
- !ruby/object:Gem::Version
|
823
|
+
version: '0.9'
|
824
|
+
type: :development
|
825
|
+
prerelease: false
|
826
|
+
version_requirements: !ruby/object:Gem::Requirement
|
827
|
+
requirements:
|
828
|
+
- - "~>"
|
829
|
+
- !ruby/object:Gem::Version
|
830
|
+
version: '0.9'
|
719
831
|
- !ruby/object:Gem::Dependency
|
720
832
|
name: solargraph
|
721
833
|
requirement: !ruby/object:Gem::Requirement
|
@@ -792,6 +904,20 @@ dependencies:
|
|
792
904
|
- - "~>"
|
793
905
|
- !ruby/object:Gem::Version
|
794
906
|
version: '2.0'
|
907
|
+
- !ruby/object:Gem::Dependency
|
908
|
+
name: undercover
|
909
|
+
requirement: !ruby/object:Gem::Requirement
|
910
|
+
requirements:
|
911
|
+
- - "~>"
|
912
|
+
- !ruby/object:Gem::Version
|
913
|
+
version: '0.5'
|
914
|
+
type: :development
|
915
|
+
prerelease: false
|
916
|
+
version_requirements: !ruby/object:Gem::Requirement
|
917
|
+
requirements:
|
918
|
+
- - "~>"
|
919
|
+
- !ruby/object:Gem::Version
|
920
|
+
version: '0.5'
|
795
921
|
- !ruby/object:Gem::Dependency
|
796
922
|
name: yard-activerecord
|
797
923
|
requirement: !ruby/object:Gem::Requirement
|
@@ -925,6 +1051,7 @@ files:
|
|
925
1051
|
- app/views/panda_cms/admin/sessions/new.html.erb
|
926
1052
|
- app/views/panda_cms/admin/settings/bulk_editor/new.html.erb
|
927
1053
|
- app/views/panda_cms/admin/settings/index.html.erb
|
1054
|
+
- app/views/panda_cms/admin/settings/insta.html
|
928
1055
|
- app/views/panda_cms/admin/shared/_breadcrumbs.html.erb
|
929
1056
|
- app/views/panda_cms/admin/shared/_flash.html.erb
|
930
1057
|
- app/views/panda_cms/admin/shared/_sidebar.html.erb
|