micro_cms 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/README.md +74 -0
- data/Rakefile +24 -0
- data/app/assets/config/micro_cms_manifest.js +1 -0
- data/app/assets/javascripts/micro_cms.js +51 -0
- data/app/assets/stylesheets/micro_cms/micro_cms.css +30 -0
- data/app/controllers/micro_cms/application_controller.rb +7 -0
- data/app/controllers/micro_cms/content_block_controller.rb +31 -0
- data/app/helpers/micro_cms/application_helper.rb +6 -0
- data/app/helpers/micro_cms/cms_block_helper.rb +28 -0
- data/app/models/micro_cms/application_record.rb +7 -0
- data/app/models/micro_cms/content_block.rb +26 -0
- data/app/views/micro_cms/_content_block.html.erb +19 -0
- data/config/routes.rb +5 -0
- data/db/migrate/20190923103919_create_micro_cms_content_blocks.rb +12 -0
- data/lib/micro_cms.rb +15 -0
- data/lib/micro_cms/engine.rb +25 -0
- data/lib/micro_cms/version.rb +5 -0
- data/spec/dummy/Rakefile +8 -0
- data/spec/dummy/app/assets/config/manifest.js +3 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/channels/application_cable/channel.rb +6 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +6 -0
- data/spec/dummy/app/controllers/application_controller.rb +4 -0
- data/spec/dummy/app/helpers/application_helper.rb +4 -0
- data/spec/dummy/app/javascript/packs/application.js +15 -0
- data/spec/dummy/app/jobs/application_job.rb +9 -0
- data/spec/dummy/app/mailers/application_mailer.rb +6 -0
- data/spec/dummy/app/models/application_record.rb +5 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/bin/rails +11 -0
- data/spec/dummy/bin/rake +11 -0
- data/spec/dummy/bin/rspec +8 -0
- data/spec/dummy/bin/setup +35 -0
- data/spec/dummy/bin/spring +17 -0
- data/spec/dummy/config.ru +7 -0
- data/spec/dummy/config/application.rb +31 -0
- data/spec/dummy/config/boot.rb +7 -0
- data/spec/dummy/config/cable.yml +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +7 -0
- data/spec/dummy/config/environments/development.rb +64 -0
- data/spec/dummy/config/environments/production.rb +114 -0
- data/spec/dummy/config/environments/test.rb +50 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +10 -0
- data/spec/dummy/config/initializers/assets.rb +14 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +9 -0
- data/spec/dummy/config/initializers/content_security_policy.rb +30 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +6 -0
- data/spec/dummy/config/initializers/inflections.rb +18 -0
- data/spec/dummy/config/initializers/mime_types.rb +6 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +16 -0
- data/spec/dummy/config/locales/en.yml +33 -0
- data/spec/dummy/config/puma.rb +40 -0
- data/spec/dummy/config/routes.rb +5 -0
- data/spec/dummy/config/spring.rb +8 -0
- data/spec/dummy/config/storage.yml +34 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20190923150252_create_micro_cms_content_blocks.micro_cms.rb +13 -0
- data/spec/dummy/db/schema.rb +22 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +1 -0
- data/spec/dummy/log/test.log +478 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/tmp/development_secret.txt +1 -0
- data/spec/engine/micro_cms_spec.rb +9 -0
- data/spec/examples.txt +28 -0
- data/spec/factories/micro_cms/content_blocks.rb +8 -0
- data/spec/helpers/micro_cms/cms_block_helper_spec.rb +138 -0
- data/spec/models/micro_cms/content_block_spec.rb +62 -0
- data/spec/rails_helper.rb +75 -0
- data/spec/requests/micro_cms/content_block_controller_spec.rb +57 -0
- data/spec/routing/micro_cms/content_blocks_routing_spec.rb +17 -0
- data/spec/spec_helper.rb +43 -0
- data/spec/support/shared_examples/cms_block_helper_spec_helper.rb +9 -0
- data/spec/views/micro_cms/content_block_spec.rb +25 -0
- metadata +250 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 30b5c1e55c3ca21195b3f9564e0d2b5a56b499450b349167469f345aa5a49485
|
|
4
|
+
data.tar.gz: bf95432f342ceedff1dfe24da3eeda9d41e24d7bd2874172bce099a4c836e903
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: bf74071bb121573869b82a8c90dc6f8ef13feb0fdd26394f8e53dbe66a17cf2d9b76f10bedb4b2787f073dca0828334f91e80bfeb379f66d4a9891e5c7e042bb
|
|
7
|
+
data.tar.gz: 51db9356c673799b72531e960520ae7b9c86747a41e28224ef438f2dca2fdca873fc350e424089b2caa2efb0206f864fc5659f4ba1001609100ae5920f7bcf05
|
data/README.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# MicroCms
|
|
2
|
+
Provides editable inline content blocks to modify your content on the fly.
|
|
3
|
+
|
|
4
|
+
## Dependencies
|
|
5
|
+
* [`ckeditor`](https://github.com/galetahub/ckeditor) gem.
|
|
6
|
+
* jQuery
|
|
7
|
+
|
|
8
|
+
## Usage
|
|
9
|
+
To provide an editable content block, use the `cms_block` helper method in your view, e.g.:
|
|
10
|
+
```slim
|
|
11
|
+
= cms_block 'my.unique.block.identifier'
|
|
12
|
+
h1 Default
|
|
13
|
+
p This is my default content
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
To print the content in readonly mode, use the `cms_content` helper method in your view, e.g:
|
|
17
|
+
```slim
|
|
18
|
+
= cms_content 'my.unique.block.identifier'
|
|
19
|
+
p My content if there's no content block yet
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
It's best to write an own helper method which also does authentication like
|
|
23
|
+
```ruby
|
|
24
|
+
def cms(path, &block)
|
|
25
|
+
if current_user&.write_cms?
|
|
26
|
+
cms_block(path, &block)
|
|
27
|
+
else
|
|
28
|
+
cms_content(path, &block)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
Add this line to your application's Gemfile:
|
|
35
|
+
|
|
36
|
+
```ruby
|
|
37
|
+
gem 'micro_cms'
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
And then execute:
|
|
41
|
+
```bash
|
|
42
|
+
$ bundle
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Or install it yourself as:
|
|
46
|
+
```bash
|
|
47
|
+
$ gem install micro_cms
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
In your app, run
|
|
51
|
+
```bash
|
|
52
|
+
bin/bundle exec rake micro_cms:install:migrations
|
|
53
|
+
bin/rails db:migrate
|
|
54
|
+
```
|
|
55
|
+
to copy the migrations.
|
|
56
|
+
|
|
57
|
+
Require the JavaScript (e.g. `//= require micro_cms`) and all styles (e.g. `@import 'micro_cms';'`).
|
|
58
|
+
|
|
59
|
+
Mount the engine routes in you `config/routes.rb` file:
|
|
60
|
+
```ruby
|
|
61
|
+
mount MicroCms::Engine => '/micro_cms'
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Configuration
|
|
65
|
+
`app/config/initializers/micro_cms.rb`:
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
MicroCms.configure do |config|
|
|
69
|
+
config.ckeditor_configuration_file = 'ckeditor/config.js' # Custom ckeditor config. Optional
|
|
70
|
+
end
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## License
|
|
74
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
begin
|
|
4
|
+
require 'bundler/setup'
|
|
5
|
+
rescue LoadError
|
|
6
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
require 'rdoc/task'
|
|
10
|
+
|
|
11
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
|
12
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
13
|
+
rdoc.title = 'MicroCms'
|
|
14
|
+
rdoc.options << '--line-numbers'
|
|
15
|
+
rdoc.rdoc_files.include('README.md')
|
|
16
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
APP_RAKEFILE = File.expand_path('spec/dummy/Rakefile', __dir__)
|
|
20
|
+
load 'rails/tasks/engine.rake'
|
|
21
|
+
|
|
22
|
+
load 'rails/tasks/statistics.rake'
|
|
23
|
+
|
|
24
|
+
require 'bundler/gem_tasks'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//= link_directory ../stylesheets/micro_cms .css
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
(function($) {
|
|
2
|
+
CKEDITOR.disableAutoInline = true;
|
|
3
|
+
|
|
4
|
+
var setupMicroCms = function() {
|
|
5
|
+
for (var instance in CKEDITOR.instances) {
|
|
6
|
+
if (!CKEDITOR.instances.hasOwnProperty(instance)) {
|
|
7
|
+
break;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
CKEDITOR.instances[instance].on('blur', function(event) {
|
|
11
|
+
event.editor.updateElement();
|
|
12
|
+
var element = event.editor.element.$;
|
|
13
|
+
var updateUrl = element.getAttribute('data-update-url');
|
|
14
|
+
var authorizationToken = element.getAttribute('data-authorization-token');
|
|
15
|
+
window.e = event;
|
|
16
|
+
|
|
17
|
+
var data = new FormData();
|
|
18
|
+
data.append('micro_cms_content_block[content]', event.editor.getData());
|
|
19
|
+
data.append('micro_cms_content_block[authorization_token]', authorizationToken);
|
|
20
|
+
|
|
21
|
+
function blink(className) {
|
|
22
|
+
$(element).addClass(className);
|
|
23
|
+
setTimeout(function () {
|
|
24
|
+
$(element).removeClass(className);
|
|
25
|
+
}, 1000);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
Rails.ajax({
|
|
29
|
+
type: 'PATCH',
|
|
30
|
+
url: updateUrl,
|
|
31
|
+
dataType: 'json',
|
|
32
|
+
contentType: 'multipart/form-data',
|
|
33
|
+
data: data,
|
|
34
|
+
success: function(e) {
|
|
35
|
+
blink('successful');
|
|
36
|
+
},
|
|
37
|
+
error: function(e) {
|
|
38
|
+
console.error(e);
|
|
39
|
+
blink('error');
|
|
40
|
+
},
|
|
41
|
+
})
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
window.addEventListener('load', setupMicroCms);
|
|
47
|
+
|
|
48
|
+
if ('Turbolinks' in window && Turbolinks.supported) {
|
|
49
|
+
$(document).on('turbolinks:load', setupMicroCms);
|
|
50
|
+
}
|
|
51
|
+
})(jQuery);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Place all the styles related to the matching controller here.
|
|
3
|
+
They will automatically be included in application.css.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
@keyframes blinkGreen {
|
|
7
|
+
from {
|
|
8
|
+
background: #66ff66
|
|
9
|
+
}
|
|
10
|
+
to {
|
|
11
|
+
background: transparent
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@keyframes blinkRed {
|
|
16
|
+
from {
|
|
17
|
+
background: #ff6666
|
|
18
|
+
}
|
|
19
|
+
to {
|
|
20
|
+
background: transparent
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.content-block.successful {
|
|
25
|
+
animation: 1s blinkGreen ease-in;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.content-block.error {
|
|
29
|
+
animation: 1s blinkRed ease-in;
|
|
30
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_dependency 'micro_cms/application_controller'
|
|
4
|
+
|
|
5
|
+
module MicroCms
|
|
6
|
+
class ContentBlockController < ApplicationController
|
|
7
|
+
def update
|
|
8
|
+
check_authorization_token
|
|
9
|
+
|
|
10
|
+
respond_to do |format|
|
|
11
|
+
format.js do
|
|
12
|
+
ContentBlock.find_by!(path: params[:path]).update(content: content_block_params[:content])
|
|
13
|
+
|
|
14
|
+
head :no_content
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def check_authorization_token
|
|
22
|
+
token = content_block_params[:authorization_token]
|
|
23
|
+
|
|
24
|
+
raise ActiveRecord::RecordNotFound unless token == MicroCms.authorization_token
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def content_block_params
|
|
28
|
+
params.require(:micro_cms_content_block).permit(:content, :authorization_token)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module MicroCms
|
|
4
|
+
module CmsBlockHelper
|
|
5
|
+
def cms_block(path, default = nil, &block)
|
|
6
|
+
content_block = content_block_for_path(path, default: capture_default(default, &block))
|
|
7
|
+
|
|
8
|
+
render partial: 'micro_cms/content_block', locals: { content_block: content_block }
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def cms_content(path, default = nil, &block)
|
|
12
|
+
content_block = content_block_for_path(path, default: capture_default(default, &block))
|
|
13
|
+
|
|
14
|
+
content_tag :div, content_block.content, nil, false
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def content_block_for_path(path, default:)
|
|
20
|
+
MicroCms::ContentBlock.content_block_for_path path, content: default || ''
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def capture_default(default)
|
|
24
|
+
default = capture { yield } if block_given? && default.nil?
|
|
25
|
+
default
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module MicroCms
|
|
4
|
+
class ContentBlock < ApplicationRecord
|
|
5
|
+
validates :path, presence: true
|
|
6
|
+
validates :content, exclusion: { in: [nil] }
|
|
7
|
+
|
|
8
|
+
def self.table_name_prefix
|
|
9
|
+
'micro_cms_'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.format_path(i18n_key)
|
|
13
|
+
"#{i18n_key.parameterize}-#{I18n.locale}"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.content_block_for_path(path, content: '')
|
|
17
|
+
ContentBlock.find_or_create_by(path: format_path(path)) do |content_block|
|
|
18
|
+
content_block.content = content
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def to_param
|
|
23
|
+
path
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<div
|
|
2
|
+
class="content-block"
|
|
3
|
+
contenteditable="true"
|
|
4
|
+
id="<%= content_block.path %>"
|
|
5
|
+
data-update-url="<%= MicroCms::Engine.routes.url_helpers.content_block_path(content_block) %>"
|
|
6
|
+
data-authorization-token="<%= MicroCms.authorization_token %>"
|
|
7
|
+
>
|
|
8
|
+
<%= raw content_block.content %>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
11
|
+
<script type="text/javascript" charset="utf-8">
|
|
12
|
+
<% if MicroCms.ckeditor_configuration_file.present? %>
|
|
13
|
+
var config = { customConfig: "<%= asset_path(MicroCms.ckeditor_configuration_file) %>" };
|
|
14
|
+
<% else %>
|
|
15
|
+
var config = undefined;
|
|
16
|
+
<% end %>
|
|
17
|
+
|
|
18
|
+
CKEDITOR.inline('<%= content_block.path %>', config);
|
|
19
|
+
</script>
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class CreateMicroCmsContentBlocks < ActiveRecord::Migration[5.2]
|
|
4
|
+
def change
|
|
5
|
+
create_table :micro_cms_content_blocks do |t|
|
|
6
|
+
t.string :path, null: false
|
|
7
|
+
t.text :content, null: false, default: ''
|
|
8
|
+
|
|
9
|
+
t.timestamps
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
data/lib/micro_cms.rb
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'micro_cms/engine'
|
|
4
|
+
|
|
5
|
+
module MicroCms
|
|
6
|
+
mattr_accessor :ckeditor_configuration_file
|
|
7
|
+
@ckeditor_configuration_file = nil
|
|
8
|
+
|
|
9
|
+
mattr_accessor :authorization_token
|
|
10
|
+
@authorization_token = nil
|
|
11
|
+
|
|
12
|
+
def self.configure
|
|
13
|
+
yield self
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module MicroCms
|
|
4
|
+
class Engine < ::Rails::Engine
|
|
5
|
+
isolate_namespace MicroCms
|
|
6
|
+
|
|
7
|
+
config.generators do |generators|
|
|
8
|
+
generators.test_framework :rspec
|
|
9
|
+
generators.fixture_replacement :factory_bot
|
|
10
|
+
generators.factory_bot dir: 'spec/factories'
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
initializer 'micro_cms.include_view_helpers' do |_app|
|
|
14
|
+
ActiveSupport.on_load :action_view do
|
|
15
|
+
ActionView::Base.public_send :include, MicroCms::CmsBlockHelper
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
initializer 'micro_cms.configure_authorization_token' do |_app|
|
|
20
|
+
MicroCms.configure do |config|
|
|
21
|
+
config.authorization_token = SecureRandom.urlsafe_base64
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
data/spec/dummy/Rakefile
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
|
4
|
+
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
|
5
|
+
|
|
6
|
+
require_relative 'config/application'
|
|
7
|
+
|
|
8
|
+
Rails.application.load_tasks
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
|
3
|
+
* listed below.
|
|
4
|
+
*
|
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
|
7
|
+
*
|
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
|
11
|
+
* It is generally better to create a new file per style scope.
|
|
12
|
+
*
|
|
13
|
+
*= require_tree .
|
|
14
|
+
*= require_self
|
|
15
|
+
*/
|