Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: automatic route mounting and a couple of tweaks #12

Merged
merged 7 commits into from
Feb 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ on:
branches: [ main ]

jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ruby-3.3.1
bundler-cache: true

- name: Lint code for consistent style
run: bin/rubocop -f github
# lint:
# runs-on: ubuntu-latest
# steps:
# - name: Checkout code
# uses: actions/checkout@v4

# - name: Set up Ruby
# uses: ruby/setup-ruby@v1
# with:
# ruby-version: ruby-3.3.1
# bundler-cache: true

# - name: Lint code for consistent style
# run: bin/rubocop -f github

test:
runs-on: ubuntu-latest
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,5 @@ node_modules
*.local

app/assets/builds

vite.config.ts.timestamp-*.mjs
7 changes: 6 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ source "https://rubygems.org"
# Specify your gem's dependencies in marksmith.gemspec.
gemspec

gem "rails", ">= 7.0.0"

gem "puma"

gem "sqlite3"
Expand All @@ -18,6 +20,9 @@ gem 'vite_rails'
gem 'stimulus-rails'
gem 'turbo-rails'

group :development do
gem "web-console", ">= 3.3.0"
end

# Access an interactive console on exception pages or by calling 'console' anywhere in the code.
gem "web-console", ">= 3.3.0"
gem "listen", ">= 3.5.1"
3 changes: 2 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ PATH
remote: .
specs:
marksmith (0.1.1)
rails (>= 7.0.0)
activesupport
redcarpet

GEM
Expand Down Expand Up @@ -305,6 +305,7 @@ DEPENDENCIES
marksmith!
propshaft
puma
rails (>= 7.0.0)
rubocop-rails-omakase
sqlite3
stimulus-rails
Expand Down
98 changes: 83 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ It supports Active Storage attachments and comes with a built-in mardown preview

![Marksmith demo](./marksmith.gif)

> [!WARNING]
> Marksmith is at the initial stage of development. It's nearing a beta release, but the API might change and bugs are expected. Please continue to use the library and report any issues in the GitHub repo.

