robin_cms 0.1.4 → 0.1.6
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 +4 -4
- data/README.md +36 -108
- data/lib/robin_cms/cms.rb +3 -10
- data/lib/robin_cms/collection_library.rb +1 -1
- data/lib/robin_cms/configuration-schema.json +3 -1
- data/lib/robin_cms/configuration.rb +8 -2
- data/lib/robin_cms/data_library.rb +1 -1
- data/lib/robin_cms/item.rb +11 -6
- data/lib/robin_cms/library.rb +13 -24
- data/lib/robin_cms/version.rb +1 -1
- data/lib/robin_cms/views/field_label.erb +9 -0
- data/lib/robin_cms/views/hidden_field.erb +1 -1
- data/lib/robin_cms/views/image_field.erb +5 -3
- data/lib/robin_cms/views/input_field.erb +2 -2
- data/lib/robin_cms/views/library.erb +5 -5
- data/lib/robin_cms/views/library_actions.erb +1 -1
- data/lib/robin_cms/views/library_item.erb +2 -1
- data/lib/robin_cms/views/richtext_field.erb +2 -2
- data/lib/robin_cms/views/select_field.erb +3 -3
- data/lib/robin_cms/views/stylesheet.css.erb +17 -14
- metadata +7 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6a9634aa2592fdf851123491cc53c9b1b347b6e6ca3f7f37d4adbd9e0fb494c7
|
|
4
|
+
data.tar.gz: 3885036d121802207eb4ae9cf80c372211ee199f60fa30c7e11f5b916af5c570
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f38e98b366edb3294b56e2b97c80819149163020d41dd565e893ec3d4d8c84f2332f108de62858a9d55bf135176bf8f042ee28980bd1eb6f6d6ddaf7d330f210
|
|
7
|
+
data.tar.gz: 29d90d7896c8366dbe5373bdd89193d4dcd336577cd8c517d2b5b5082b1aa65ffef18c0b733b5387bb9bf53405c8fcf77b8afdb700e1a682c98bc37ae1c51540
|
data/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
> This software is currently in beta. There may be bugs and breaking changes.
|
|
5
5
|
> If you find a bug, I'd love to hear about it.
|
|
6
6
|
|
|
7
|
-

|
|
7
|
+

