This editor uses packages from the Wordpress Gutenberg project to build a standalone block editor for Rails. This editor has been extracted from Integral CMS where it was built following the Wordpress custom block editor tutorial.
The editor currently uses the v9.2.1 Gutenberg release packages which were part of the Wordpress v5.6 release.
Looking for a demo? Checkout this simple host application example.
More information;
Add this line to your application's Gemfile:
gem 'block_editor'
And then execute:
$ bundle
Or install it yourself as:
$ gem install block_editor
rails block_editor:install:migrations
rails db:migrate
include BlockEditor::Listable
to any model you wish to associate the block editor with, i.e.class Post < ApplicationRecord
include BlockEditor::Listable
end
<%= form.fields_for :active_block_list do |block_list| %>
<%= BlockEditor::Instance.render(block_list) %>
<% end %>
HEAD
tag <%= javascript_pack_tag 'block_editor/application', 'data-turbolinks-track': 'reload', webpacker: 'BlockEditor' %>
<%= stylesheet_pack_tag 'block_editor/application', 'data-turbolinks-track': 'reload', webpacker: 'BlockEditor' %>
Note: If the error Webpacker::Manifest::MissingEntryError
appears you need to run the following command to precompile the BlockEditor assets;
rails block_editor:webpacker:compile
Remember to permit the block list attributes if you're using Strong Parameters (you should be), i.e;
# Only allow a list of trusted parameters through.
def post_params
params.require(:post).permit(:title, active_block_list_attributes: [ :id, :content ])
end
Note: You may also need to specifically set the listable attribute within your controller before saving, i.e. -
@post.active_block_list.listable = @post
BlockEditor has a soft dependency on Bootstrap. You will need to add this to your application in order for the default styles to be compiled. If you do not want to use the default styles do not include them in the your application stylesheet and override BlockEditor's backend stylesheet (block_editor/frontend.scss
) with whatever custom styles you want to include.
Include the default styles into your application stylesheet;
@import "block_editor/blocks/frontend";
@import "block_editor/utilities";
Add the backend stylesheet where you are rendering the block editor, for example admin dashboard;
<%= stylesheet_link_tag 'block_editor/backend', media: 'all', 'data-turbolinks-track': 'reload' %>
The below files are provided by BlockEditor as entry points. Override them if you want to provide custom styling to your blocks;
app/assets/stylesheets/block_editor/host_app/blocks/_frontend.scss
- Any styles that should be displayed within the frontend and backendapp/assets/stylesheets/block_editor/host_app/blocks/_backend.scss
- Any styles that should only be displayed within the block editor itself, i.e when creating or editing the blocksThere is no built in MediaUploader or media gallery, it is up to the host application to implement this.
When the media uploader is requested the Block Editor checks if window.BlockEditorMediaUploader
is defined. If it is defined the block editor will call window.BlockEditorMediaUploader.open(callback)
, otherwise it will randomly select an image from Unsplash
When an image is successfully uploaded or selected the BlockEditorMediaUploader instance should call the callback which was passed into the open
function;
callback({url: imageUrl})
Currently Block Editor is not compatible with Turbolinks as history is only being reset on full page loads. To disable Turbolinks per page add the following in your layout view file within your <HEAD>
;;
<meta name="turbolinks-visit-control" content="reload">
BlockEditor will check the following endpoints for any available reusable blocks, if any are found they will appear in the inserter menus
get '/wp/v2/types', to: 'backend/block_lists#wp_types'
get '/wp/v2/types/wp_block', to: 'backend/block_lists#wp_type'
get '/wp/v2/block_lists', to: 'backend/block_lists#block_lists'
get '/wp/v2/block_list/:id', to: 'backend/block_lists#show'
get '/wp/v2/blocks/:id', to: 'backend/block_lists#show'
For an example of what the BlockEditor is expecting from these endpoints checkout how Integral CMS has implemented this
Currently there isn't a way of adding or removing blocks without forking the gem.
app/javascript/block_editor/blocks/index.js
where all blocks are registeredDynamic blocks are useful for non-static content such as a recent posts block or more complex blocks like a contact form block.
Currently the gem needs to be forked in order to create a dynamic block
A dynamic block is made up of 4 components;
class RecentPosts < BlockEditor::Base
def self.name
'block-editor/recent-posts'
end
end
BlockEditor.dynamic_blocks
config;// application.rb
BlockEditor.dynamic_blocks = [RecentPosts]
// app/views/block_editor/blocks/block-editor/recent-posts/_block.html.erb
My Recent Posts
<%= @posts %>
app/assets/stylesheets/block_editor/host_app/blocks/_frontend.scss
app/assets/stylesheets/block_editor/host_app/blocks/_backend.scss
app/javascript/block_editor/blocks/contact_form/index.js
app/javascript/block_editor/blocks/index.js
to register the blockContribution are very welcome! Currently the biggest issue that needs to be solved is extensibility. There is no way to modify and configure the editor behaviour (such as blocks to display, block output etc) without forking the engine.
The gem is available as open source under the terms of the MIT License.