richer_text 0.0.1 → 0.2.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 +4 -4
- data/README.md +62 -5
- data/app/helpers/richer_text/tag_helper.rb +49 -0
- data/app/javascript/controllers/richer_text_editor_controller.js +10 -0
- data/app/models/richer_text/rich_text.rb +3 -2
- data/app/views/richer_text/contents/_content.html.erb +3 -0
- data/lib/generators/richer_text/install/install_generator.rb +49 -0
- data/lib/richer_text/content.rb +4 -3
- data/lib/richer_text/engine.rb +6 -0
- data/lib/richer_text/rendering.rb +13 -0
- data/lib/richer_text/version.rb +1 -1
- data/lib/richer_text.rb +1 -0
- data/lib/tasks/richer_text_tasks.rake +4 -4
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8ab9e5f516632d096522a7aa18daaad74e8c6b2eb5736bce0aff526e49a6f5a0
|
4
|
+
data.tar.gz: 532ff98188ba2b2425188cfcbec7cf80d5563d65339c7a247fdebb41d418247a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39981e09d8ce208402c1c66a1541a706af868ad1563d4497b5d919a452256da00308448a6c08a5751f5cebc4b1613c165a2c0ec4d9302a8356a0f33f27f653db
|
7
|
+
data.tar.gz: 5ea9229f6bfd06ab525ab96b543dc63eed8dcbd34b3419f2dda0fe1058dba8168d881e29871917916ba1b03be7b7d7372da1b233f7c37018528f7c867383d4a6
|
data/README.md
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# RicherText
|
2
|
-
Short description and motivation.
|
3
2
|
|
4
|
-
|
5
|
-
|
3
|
+
RicherText aims to provide a richer text editing experience than what comes out of the box with ActionText in Rails. **It is however a seperate thing from ActionText** and is **not** backwards compatible.
|
4
|
+
|
5
|
+
RicherText uses React and TipTap under the hood to create an editor, this does mean that you'll have react and react-dom in your project, but you absolutely don't need to use it outside of the RicherText editor. Additionally there's currently a hard requirement for ActiveStorage as well.
|
6
6
|
|
7
7
|
## Installation
|
8
|
+
|
8
9
|
Add this line to your application's Gemfile:
|
9
10
|
|
10
11
|
```ruby
|
@@ -12,17 +13,73 @@ gem "richer_text"
|
|
12
13
|
```
|
13
14
|
|
14
15
|
And then execute:
|
16
|
+
|
15
17
|
```bash
|
16
18
|
$ bundle
|
17
19
|
```
|
18
20
|
|
19
|
-
|
21
|
+
Once you've installed the gem the next step is to run the Generator and install all required libraries.
|
22
|
+
|
20
23
|
```bash
|
21
|
-
$
|
24
|
+
$ rails richer_text:install
|
25
|
+
```
|
26
|
+
|
27
|
+
> [!IMPORTANT]
|
28
|
+
> If you wish to use highlight.js outside of RicherText you'll need to add some code to your javascript entry point.
|
29
|
+
|
30
|
+
```js
|
31
|
+
const hljs = require("highlight.js");
|
32
|
+
|
33
|
+
document.addEventListener("turbo:load", (event) => {
|
34
|
+
document.querySelectorAll("pre").forEach((block) => {
|
35
|
+
hljs.highlightElement(block);
|
36
|
+
});
|
37
|
+
});
|
38
|
+
```
|
39
|
+
|
40
|
+
## Usage
|
41
|
+
|
42
|
+
> [!WARNING]
|
43
|
+
> You probably shouldn't use this gem / npm package (yet!) for anything serious. It's still undergoing development. But please do try it on a non-production app!
|
44
|
+
|
45
|
+
To use RicherText, once you've completed the installation process is a matter of doing the following:
|
46
|
+
|
47
|
+
**Add has_richer_text to a model**
|
48
|
+
|
49
|
+
Take a Post model where you'd like to add RicherText to write, and edit the body attribute:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
class Post < ApplicationRecord
|
53
|
+
has_richer_text :body
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
57
|
+
**Add the form helper to the form**
|
58
|
+
|
59
|
+
Inside of your form partial:
|
60
|
+
|
61
|
+
```erb
|
62
|
+
<%= form.label :body %>
|
63
|
+
<%= form.richer_text_area :body %>
|
64
|
+
```
|
65
|
+
|
66
|
+
Optionally you can pass arguments to the RicherText editor...
|
67
|
+
|
68
|
+
```erb
|
69
|
+
<%= form.label :body %>
|
70
|
+
<%= form.richer_text_area :body, callouts: true, placeholder: "Write something..." %>
|
71
|
+
```
|
72
|
+
|
73
|
+
**Render the richer text content**
|
74
|
+
|
75
|
+
```erb
|
76
|
+
<%= @post.body %>
|
22
77
|
```
|
23
78
|
|
24
79
|
## Contributing
|
80
|
+
|
25
81
|
Contribution directions go here.
|
26
82
|
|
27
83
|
## License
|
84
|
+
|
28
85
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require "action_view/helpers/tags/placeholderable"
|
2
|
+
|
3
|
+
module ActionView::Helpers
|
4
|
+
class Tags::Editor < Tags::Base
|
5
|
+
include Tags::Placeholderable
|
6
|
+
|
7
|
+
def render
|
8
|
+
options = @options.stringify_keys
|
9
|
+
options["value"] = options.fetch("value") { value&.to_html }
|
10
|
+
add_default_name_and_id(options)
|
11
|
+
|
12
|
+
@template_object.richer_text_area_tag(options["name"], options["value"], options.except("value"))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module FormHelper
|
17
|
+
def richer_text_area(object_name, method, options = {})
|
18
|
+
Tags::Editor.new(object_name, method, self, options).render
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class FormBuilder
|
23
|
+
def richer_text_area(method, options = {})
|
24
|
+
@template.richer_text_area(@object_name, method, objectify_options(options))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
module RicherText
|
31
|
+
module TagHelper
|
32
|
+
cattr_accessor(:id, instance_accessor: false) { 0 }
|
33
|
+
|
34
|
+
def richer_text_area_tag(name, value = nil, options = {})
|
35
|
+
options = options.symbolize_keys
|
36
|
+
options[:id] ||= "editor_input_#{TagHelper.id += 1}"
|
37
|
+
options[:class] ||= "editor-input"
|
38
|
+
|
39
|
+
# So that we can access the content in the tiptap editor
|
40
|
+
options[:content] ||= value
|
41
|
+
|
42
|
+
# editor_toolbar(id: options[:id]) + content_tag("textarea", value, options)
|
43
|
+
content_tag("div", data: { controller: "richer-text-editor", action: "editor:update->richer-text-editor#update" }) do
|
44
|
+
hidden_field_tag(name, value, { class: "w-full", data: { richer_text_editor_target: "input" } }) +
|
45
|
+
tag("richer-text-editor", options)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -1,17 +1,18 @@
|
|
1
1
|
module RicherText
|
2
2
|
class RichText < ApplicationRecord
|
3
|
-
belongs_to :record, polymorphic: true
|
3
|
+
belongs_to :record, polymorphic: true, touch: true
|
4
4
|
|
5
5
|
serialize :body, RicherText::Content
|
6
6
|
|
7
7
|
delegate :to_s, :nil?, to: :body
|
8
|
+
delegate :blank?, :empty?, :present?, to: :to_html
|
8
9
|
|
9
10
|
has_many_attached :images
|
10
11
|
|
11
12
|
before_save :update_images
|
12
13
|
|
13
14
|
def to_html
|
14
|
-
body&.to_html
|
15
|
+
body&.to_html&.to_s
|
15
16
|
end
|
16
17
|
|
17
18
|
private
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require "pathname"
|
2
|
+
|
3
|
+
module RicherText
|
4
|
+
module Generators
|
5
|
+
class InstallGenerator < ::Rails::Generators::Base
|
6
|
+
source_root RicherText::Engine.root
|
7
|
+
|
8
|
+
def create_migrations
|
9
|
+
rails_command "railties:install:migrations FROM=active_storage,richer_text", inline: true
|
10
|
+
end
|
11
|
+
|
12
|
+
def copy_files
|
13
|
+
copy_file(
|
14
|
+
"app/views/richer_text/contents/_content.html.erb",
|
15
|
+
"app/views/richer_text/contents/_content.html.erb"
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
def install_javascript_dependencies
|
20
|
+
destination = Pathname(destination_root)
|
21
|
+
|
22
|
+
if destination.join("package.json").exist?
|
23
|
+
say "Adding dependencies to package.json", :green
|
24
|
+
run "yarn add react react-dom highlight.js @afomera/richer-text"
|
25
|
+
end
|
26
|
+
|
27
|
+
say "Adding import to application.js", :green
|
28
|
+
append_to_file "app/javascript/application.js", %(import "@afomera/richer-text"\n)
|
29
|
+
end
|
30
|
+
|
31
|
+
def install_stylesheet_dependencies
|
32
|
+
destination = Pathname(destination_root)
|
33
|
+
|
34
|
+
if destination.join("app/assets/stylesheets/application.tailwind.css").exist?
|
35
|
+
say "Adding import to application.tailwind.css", :green
|
36
|
+
prepend_to_file "app/assets/stylesheets/application.tailwind.css", %(@import "@afomera/richer-text/dist/css/richer-text.css";\n@import "highlight.js/styles/github-dark.css";\n)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def generate_stimulus_controller
|
41
|
+
say "Copying Stimulus controller", :green
|
42
|
+
copy_file "app/javascript/controllers/richer_text_editor_controller.js", "app/javascript/controllers/richer_text_editor_controller.js"
|
43
|
+
|
44
|
+
say "Updating Stimulus manifest", :green
|
45
|
+
rails_command "stimulus:manifest:update"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/richer_text/content.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module RicherText
|
2
2
|
class Content
|
3
|
-
include Serialization
|
3
|
+
include ActiveModel::Conversion, Serialization, Rendering
|
4
4
|
|
5
5
|
delegate :blank?, :empty?, :html_safe, :present?, to: :to_html
|
6
6
|
|
@@ -15,7 +15,7 @@ module RicherText
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def to_s
|
18
|
-
|
18
|
+
render partial: to_partial_path, layout: false, locals: { content: self }
|
19
19
|
end
|
20
20
|
|
21
21
|
def to_html
|
@@ -41,6 +41,7 @@ module RicherText
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
attr_reader :
|
44
|
+
attr_reader :fragment
|
45
|
+
attr_accessor :body
|
45
46
|
end
|
46
47
|
end
|
data/lib/richer_text/engine.rb
CHANGED
data/lib/richer_text/version.rb
CHANGED
data/lib/richer_text.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
desc "Installs RicherText into your application"
|
2
|
+
task "richer_text:install" do
|
3
|
+
Rails::Command.invoke :generate, ["richer_text:install"]
|
4
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: richer_text
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrea Fomera
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-07-
|
11
|
+
date: 2023-07-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -38,18 +38,23 @@ files:
|
|
38
38
|
- app/assets/stylesheets/richer_text/application.css
|
39
39
|
- app/controllers/richer_text/application_controller.rb
|
40
40
|
- app/helpers/richer_text/application_helper.rb
|
41
|
+
- app/helpers/richer_text/tag_helper.rb
|
42
|
+
- app/javascript/controllers/richer_text_editor_controller.js
|
41
43
|
- app/jobs/richer_text/application_job.rb
|
42
44
|
- app/mailers/richer_text/application_mailer.rb
|
43
45
|
- app/models/richer_text/application_record.rb
|
44
46
|
- app/models/richer_text/rich_text.rb
|
45
47
|
- app/views/layouts/richer_text/application.html.erb
|
48
|
+
- app/views/richer_text/contents/_content.html.erb
|
46
49
|
- config/routes.rb
|
47
50
|
- db/migrate/20230107020316_create_richer_text_rich_texts.rb
|
51
|
+
- lib/generators/richer_text/install/install_generator.rb
|
48
52
|
- lib/richer_text.rb
|
49
53
|
- lib/richer_text/attribute.rb
|
50
54
|
- lib/richer_text/content.rb
|
51
55
|
- lib/richer_text/engine.rb
|
52
56
|
- lib/richer_text/fragment.rb
|
57
|
+
- lib/richer_text/rendering.rb
|
53
58
|
- lib/richer_text/serialization.rb
|
54
59
|
- lib/richer_text/version.rb
|
55
60
|
- lib/tasks/richer_text_tasks.rake
|