|
|
8
8
|
|
|
9
9
|
Robin CMS is a minimalist flat-file CMS built with Ruby and Sinatra. It is
|
|
10
10
|
designed to be used by developers for creating custom built websites where the
|
|
@@ -61,125 +61,53 @@ that are commonly found in CMS software have been omitted.
|
|
|
61
61
|
content. You can however add richtext fields to your content models (see
|
|
62
62
|
example below).
|
|
63
63
|
|
|
64
|
-
## Installation
|
|
65
|
-
|
|
66
|
-
Just the usual incantation:
|
|
67
|
-
|
|
68
|
-
```sh
|
|
69
|
-
gem install robin_cms
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
## Configuring
|
|
73
|
-
|
|
74
|
-
You can define your content model in a `_cms.yml` file like this:
|
|
75
|
-
|
|
76
|
-
```yml
|
|
77
|
-
url: https://example.com
|
|
78
|
-
title: Example
|
|
79
|
-
libraries:
|
|
80
|
-
- id: poem
|
|
81
|
-
type: collection
|
|
82
|
-
label: Poem
|
|
83
|
-
location: poems
|
|
84
|
-
filetype: html
|
|
85
|
-
fields:
|
|
86
|
-
- { label: Title, id: title, type: input }
|
|
87
|
-
- { label: Author, id: author_name, type: input }
|
|
88
|
-
- { label: Content, id: content, type: richtext }
|
|
89
|
-
- id: book
|
|
90
|
-
type: data
|
|
91
|
-
label: Book
|
|
92
|
-
location: books
|
|
93
|
-
filetype: yml
|
|
94
|
-
fields:
|
|
95
|
-
- { label: Title, id: title, type: input }
|
|
96
|
-
- { label: Author, id: author_name, type: input }
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
The admin username and password needs to be set in a `.htpasswd` file in the
|
|
100
|
-
root directory of the project. Obviously make sure you `.gitignore` that file.
|
|
101
|
-
Also make sure your static site generator is ignoring it because you don't want
|
|
102
|
-
it in your public directory! Each line of the `.htpasswd` file should follow
|
|
103
|
-
the format `<username>:<password>`, but note that only a single
|
|
104
|
-
username/password is supported for now. The password needs to be encrypted with
|
|
105
|
-
bcrypt. You can do this in Ruby with the `bcrypt` gem:
|
|
106
|
-
|
|
107
|
-
```sh
|
|
108
|
-
ruby -r bcrypt -e "puts BCrypt::Password.create('mypassword')"
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
Another thing to note is that if no `.htpasswd` file is found, it will
|
|
112
|
-
automatically create one with username "admin" and password "admin". This lets
|
|
113
|
-
you play around with it locally without configuring a password. So make sure
|
|
114
|
-
you create a `.htpasswd` file before running it in production!
|
|
115
|
-
|
|
116
|
-
You'll also need to expose a `SESSION_SECRET` environment variable. If you
|
|
117
|
-
don't, it will create one for you, but it creates a new secret each time
|
|
118
|
-
the server starts, meaning you will have to log in again whenever you restart
|
|
119
|
-
the server. It is recommended to create one via Ruby's SecureRandom package.
|
|
120
|
-
|
|
121
|
-
```sh
|
|
122
|
-
ruby -r securerandom -e "puts SecureRandom.hex(64)"
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
See the [examples](./examples) folder for a full example. I haven't written any
|
|
126
|
-
documentation yet, but the example `_cms.yml` file is thoroughly commented to
|
|
127
|
-
explain each of the fields.
|
|
128
|
-
|
|
129
64
|
## Usage
|
|
130
65
|
|
|
131
|
-
|
|
132
|
-
it directly as a CMS for any Static Site Generator with the following
|
|
133
|
-
`config.ru`:
|
|
134
|
-
|
|
135
|
-
```ruby
|
|
136
|
-
require 'robin_cms'
|
|
137
|
-
map "/admin" { run RobinCMS::CMS.new }
|
|
138
|
-
```
|
|
66
|
+
Robin CMS is packaged as a Ruby gem, so installation is as simple as
|
|
139
67
|
|
|
140
|
-
|
|
141
|
-
in your browser.
|
|
68
|
+
gem install robin_cms
|
|
142
69
|
|
|
143
|
-
|
|
70
|
+
It's possible to use the CMS in a few different ways. You can use it as a
|
|
71
|
+
standalone CMS for any Static Site Generator, you can embed it in a dynamic
|
|
72
|
+
Sinatra app, or you can use it as a Jekyll plugin. If you're already using
|
|
73
|
+
Jekyll as your SSG, this is the simplest approach.
|
|
144
74
|
|
|
145
|
-
|
|
146
|
-
require 'robin_cms'
|
|
147
|
-
require 'sinatra'
|
|
75
|
+
See the [documentation](./docs/index.adoc) for further information on usage.
|
|
148
76
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
get '/' do
|
|
152
|
-
'Hello, world!'
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
run Sinatra::Application.new
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
Yet another option is to use it as a [Jekyll](https://jekyllrb.com/) plugin. To
|
|
159
|
-
do this, you just need to pop `robin_cms` in the `:jekyll_plugins` group of
|
|
160
|
-
your `Gemfile` like so:
|
|
161
|
-
|
|
162
|
-
```
|
|
163
|
-
gem "jekyll"
|
|
164
|
-
|
|
165
|
-
group :jekyll_plugins do
|
|
166
|
-
gem "robin_cms"
|
|
167
|
-
end
|
|
168
|
-
```
|
|
77
|
+
## Configuring
|
|
169
78
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
79
|
+
Your content model is defined in a single YAML file. It acts as a sort of
|
|
80
|
+
schema for your content. An example YAML file looks like this:
|
|
81
|
+
|
|
82
|
+
url: https://example.com
|
|
83
|
+
title: Example
|
|
84
|
+
libraries:
|
|
85
|
+
- id: poem
|
|
86
|
+
type: collection
|
|
87
|
+
label: Poem
|
|
88
|
+
location: poems
|
|
89
|
+
filetype: html
|
|
90
|
+
fields:
|
|
91
|
+
- { label: Title, id: title, type: input }
|
|
92
|
+
- { label: Author, id: author_name, type: input }
|
|
93
|
+
- { label: Content, id: content, type: richtext }
|
|
94
|
+
- id: book
|
|
95
|
+
type: data
|
|
96
|
+
label: Book
|
|
97
|
+
location: books
|
|
98
|
+
filetype: yml
|
|
99
|
+
fields:
|
|
100
|
+
- { label: Title, id: title, type: input }
|
|
101
|
+
- { label: Author, id: author_name, type: input }
|
|
102
|
+
|
|
103
|
+
See the [docs](./docs/index.adoc) for more details on configuration. You can
|
|
104
|
+
also find some examples [here](./examples).
|
|
175
105
|
|
|
176
106
|
## Testing
|
|
177
107
|
|
|
178
108
|
Unit test are written in RSpec. To run them:
|
|
179
109
|
|
|
180
|
-
|
|
181
|
-
rspec
|
|
182
|
-
```
|
|
110
|
+
rake test
|
|
183
111
|
|
|
184
112
|
## Roadmap
|
|
185
113
|
|
data/lib/robin_cms/cms.rb
CHANGED
|
@@ -18,25 +18,18 @@ module RobinCMS
|
|
|
18
18
|
set :session_secret, ENV.fetch("SESSION_SECRET", SecureRandom.hex(64))
|
|
19
19
|
|
|
20
20
|
before do
|
|
21
|
-
if %w[/login /logout].include?(request.path_info)
|
|
22
|
-
pass
|
|
23
|
-
end
|
|
21
|
+
pass if %w[/login /logout].include?(request.path_info)
|
|
24
22
|
|
|
25
23
|
redirect to("/login") unless session[:auth_user]
|
|
26
24
|
end
|
|
27
25
|
|
|
28
26
|
before /\/libraries\/(.*).*/ do
|
|
29
27
|
kind = params[:captures].first.split("/").first
|
|
30
|
-
library_schema = @config.
|
|
28
|
+
library_schema = @config.get_schema(kind)
|
|
31
29
|
|
|
32
30
|
halt 404 unless library_schema
|
|
33
31
|
|
|
34
|
-
@library =
|
|
35
|
-
when "collection"
|
|
36
|
-
CollectionLibrary.new(library_schema)
|
|
37
|
-
when "data"
|
|
38
|
-
DataLibrary.new(library_schema)
|
|
39
|
-
end
|
|
32
|
+
@library = Library.new(library_schema)
|
|
40
33
|
end
|
|
41
34
|
|
|
42
35
|
after do
|
|
@@ -69,6 +69,7 @@
|
|
|
69
69
|
"options": { "$ref": "#/$defs/options_schema" },
|
|
70
70
|
"dimensions": { "$ref": "#/$defs/image_dimensions_schema" },
|
|
71
71
|
"filetype": { "$ref": "#/$defs/image_filetype_schema" },
|
|
72
|
+
"description": { "type": "string" },
|
|
72
73
|
"order": { "type": "number" }
|
|
73
74
|
}
|
|
74
75
|
}
|
|
@@ -108,7 +109,8 @@
|
|
|
108
109
|
"readonly": { "type": "boolean" },
|
|
109
110
|
"options": { "$ref": "#/$defs/options_schema" },
|
|
110
111
|
"dimensions": { "$ref": "#/$defs/image_dimensions_schema" },
|
|
111
|
-
"filetype": { "$ref": "#/$defs/image_filetype_schema" }
|
|
112
|
+
"filetype": { "$ref": "#/$defs/image_filetype_schema" },
|
|
113
|
+
"description": { "type": "string" }
|
|
112
114
|
}
|
|
113
115
|
}
|
|
114
116
|
}
|
|
@@ -42,6 +42,7 @@ module RobinCMS
|
|
|
42
42
|
id: "title",
|
|
43
43
|
type: "text",
|
|
44
44
|
required: true,
|
|
45
|
+
description: "Provide a short, descriptive title.",
|
|
45
46
|
order: 1
|
|
46
47
|
}, {
|
|
47
48
|
label: "Published date",
|
|
@@ -65,6 +66,9 @@ module RobinCMS
|
|
|
65
66
|
label: "Published",
|
|
66
67
|
value: true
|
|
67
68
|
}],
|
|
69
|
+
description: "Set this to draft if you're not ready to publish this item
|
|
70
|
+
just yet. Draft items won't appear on your website, even after clicking
|
|
71
|
+
'Publish site'.",
|
|
68
72
|
order: 2
|
|
69
73
|
}].freeze
|
|
70
74
|
|
|
@@ -74,7 +78,9 @@ module RobinCMS
|
|
|
74
78
|
}, {
|
|
75
79
|
id: "image_alt",
|
|
76
80
|
type: "text",
|
|
77
|
-
label: "Alt text"
|
|
81
|
+
label: "Alt text",
|
|
82
|
+
description: "Provide a descriptive and concise description of your
|
|
83
|
+
image. This helps to improve the accessibility of your website."
|
|
78
84
|
}].freeze
|
|
79
85
|
|
|
80
86
|
def self.parse(config_file: "_cms.yml", jekyll_plugin: false)
|
|
@@ -101,7 +107,7 @@ module RobinCMS
|
|
|
101
107
|
hash.each_with_object(new) { |(k, v), h| h[k] = v }
|
|
102
108
|
end
|
|
103
109
|
|
|
104
|
-
def
|
|
110
|
+
def get_schema(kind)
|
|
105
111
|
self[:libraries].find { |library| library[:id] == kind }
|
|
106
112
|
end
|
|
107
113
|
|
data/lib/robin_cms/item.rb
CHANGED
|
@@ -2,20 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
module RobinCMS
|
|
4
4
|
class Item
|
|
5
|
-
attr_reader :id, :attributes
|
|
5
|
+
attr_reader :id, :attributes, :schema
|
|
6
6
|
|
|
7
7
|
DATETIME_FORMAT = "%Y-%m-%d"
|
|
8
8
|
|
|
9
9
|
# The keys which we don't want to serialize.
|
|
10
10
|
FRONTMATTER_IGNORE_KEYS = [:id, :content, :image, :captures].freeze
|
|
11
11
|
|
|
12
|
-
def initialize(id, attrs = {}, **
|
|
12
|
+
def initialize(id, attrs = {}, **schema)
|
|
13
13
|
if !attrs.empty? && !attrs.has_key?(:title)
|
|
14
14
|
raise TypeError, "Missing required field `title'"
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
@id = id
|
|
18
|
-
@
|
|
18
|
+
@schema = schema
|
|
19
19
|
|
|
20
20
|
# Be sure to use the setter here so the keys get converted to symbols.
|
|
21
21
|
self.attributes = attrs
|
|
@@ -71,9 +71,9 @@ module RobinCMS
|
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
def display_name
|
|
74
|
-
return @attributes[:title] unless @
|
|
74
|
+
return @attributes[:title] unless @schema[:display_name_pattern]
|
|
75
75
|
|
|
76
|
-
@
|
|
76
|
+
@schema[:display_name_pattern].clone.tap do |name|
|
|
77
77
|
@attributes.each { |key, value| name.gsub!(":#{key}", value) }
|
|
78
78
|
end
|
|
79
79
|
end
|
|
@@ -96,9 +96,14 @@ module RobinCMS
|
|
|
96
96
|
frontmatter.to_h.transform_keys(&:to_s)
|
|
97
97
|
end
|
|
98
98
|
|
|
99
|
-
def field_value_or_default(
|
|
99
|
+
def field_value_or_default(field_id)
|
|
100
|
+
field = @schema[:fields].find { |f| f[:id] == field_id }
|
|
100
101
|
value = @attributes[field[:id].to_sym] || field[:default]
|
|
101
102
|
value.to_s
|
|
102
103
|
end
|
|
104
|
+
|
|
105
|
+
def can_delete?
|
|
106
|
+
@id && @schema[:can_delete]
|
|
107
|
+
end
|
|
103
108
|
end
|
|
104
109
|
end
|
data/lib/robin_cms/library.rb
CHANGED
|
@@ -8,38 +8,27 @@ module RobinCMS
|
|
|
8
8
|
|
|
9
9
|
attr_reader :schema
|
|
10
10
|
|
|
11
|
+
def self.of_kind(kind, **opts)
|
|
12
|
+
config = Configuration.parse(**opts)
|
|
13
|
+
schema = config.get_schema(kind)
|
|
14
|
+
new(schema)
|
|
15
|
+
end
|
|
16
|
+
|
|
11
17
|
def initialize(schema)
|
|
12
18
|
@schema = schema.freeze
|
|
19
|
+
|
|
20
|
+
case schema[:type]
|
|
21
|
+
when "collection"
|
|
22
|
+
extend CollectionLibrary
|
|
23
|
+
when "data"
|
|
24
|
+
extend DataLibrary
|
|
25
|
+
end
|
|
13
26
|
end
|
|
14
27
|
|
|
15
28
|
def blank
|
|
16
29
|
Item.new(nil, **@schema)
|
|
17
30
|
end
|
|
18
31
|
|
|
19
|
-
def create(attributes)
|
|
20
|
-
raise NotImplementedError
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def find_one(id)
|
|
24
|
-
raise NotImplementedError
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def all
|
|
28
|
-
raise NotImplementedError
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# Writes the specified item to disk.
|
|
32
|
-
#
|
|
33
|
-
# Returns the path where the item was written.
|
|
34
|
-
def write(item)
|
|
35
|
-
raise NotImplementedError
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# Delete the item specified by +id+.
|
|
39
|
-
def delete(id)
|
|
40
|
-
raise NotImplementedError
|
|
41
|
-
end
|
|
42
|
-
|
|
43
32
|
def create_static(filename, tempfile)
|
|
44
33
|
path = File.join(@schema[:static_location], File.basename(make_slug(filename)))
|
|
45
34
|
FileUtils.mkdir_p(File.dirname(path))
|
data/lib/robin_cms/version.rb
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
<%= erb :field_label, locals: { field: field } %>
|
|
2
2
|
<%#
|
|
3
3
|
There is a bug here where if you upload a different image with the
|
|
4
4
|
same name, it shows the old image due to caching. This is a very
|
|
5
5
|
low priority because a) the user should be naming things in a
|
|
6
6
|
reasonable way and b) you can always just do a hard refresh.
|
|
7
|
+
|
|
8
|
+
Also required does nothing here as we're not populating the field with any
|
|
9
|
+
initial values. This one probably needs to be fixed.
|
|
7
10
|
%>
|
|
8
11
|
<img
|
|
9
12
|
id="image-preview"
|
|
@@ -15,6 +18,5 @@
|
|
|
15
18
|
id="<%= safe_id('image', 'field') %>"
|
|
16
19
|
type="file"
|
|
17
20
|
name="image"
|
|
18
|
-
accept="image/png,
|
|
19
|
-
<% if field[:required] %>required<% end %>
|
|
21
|
+
accept="image/png,image/jpeg"
|
|
20
22
|
/>
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
<%= erb :field_label, locals: { field: field } %>
|
|
2
2
|
<input
|
|
3
3
|
id="<%= safe_id(field[:id], 'field') %>"
|
|
4
4
|
type="<%= field[:type] %>"
|
|
5
5
|
name="<%= field[:id] %>"
|
|
6
|
-
value="<%= @item.field_value_or_default(field) %>"
|
|
6
|
+
value="<%= @item.field_value_or_default(field[:id]) %>"
|
|
7
7
|
<% if field[:required] %>required<% end %>
|
|
8
8
|
<% if field[:readonly] %>readonly<% end %>
|
|
9
9
|
/>
|
|
@@ -28,12 +28,12 @@
|
|
|
28
28
|
<table>
|
|
29
29
|
<thead>
|
|
30
30
|
<tr>
|
|
31
|
-
<th
|
|
31
|
+
<th>Name</th>
|
|
32
32
|
<% if @library.drafts_enabled? %>
|
|
33
33
|
<th>Status</th>
|
|
34
34
|
<% end %>
|
|
35
|
-
<th>Created</th>
|
|
36
|
-
<th>Last updated</th>
|
|
35
|
+
<th class="date">Created</th>
|
|
36
|
+
<th class="date">Last updated</th>
|
|
37
37
|
</tr>
|
|
38
38
|
</thead>
|
|
39
39
|
<tbody>
|
|
@@ -53,12 +53,12 @@
|
|
|
53
53
|
</a>
|
|
54
54
|
</td>
|
|
55
55
|
<% end %>
|
|
56
|
-
<td>
|
|
56
|
+
<td class="date">
|
|
57
57
|
<a href='<%= url("/libraries/#{@library.kind}/item/#{item.id}") %>'>
|
|
58
58
|
<%= item.created_at.strftime("%b %d, %Y") %>
|
|
59
59
|
</a>
|
|
60
60
|
</td>
|
|
61
|
-
<td>
|
|
61
|
+
<td class="date">
|
|
62
62
|
<a href='<%= url("/libraries/#{@library.kind}/item/#{item.id}") %>'>
|
|
63
63
|
<%= item.updated_at.strftime("%b %d, %Y") %>
|
|
64
64
|
</a>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<span class="controls">
|
|
2
2
|
<a href='<%= url("/libraries/#{@library.kind}") %>'>Back</a>
|
|
3
|
-
<button type="submit">Save</button>
|
|
3
|
+
<button form="<%= safe_id(@item.id, 'edit_item') %>" type="submit">Save</button>
|
|
4
4
|
<% if has_delete %>
|
|
5
5
|
<%= erb :delete_dialog %>
|
|
6
6
|
<% end %>
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
<h2>
|
|
3
3
|
<% if @item.id %>Edit<% else %>New<% end %> <%= @library[:label_singular].downcase %>
|
|
4
4
|
</h2>
|
|
5
|
-
<%= erb :library_actions, locals: { has_delete: @
|
|
5
|
+
<%= erb :library_actions, locals: { has_delete: @item.can_delete? } %>
|
|
6
6
|
</header>
|
|
7
7
|
<form
|
|
8
|
+
id="<%= safe_id(@item.id, 'edit_item') %>"
|
|
8
9
|
class="card"
|
|
9
10
|
<% if @item.id %>
|
|
10
11
|
action='<%= url("/libraries/#{@library.kind}/item/#{@item.id}") %>'
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<link rel="stylesheet" type="text/css" href="https://unpkg.com/trix@2.0.8/dist/trix.css">
|
|
2
2
|
<script type="text/javascript" src="https://unpkg.com/trix@2.0.8/dist/trix.umd.min.js"></script>
|
|
3
|
-
|
|
3
|
+
<%= erb :field_label, locals: { field: field } %>
|
|
4
4
|
<input
|
|
5
5
|
id="richtext-content"
|
|
6
6
|
type="hidden"
|
|
7
7
|
name="<%= field[:id] %>"
|
|
8
|
-
value="<%= @item.field_value_or_default(field) %>"
|
|
8
|
+
value="<%= @item.field_value_or_default(field[:id]) %>"
|
|
9
9
|
>
|
|
10
10
|
<trix-editor input="richtext-content"></trix-editor>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
<%= erb :field_label, locals: { field: field } %>
|
|
2
2
|
<select
|
|
3
3
|
id="<%= safe_id(field[:id], 'field') %>"
|
|
4
4
|
name="<%= field[:id] %>"
|
|
5
|
-
value="<%= @item.field_value_or_default(field) %>"
|
|
5
|
+
value="<%= @item.field_value_or_default(field[:id]) %>"
|
|
6
6
|
>
|
|
7
7
|
<% for option in field[:options] %>
|
|
8
8
|
<option
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
selected
|
|
13
13
|
<% end %>
|
|
14
14
|
<% else %>
|
|
15
|
-
<% if option[:value].to_s == @item.field_value_or_default(field) %>
|
|
15
|
+
<% if option[:value].to_s == @item.field_value_or_default(field[:id]) %>
|
|
16
16
|
selected
|
|
17
17
|
<% end %>
|
|
18
18
|
<% end %>
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
--border-radius: 8px;
|
|
4
4
|
--bg-color: rgb(246, 246, 247);
|
|
5
5
|
--font-color: #141414;
|
|
6
|
+
--font-color-light: #44474a;
|
|
6
7
|
--link-color: rgb(71, 95, 145);
|
|
7
8
|
--accent-color: <%= @config[:accent_color] %>;
|
|
8
9
|
--accent-color-light: <%= @config[:accent_color] %>1e;
|
|
@@ -24,10 +25,6 @@
|
|
|
24
25
|
--box-shadow-input: inset rgba(0, 0, 0, 0.1) 0px 1px 0px 0px;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
test {
|
|
28
|
-
te
|
|
29
|
-
}
|
|
30
|
-
|
|
31
28
|
@media only screen and (max-width: 1250px) {
|
|
32
29
|
:root {
|
|
33
30
|
--content-left-margin: 3rem;
|
|
@@ -80,11 +77,10 @@ th {
|
|
|
80
77
|
font-weight: 500;
|
|
81
78
|
}
|
|
82
79
|
|
|
83
|
-
th,
|
|
84
|
-
td {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
text-overflow: ellipsis;
|
|
80
|
+
th.date,
|
|
81
|
+
td.date > * {
|
|
82
|
+
width: 7rem;
|
|
83
|
+
text-align: right;
|
|
88
84
|
}
|
|
89
85
|
|
|
90
86
|
td a {
|
|
@@ -153,7 +149,10 @@ tbody tr:hover td {
|
|
|
153
149
|
|
|
154
150
|
label {
|
|
155
151
|
display: block;
|
|
156
|
-
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
small {
|
|
155
|
+
color: var(--font-color-light);
|
|
157
156
|
}
|
|
158
157
|
|
|
159
158
|
input {
|
|
@@ -190,6 +189,14 @@ select {
|
|
|
190
189
|
box-shadow: var(--box-shadow-input);
|
|
191
190
|
}
|
|
192
191
|
|
|
192
|
+
input,
|
|
193
|
+
select,
|
|
194
|
+
trix-toolbar,
|
|
195
|
+
img#image-preview {
|
|
196
|
+
display: block;
|
|
197
|
+
margin-top: var(--padding-xs);
|
|
198
|
+
}
|
|
199
|
+
|
|
193
200
|
button {
|
|
194
201
|
padding: var(--padding-xxs) var(--padding-xs);
|
|
195
202
|
color: var(--accent-color);
|
|
@@ -405,10 +412,6 @@ hr {
|
|
|
405
412
|
padding: 2rem;
|
|
406
413
|
}
|
|
407
414
|
|
|
408
|
-
.grow-column {
|
|
409
|
-
width: 100%;
|
|
410
|
-
}
|
|
411
|
-
|
|
412
415
|
.image-preview {
|
|
413
416
|
width: 8rem;
|
|
414
417
|
height: 8rem;
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: robin_cms
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Aron Lebani
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-
|
|
11
|
+
date: 2025-11-03 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bcrypt
|
|
@@ -66,7 +66,7 @@ dependencies:
|
|
|
66
66
|
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
68
|
version: '2.2'
|
|
69
|
-
description:
|
|
69
|
+
description: Robin CMS is a simple, flat-file CMS for Static Site Generators.
|
|
70
70
|
email:
|
|
71
71
|
- aron@lebani.dev
|
|
72
72
|
executables: []
|
|
@@ -94,6 +94,7 @@ files:
|
|
|
94
94
|
- lib/robin_cms/views/change_password.erb
|
|
95
95
|
- lib/robin_cms/views/delete_dialog.erb
|
|
96
96
|
- lib/robin_cms/views/error.erb
|
|
97
|
+
- lib/robin_cms/views/field_label.erb
|
|
97
98
|
- lib/robin_cms/views/filter_form.erb
|
|
98
99
|
- lib/robin_cms/views/flash.erb
|
|
99
100
|
- lib/robin_cms/views/hidden_field.erb
|
|
@@ -111,11 +112,11 @@ files:
|
|
|
111
112
|
- lib/robin_cms/views/richtext_field.erb
|
|
112
113
|
- lib/robin_cms/views/select_field.erb
|
|
113
114
|
- lib/robin_cms/views/stylesheet.css.erb
|
|
114
|
-
homepage: https://
|
|
115
|
+
homepage: https://robincms.org
|
|
115
116
|
licenses:
|
|
116
117
|
- MIT
|
|
117
118
|
metadata:
|
|
118
|
-
homepage_uri: https://
|
|
119
|
+
homepage_uri: https://robincms.org
|
|
119
120
|
source_code_uri: https://codeberg.org/evencuriouser/robin_cms
|
|
120
121
|
post_install_message:
|
|
121
122
|
rdoc_options: []
|
|
@@ -135,5 +136,5 @@ requirements: []
|
|
|
135
136
|
rubygems_version: 3.5.16
|
|
136
137
|
signing_key:
|
|
137
138
|
specification_version: 4
|
|
138
|
-
summary: A
|
|
139
|
+
summary: A simple, flat-file CMS for Static Site Generators.
|
|
139
140
|
test_files: []
|