Skip to content

Commit

Permalink
Simplify stimulus controller setup (#52)
Browse files Browse the repository at this point in the history
* Simplify stimulus controller setup

* Bump version

* Corrections
  • Loading branch information
coorasse authored Nov 11, 2024
1 parent 57ffcd6 commit f2d2c28
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 36 deletions.
84 changes: 51 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@
### Manage translation strings in real time

- Let your non-developer team members finally manage translations (yes, even Karen from marketing...).
- See those translations live in your app, so you can make sure “Submit” isn’t overlapping the button where “**Do not press this button EVER” should be.
- Automatically create Pull Requests based on these changes, saving your developers from yet another “small tweak” email request.
- See those translations live in your app, so you can make sure “Submit” isn’t overlapping the button where “**Do not
press this button EVER” should be.
- Automatically create Pull Requests based on these changes, saving your developers from yet another “small tweak” email
request.

> Let the world be translated, one typo at a time.

## Installation

Add this line to your application's Gemfile:
Expand All @@ -20,11 +21,13 @@ gem "moirai"
```

And then execute:

```bash
bundle
```

Next, you need to run the generator which will create the necessary files including the database migration, as well as inserting the engine in the `routes.rb` file:
Next, you need to run the generator which will create the necessary files including the database migration,
as well as inserting the engine in the `routes.rb` file, and importing the necessary javascript files:

```bash
bin/rails g moirai:install
Expand All @@ -40,40 +43,51 @@ bin/rails db:migrate

### How to change translations

If you mounted Moirai under "/moirai", head there and you will find a list of all the files containing texts that can be translated.
Open a file, change the value of translations, and press ENTER to update the translation and see it immediately changed on the application.
If you mounted Moirai under "/moirai", head there and you will find a list of all the files containing texts that can be
translated.
Open a file, change the value of translations, and press ENTER to update the translation and see it immediately changed
on the application.

### Inline editing

By default, inline editing is disabled. To enable it, set the `moirai=true` query parameter in the URL.

If you want to only allow specific users to perform inline editing, you can override the `moirai_edit_enabled?` method in your application helper.
If you want to only allow specific users to perform inline editing, you can override the `moirai_edit_enabled?` method
in your application helper.

```ruby

module ApplicationHelper
def moirai_edit_enabled?
params[:moirai] == "true" || current_user&.admin?
params[:moirai] == "true" && current_user&.admin?
end
end
```

You also need to have the moirai_translations_controller.js Stimulus Controller initialized.

If you use importmaps:
#### Importmap

Pin the controller in `config/importmap.rb`
The command `bin/rails g moirai:install` should have already pinned the necessary controller for you in importmap.rb, so
no further steps are needed.

```ruby
pin "controllers/moirai_translation_controller", to: "moirai_translation_controller.js"
```
#### jsbulding

If you’re unsure about all the possible configuration options, you can simply copy and paste the stimulus controller into your app as a fallback.
The command `bin/rails g moirai:install` should have already copied the necessary controller for you in
`app/javascripts/controllers`, so no further steps are needed.

#### More?

If you’re unsure about all the possible configuration options, you can simply copy and paste the stimulus controller
into your app as a fallback.

### Automatic PR creation with Octokit (**optional**)

If you would like Moirai to automatically create a pull request on GitHub to keep translations synchronized with the codebase,
If you would like Moirai to automatically create a pull request on GitHub to keep translations synchronized with the
codebase,
you need to set up [Octokit](https://github.com/octokit/octokit.rb).
You will also need to create a **Personal Access Token** on GitHub, and configure the access in the appropriate **environment variables** (this is explained below).
You will also need to create a **Personal Access Token** on GitHub, and configure the access in the appropriate *
*environment variables** (this is explained below).

#### 1. Add Octokit to Your Gemfile

Expand All @@ -87,22 +101,23 @@ Then run `bundle install`.

#### 2. Create a Personal Access Token (PAT) on GitHub

You will need a Personal Access Token (PAT) with the `Content - Write` permission to allow Octokit to create branches and pull requests.
You will need a Personal Access Token (PAT) with the `Content - Write` permission to allow Octokit to create branches
and pull requests.

- Go to GitHub Token Settings.
- Click Generate New Token.
- Give your token a name (e.g., “Moirai”).
- Under Scopes, select:
- repo (for full control of private repositories, including writing content).
- content (for read/write access to code, commit statuses, and pull requests).
- Generate the token and copy it immediately as it will be shown only once.
- Go to GitHub Token Settings.
- Click Generate New Token.
- Give your token a name (e.g., “Moirai”).
- Under Scopes, select:
- repo (for full control of private repositories, including writing content).
- content (for read/write access to code, commit statuses, and pull requests).
- Generate the token and copy it immediately as it will be shown only once.

#### 3. Set Up Environment Variables

You need to configure the following environment variables in your application:

- `MOIRAI_GITHUB_REPO_NAME`: The name of the repository where the pull request will be created.
- `MOIRAI_GITHUB_ACCESS_TOKEN`: The Personal Access Token (PAT) you created earlier.
- `MOIRAI_GITHUB_REPO_NAME`: The name of the repository where the pull request will be created.
- `MOIRAI_GITHUB_ACCESS_TOKEN`: The Personal Access Token (PAT) you created earlier.

For example, in your `.env` file:

Expand All @@ -111,7 +126,8 @@ MOIRAI_GITHUB_REPO_NAME=your-organization/your-repo
MOIRAI_GITHUB_ACCESS_TOKEN=your-generated-token
```

We also support Rails credentials. The environment variables need to be stored in a slightly different way to adhere to convention. For example:
We also support Rails credentials. The environment variables need to be stored in a slightly different way to adhere to
convention. For example:

```env
moirai:
Expand All @@ -121,13 +137,14 @@ moirai:

#### 4. Triggering the pull request creation

Moirai will now be able to use this Personal Access Token to create a pull request on GitHub when a translation is updated.
Moirai will now be able to use this Personal Access Token to create a pull request on GitHub when a translation is
updated.

To trigger this, you can press the `Create or update PR` button once you have made your changes.

### Authentication

Moirai allows you to use basic HTTP authentication to protect the engine.
Moirai allows you to use basic HTTP authentication to protect the engine.
To enable this, you need to set the following environment variables:

```env
Expand All @@ -137,11 +154,11 @@ MOIRAI_BASICAUTH_PASSWORD=moirai

> ⚠️ Remember to protect Moirai. You don't want to give everyone the possibility to change strings in the application.
If you have authenticated users, you can leverage the Rails Routes protection mechanism to protect the engine.
If you have authenticated users, you can leverage the Rails Routes protection mechanism to protect the engine.
See the following example:

```ruby
authenticated :user, lambda {|u| u.role == "admin"} do
authenticated :user, lambda { |u| u.role == "admin" } do
mount Moirai::Engine => '/moirai', as: 'moirai'
end
```
Expand All @@ -166,12 +183,12 @@ end

4. Set your environment variables using the newly created `.env` file.

You will need a repository to test against and a token. Generate a new Fine-GRained Personal access token and give the necessary permissions to your repository.
You will need a repository to test against and a token. Generate a new Fine-GRained Personal access token and give the
necessary permissions to your repository.
See the image below as an example:

![](docs/github_settings.png)


5. Run the tests:
```bash
bin/check
Expand All @@ -191,6 +208,7 @@ See the image below as an example:
* Support for fallbacks: it should detect when a fallback string is in use and prevent attempts to override its value.

## License

The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).

## Copyright
Expand Down
26 changes: 26 additions & 0 deletions lib/generators/moirai/install_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,35 @@ def copy_migration
invoke "moirai:migration"
end

def setup_javascript
if using_importmap?
say "Pin moirai"
string_to_be_added = "pin \"controllers/moirai_translation_controller\", to: \"moirai_translation_controller.js\""
say %(Appending: #{string_to_be_added})
append_to_file "config/importmap.rb", %(#{string_to_be_added}\n)
elsif using_js_bundling?
append_path = "app/javascript/controllers/moirai_translation_controller.js"
say "Copying Moirai Stimulus controller in #{append_path}"
copy_file "../../../../app/assets/javascripts/moirai_translation_controller.js", append_path
rails_command "stimulus:manifest:update"
end
end

private

def using_js_bundling?
Rails.root.join("app/javascript/controllers").exist?
end

def mount_engine
route 'mount Moirai::Engine => "/moirai", as: "moirai"'
end

private

def using_importmap?
Rails.root.join("config/importmap.rb").exist?
end
end
end
end
6 changes: 5 additions & 1 deletion lib/moirai/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ class Engine < ::Rails::Engine
end

config.after_initialize do
I18n.backend = I18n::Backend::Chain.new(I18n::Backend::Moirai.new, I18n.backend)
if ActiveRecord::Base.connection.data_source_exists?("moirai_translations")
I18n.backend = I18n::Backend::Chain.new(I18n::Backend::Moirai.new, I18n.backend)
else
Rails.logger.warn("moirai disabled: tables have not been generated yet.")
end
end

# TODO: how to do this without rewriting the entire method?
Expand Down
2 changes: 1 addition & 1 deletion lib/moirai/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Moirai
VERSION = "0.1.0"
VERSION = "0.2.0"
end
4 changes: 3 additions & 1 deletion moirai.gemspec
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# frozen_string_literal: true

require_relative "lib/moirai/version"

Gem::Specification.new do |spec|
spec.name = "moirai"
spec.version = "0.2.0"
spec.version = Moirai::VERSION
spec.authors = ["Alessandro Rodi", "Oliver Anthony", "Daniel Bengl"]
spec.email = %w[[email protected] [email protected] [email protected]]

Expand Down

0 comments on commit f2d2c28

Please sign in to comment.