Temporary live demo here, under the description field: [https://main.avodemo.com/avo/resources/projects/new](https://main.avodemo.com/avo/resources/projects/new)

## Usage
Expand All @@ -18,7 +21,7 @@ Temporary live demo here, under the description field: [https://main.avodemo.com

## Installation

### 1. Add `marksmith` to your `Gemfile`
#### 1. Add `marksmith` to your `Gemfile`

Have Bundler add it by running this command:

Expand All @@ -35,20 +38,27 @@ Add this line to your application's Gemfile:
gem "marksmith"
```

### 2. Install the NPM package to import the StimulusJS controller.
#### 2. Install the NPM package to import the StimulusJS controller.

Install the package.
Install the package from npmjs.org.

```bash
$ yarn add @avo-hq/marksmith
```

Import and register it in your application.
Or pin it using importmap.

```bash
bin/importmap pin @avo-hq/marksmith
```

Import and register the controllers in your application. The `ListContinuationController` is optional and only needed if you want to have continued lists in your markdown.

```js
import { MarksmithController } from '@avo-hq/marksmith'
import { MarksmithController, ListContinuationController } from '@avo-hq/marksmith'

application.register('marksmith', MarksmithController)
application.register('list-continuation', ListContinuationController)
```

> [!NOTE]
Expand All @@ -68,28 +78,78 @@ import { MarksmithController } from '@avo-hq/marksmith/core'
application.register('marksmith', MarksmithController)
```

### 3. Add the style tag to your `application.html` layout
#### 3. Add the style tag to your `application.html` layout

```erb
<%= stylesheet_link_tag "marksmith" %>
```

### 4. Use it
#### 4. Use it

Use a form helper tag or attach it to your form builder.

```erb
<%= marksmith_tag :body, value: "### This is important" %>
or
<%= @form.marksmith :body %>
<%= form.marksmith :body %>
```

## Options
## Configuration

Marksmith accepts a few configuration options.

### Field options

The field supports a few of the regular options like `disabled`, `placeholder`, `autofocus`, `style`, `class`, `rows`, `data`, and `value`, but also a custom one.

`extra_preview_params` - Sends extra params to the preview renderer.

`enable_file_uploads` - Whether to enable file uploads.

`upload_url` - The URL to use for file uploads. If not provided, the editor will use the `rails_direct_uploads_url` helper.

```erb
<%= marksmith_tag :body,
disabled: true,
placeholder: "Write your best markdown here.",
extra_preview_params: { foo: "bar" },
enable_file_uploads: true,
upload_url: nil
%>
```

### Eject configuration file

Marksmith comes with a default configuration file that you can eject to your app.

```bash
bin/rails generate marksmith:install
```

This will create a `config/initializers/marksmith.rb` file in your app.

### Mount path

The engine is mounted by default at `/marksmith`. You can change it by setting `Marksmith.configuration.mount_path` to a different path.

```ruby
# config/initializers/marksmith.rb
Marksmith.configure do |config|
config.mount_path = "/markdown"
end
```

### Mounting the engine

The engine is mounted by default, but you can disable it by setting `Marksmith.configuration.automatically_mount_engine` to `false` and then manually mount the engine in your `routes.rb` file.

```ruby
# config/routes.rb
Rails.application.routes.draw do
mount Marksmith::Engine => Marksmith.configuration.mount_path
end
```

## Built-in preview renderer

The renderer is powered by [`Redcarpet`](https://github.com/vmg/redcarpet).
Expand All @@ -101,13 +161,15 @@ In your `show.html.erb` view or the place where you want to render the compiled
<%== marksmithed post.body %>
```

## Using with importmap
> [!WARNING]
> Using the `<%==` tag will output the raw HTML, so ensure you sanitize the content to avoid XSS attacks.
>
> See how we do it [here](https://github.com/avo-hq/avo/blob/main/app/views/marksmith/shared/_rendered_body.html.erb#L2).
> ```ruby
> # sample sanitization
> sanitize(body, tags: %w(table th tr td span) + ActionView::Helpers::SanitizeHelper.sanitizer_vendor.safe_list_sanitizer.allowed_tags.to_a)
> ```

It should be as simple as running this command and have it pinned in your `importmap.rb` file.

```bash
bin/importmap pin @avo-hq/marksmith
```

## Active Storage

Expand All @@ -130,6 +192,12 @@ application.register('marksmith', MarksmithController)
application.register('list-continuation', ListContinuationController)
```

## Who uses Marksmith?

- [Avo](https://avohq.io) - Ruby on Rails Code-Based App Builder Framework

*Open a PR and add your project here*

## Contributing

Contribution directions go here.
Expand Down
9 changes: 9 additions & 0 deletions app/assets/javascripts/marksmith_controller-full.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -2827,10 +2827,15 @@ var MarksmithController = (function () {
fieldId: String,
galleryEnabled: { type: Boolean, default: false },
galleryOpenPath: String,
fileUploadsEnabled: { type: Boolean, default: true },
}

static targets = ['fieldContainer', 'fieldElement', 'previewElement', 'writeTabButton', 'previewTabButton', 'toolbar']

get #fileUploadsDisabled() {
return !this.fileUploadsEnabledValue
}

connect() {
subscribe(this.fieldContainerTarget, { defaultPlainTextPaste: { urlLinks: true } });
}
Expand Down Expand Up @@ -2878,11 +2883,15 @@ var MarksmithController = (function () {
}

dropUpload(event) {
if (this.#fileUploadsDisabled) return

event.preventDefault();
this.#uploadFiles(event.dataTransfer.files);
}

pasteUpload(event) {
if (this.#fileUploadsDisabled) return

if (!event.clipboardData.files.length) return

event.preventDefault();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2337,10 +2337,15 @@ var MarksmithController = (function (stimulus) {
fieldId: String,
galleryEnabled: { type: Boolean, default: false },
galleryOpenPath: String,
fileUploadsEnabled: { type: Boolean, default: true },
}

static targets = ['fieldContainer', 'fieldElement', 'previewElement', 'writeTabButton', 'previewTabButton', 'toolbar']

get #fileUploadsDisabled() {
return !this.fileUploadsEnabledValue
}

connect() {
subscribe(this.fieldContainerTarget, { defaultPlainTextPaste: { urlLinks: true } });
}
Expand Down Expand Up @@ -2388,11 +2393,15 @@ var MarksmithController = (function (stimulus) {
}

dropUpload(event) {
if (this.#fileUploadsDisabled) return

event.preventDefault();
this.#uploadFiles(event.dataTransfer.files);
}

pasteUpload(event) {
if (this.#fileUploadsDisabled) return

if (!event.clipboardData.files.length) return

event.preventDefault();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,15 @@ export default class extends Controller {
fieldId: String,
galleryEnabled: { type: Boolean, default: false },
galleryOpenPath: String,
fileUploadsEnabled: { type: Boolean, default: true },
}

static targets = ['fieldContainer', 'fieldElement', 'previewElement', 'writeTabButton', 'previewTabButton', 'toolbar']

get #fileUploadsDisabled() {
return !this.fileUploadsEnabledValue
}

connect() {
subscribe(this.fieldContainerTarget, { defaultPlainTextPaste: { urlLinks: true } })
}
Expand Down Expand Up @@ -68,11 +73,15 @@ export default class extends Controller {
}

dropUpload(event) {
if (this.#fileUploadsDisabled) return

event.preventDefault()
this.#uploadFiles(event.dataTransfer.files)
}

pasteUpload(event) {
if (this.#fileUploadsDisabled) return

if (!event.clipboardData.files.length) return

event.preventDefault()
Expand Down
23 changes: 20 additions & 3 deletions app/views/marksmith/shared/_editor.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@
local_assigns[:value] || nil
end
extra_preview_params = local_assigns[:extra_preview_params] || {}
upload_url = if local_assigns[:upload_url].present?
local_assigns[:upload_url]
elsif defined?(ActiveStorage)
main_app.rails_direct_uploads_url
end

enable_file_uploads = if upload_url.blank?
false
elsif local_assigns[:enable_file_uploads].nil?
true
else
local_assigns[:enable_file_uploads]
end


# Used by Avo and other adapters to enable the gallery link.
gallery_enabled = local_assigns.dig(:gallery, :enabled) || false
Expand All @@ -35,8 +49,9 @@
",
unique_selector: ".#{@input_id}", # used to pinpoint the exact element in which to insert the attachment
marksmith_preview_url_value: marksmith.markdown_previews_path,
marksmith_file_uploads_enabled_value: enable_file_uploads,
marksmith_active_tab_class: "bg-white",
marksmith_attach_url_value: main_app.rails_direct_uploads_url,
marksmith_attach_url_value: upload_url,
marksmith_extra_preview_params_value: extra_preview_params.as_json,
**local_assigns.fetch(:controller_data_attributes, {})
} do %>
Expand Down Expand Up @@ -85,8 +100,10 @@
<%= link_to "https://docs.github.com/github/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax", target: "_blank", class: class_names("ms:flex ms:items-center ms:text-neutral-800 ms:no-underline", toolbar_button_classes) do %>
<%= image_tag asset_path("marksmith/svgs/markdown.svg"), class: "ms:inline ms:size-4 ms:mr-1" %> <%= t("marksmith.markdown_is_supported").humanize %>
<% end %>
<%= button_tag data: { action: "click->marksmith#buttonUpload" }, class: class_names("ms:bg-none ms:border-none ms:bg-transparent ms:text-neutral-600 ms:items-center ms:flex", toolbar_button_classes) do %>
<%= image_tag asset_path("marksmith/svgs/paperclip.svg"), class: "ms:inline ms:size-4 ms:mr-1" %> <%= t("marksmith.upload_files").humanize %>
<% if enable_file_uploads %>
<%= button_tag data: { action: "click->marksmith#buttonUpload" }, class: class_names("ms:bg-none ms:border-none ms:bg-transparent ms:text-neutral-600 ms:items-center ms:flex", toolbar_button_classes) do %>
<%= image_tag asset_path("marksmith/svgs/paperclip.svg"), class: "ms:inline ms:size-4 ms:mr-1" %> <%= t("marksmith.upload_files").humanize %>
<% end %>
<% end %>
<% if gallery_enabled %>
<%= link_to gallery_full_path, data: { turbo_frame: gallery_turbo_frame }, class: class_names("ms:flex ms:items-center ms:text-neutral-800 ms:no-underline", toolbar_button_classes) do %>
Expand Down
Loading
Loading