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.
Files changed (85) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +74 -0
  3. data/Rakefile +24 -0
  4. data/app/assets/config/micro_cms_manifest.js +1 -0
  5. data/app/assets/javascripts/micro_cms.js +51 -0
  6. data/app/assets/stylesheets/micro_cms/micro_cms.css +30 -0
  7. data/app/controllers/micro_cms/application_controller.rb +7 -0
  8. data/app/controllers/micro_cms/content_block_controller.rb +31 -0
  9. data/app/helpers/micro_cms/application_helper.rb +6 -0
  10. data/app/helpers/micro_cms/cms_block_helper.rb +28 -0
  11. data/app/models/micro_cms/application_record.rb +7 -0
  12. data/app/models/micro_cms/content_block.rb +26 -0
  13. data/app/views/micro_cms/_content_block.html.erb +19 -0
  14. data/config/routes.rb +5 -0
  15. data/db/migrate/20190923103919_create_micro_cms_content_blocks.rb +12 -0
  16. data/lib/micro_cms.rb +15 -0
  17. data/lib/micro_cms/engine.rb +25 -0
  18. data/lib/micro_cms/version.rb +5 -0
  19. data/spec/dummy/Rakefile +8 -0
  20. data/spec/dummy/app/assets/config/manifest.js +3 -0
  21. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  22. data/spec/dummy/app/channels/application_cable/channel.rb +6 -0
  23. data/spec/dummy/app/channels/application_cable/connection.rb +6 -0
  24. data/spec/dummy/app/controllers/application_controller.rb +4 -0
  25. data/spec/dummy/app/helpers/application_helper.rb +4 -0
  26. data/spec/dummy/app/javascript/packs/application.js +15 -0
  27. data/spec/dummy/app/jobs/application_job.rb +9 -0
  28. data/spec/dummy/app/mailers/application_mailer.rb +6 -0
  29. data/spec/dummy/app/models/application_record.rb +5 -0
  30. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  31. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  32. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  33. data/spec/dummy/bin/rails +11 -0
  34. data/spec/dummy/bin/rake +11 -0
  35. data/spec/dummy/bin/rspec +8 -0
  36. data/spec/dummy/bin/setup +35 -0
  37. data/spec/dummy/bin/spring +17 -0
  38. data/spec/dummy/config.ru +7 -0
  39. data/spec/dummy/config/application.rb +31 -0
  40. data/spec/dummy/config/boot.rb +7 -0
  41. data/spec/dummy/config/cable.yml +10 -0
  42. data/spec/dummy/config/database.yml +25 -0
  43. data/spec/dummy/config/environment.rb +7 -0
  44. data/spec/dummy/config/environments/development.rb +64 -0
  45. data/spec/dummy/config/environments/production.rb +114 -0
  46. data/spec/dummy/config/environments/test.rb +50 -0
  47. data/spec/dummy/config/initializers/application_controller_renderer.rb +10 -0
  48. data/spec/dummy/config/initializers/assets.rb +14 -0
  49. data/spec/dummy/config/initializers/backtrace_silencers.rb +9 -0
  50. data/spec/dummy/config/initializers/content_security_policy.rb +30 -0
  51. data/spec/dummy/config/initializers/cookies_serializer.rb +7 -0
  52. data/spec/dummy/config/initializers/filter_parameter_logging.rb +6 -0
  53. data/spec/dummy/config/initializers/inflections.rb +18 -0
  54. data/spec/dummy/config/initializers/mime_types.rb +6 -0
  55. data/spec/dummy/config/initializers/wrap_parameters.rb +16 -0
  56. data/spec/dummy/config/locales/en.yml +33 -0
  57. data/spec/dummy/config/puma.rb +40 -0
  58. data/spec/dummy/config/routes.rb +5 -0
  59. data/spec/dummy/config/spring.rb +8 -0
  60. data/spec/dummy/config/storage.yml +34 -0
  61. data/spec/dummy/db/development.sqlite3 +0 -0
  62. data/spec/dummy/db/migrate/20190923150252_create_micro_cms_content_blocks.micro_cms.rb +13 -0
  63. data/spec/dummy/db/schema.rb +22 -0
  64. data/spec/dummy/db/test.sqlite3 +0 -0
  65. data/spec/dummy/log/development.log +1 -0
  66. data/spec/dummy/log/test.log +478 -0
  67. data/spec/dummy/public/404.html +67 -0
  68. data/spec/dummy/public/422.html +67 -0
  69. data/spec/dummy/public/500.html +66 -0
  70. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  71. data/spec/dummy/public/apple-touch-icon.png +0 -0
  72. data/spec/dummy/public/favicon.ico +0 -0
  73. data/spec/dummy/tmp/development_secret.txt +1 -0
  74. data/spec/engine/micro_cms_spec.rb +9 -0
  75. data/spec/examples.txt +28 -0
  76. data/spec/factories/micro_cms/content_blocks.rb +8 -0
  77. data/spec/helpers/micro_cms/cms_block_helper_spec.rb +138 -0
  78. data/spec/models/micro_cms/content_block_spec.rb +62 -0
  79. data/spec/rails_helper.rb +75 -0
  80. data/spec/requests/micro_cms/content_block_controller_spec.rb +57 -0
  81. data/spec/routing/micro_cms/content_blocks_routing_spec.rb +17 -0
  82. data/spec/spec_helper.rb +43 -0
  83. data/spec/support/shared_examples/cms_block_helper_spec_helper.rb +9 -0
  84. data/spec/views/micro_cms/content_block_spec.rb +25 -0
  85. 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,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MicroCms
4
+ class ApplicationController < ActionController::Base
5
+ protect_from_forgery with: :exception
6
+ end
7
+ end
@@ -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,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MicroCms
4
+ module ApplicationHelper
5
+ end
6
+ 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,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MicroCms
4
+ class ApplicationRecord < ActiveRecord::Base
5
+ self.abstract_class = true
6
+ end
7
+ 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,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ MicroCms::Engine.routes.draw do
4
+ resources :content_block, only: :update, param: :path
5
+ end
@@ -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
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MicroCms
4
+ VERSION = '0.1.0'
5
+ end
@@ -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,3 @@
1
+ //= link_tree ../images
2
+ //= link_directory ../stylesheets .css
3
+ //= link micro_cms_manifest.js
@@ -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
+ */
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ApplicationCable
4
+ class Channel < ActionCable::Channel::Base
5
+ end
6
+ end