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 web component i18n issues #2585

Merged
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
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ if ENV["DB"] == "mysql" || ENV["DB"] == "mariadb"
end
gem "pg", "~> 1.0" if ENV["DB"] == "postgresql"

gem "alchemy_i18n", git: "https://github.com/AlchemyCMS/alchemy_i18n.git", branch: "main"

group :development, :test do
gem "execjs", "~> 2.9.1"
gem "rubocop", require: false
Expand Down
1 change: 1 addition & 0 deletions app/assets/stylesheets/alchemy/forms.scss
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ form {
> .select2-container,
> .autocomplete_tag_list,
> .tinymce_container,
> alchemy-datepicker,
> .with-hint {
width: $form-right-width;
float: right;
Expand Down
4 changes: 1 addition & 3 deletions app/javascript/alchemy_admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ import "@hotwired/turbo-rails"

import Buttons from "alchemy_admin/buttons"
import GUI from "alchemy_admin/gui"
import translate from "alchemy_admin/i18n"
import { translate } from "alchemy_admin/i18n"
import Dirty from "alchemy_admin/dirty"
import translationData from "alchemy_admin/translations"
import fileEditors from "alchemy_admin/file_editors"
import IngredientAnchorLink from "alchemy_admin/ingredient_anchor_link"
import pictureEditors from "alchemy_admin/picture_editors"
Expand Down Expand Up @@ -41,7 +40,6 @@ Object.assign(Alchemy, {
...Dirty,
GUI,
t: translate, // Global utility method for translating a given string
translations: Object.assign(Alchemy.translations || {}, translationData),
fileEditors,
pictureEditors,
ImageLoader: ImageLoader.init,
Expand Down
15 changes: 9 additions & 6 deletions app/javascript/alchemy_admin/components/char_counter.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
/**
* Show the character counter below input fields and textareas
*/
class CharCounter extends HTMLElement {
constructor() {
super()
import { AlchemyHTMLElement } from "./alchemy_html_element"
import { translate } from "alchemy_admin/i18n"

this.maxChar = this.dataset.count
this.translation = Alchemy.t("allowed_chars", this.maxChar)
class CharCounter extends AlchemyHTMLElement {
static properties = {
maxChars: { default: 60 }
}
connected() {
this.translation = translate("allowed_chars", this.maxChars)
this.formField = this.getFormField()

if (this.formField) {
Expand All @@ -30,7 +33,7 @@ class CharCounter extends HTMLElement {
countCharacters() {
const charLength = this.formField.value.length
this.display.textContent = `${charLength} ${this.translation}`
this.display.classList.toggle("too-long", charLength > this.maxChar)
this.display.classList.toggle("too-long", charLength > this.maxChars)
}
}

Expand Down
7 changes: 4 additions & 3 deletions app/javascript/alchemy_admin/components/datepicker.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AlchemyHTMLElement } from "./alchemy_html_element"
import { translate, currentLocale } from "alchemy_admin/i18n"
import flatpickr from "flatpickr"

class Datepicker extends AlchemyHTMLElement {
Expand All @@ -9,14 +10,14 @@ class Datepicker extends AlchemyHTMLElement {
afterRender() {
const options = {
// alchemy_i18n supports `zh_CN` etc., but flatpickr only has two-letter codes (`zh`)
locale: Alchemy.locale.slice(0, 2),
locale: currentLocale().slice(0, 2),
altInput: true,
altFormat: Alchemy.t(`formats.${this.type}`),
altFormat: translate(`formats.${this.type}`),
altInputClass: "flatpickr-input",
dateFormat: "Z",
enableTime: /time/.test(this.type),
noCalendar: this.type === "time",
time_24hr: Alchemy.t("formats.time_24hr"),
time_24hr: translate("formats.time_24hr"),
onValueUpdate(_selectedDates, _dateStr, instance) {
Alchemy.setElementDirty(instance.element.closest(".element-editor"))
}
Expand Down
3 changes: 2 additions & 1 deletion app/javascript/alchemy_admin/components/tinymce.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AlchemyHTMLElement } from "./alchemy_html_element"
import { currentLocale } from "alchemy_admin/i18n"

class Tinymce extends AlchemyHTMLElement {
/**
Expand Down Expand Up @@ -101,7 +102,7 @@ class Tinymce extends AlchemyHTMLElement {
return {
...Alchemy.TinymceDefaults,
...customConfig,
locale: Alchemy.locale,
locale: currentLocale(),
selector: `#${this.editorId}`
}
}
Expand Down
20 changes: 12 additions & 8 deletions app/javascript/alchemy_admin/i18n.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
const KEY_SEPARATOR = /\./
import { en } from "alchemy_admin/locales/en"

function currentLocale() {
if (Alchemy.locale == null) {
throw "Alchemy.locale is not set! Please set Alchemy.locale to a locale string in order to translate something."
}
return Alchemy.locale
}
Alchemy.translations = Object.assign(Alchemy.translations || {}, { en })

const KEY_SEPARATOR = /\./

function getTranslations() {
const locale = currentLocale()
Expand Down Expand Up @@ -36,7 +33,14 @@ function getTranslation(key) {
return translations[key] || key
}

export default function translate(key, replacement) {
export function currentLocale() {
if (document.documentElement.lang) {
return document.documentElement.lang
}
return "en"
}

export function translate(key, replacement = undefined) {
let translation = getTranslation(key)

if (replacement) {
Expand Down
13 changes: 10 additions & 3 deletions app/javascript/alchemy_admin/initializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,19 @@
* add change listener to select to redirect the user after selecting another locale or site
* @param {string} selectId
* @param {string} parameterName
* @param {boolean} forcedReload
*/
function selectHandler(selectId, parameterName) {
function selectHandler(selectId, parameterName, forcedReload = false) {
$(`select#${selectId}`).on("change", function (e) {
let url = window.location.pathname
let delimiter = url.match(/\?/) ? "&" : "?"
Turbo.visit(`${url}${delimiter}${parameterName}=${$(this).val()}`, {})
const location = `${url}${delimiter}${parameterName}=${$(this).val()}`

if (forcedReload) {
window.location.href = location
} else {
Turbo.visit(location, {})
}
})
}

Expand All @@ -32,7 +39,7 @@ function Initialize() {
$("a.button").attr({ tabindex: 0 })

// Locale select handler
selectHandler("change_locale", "admin_locale")
selectHandler("change_locale", "admin_locale", true)

// Site select handler
selectHandler("change_site", "site_id")
Expand Down
28 changes: 28 additions & 0 deletions app/javascript/alchemy_admin/locales/en.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export const en = {
allowed_chars: "of %{count} chars",
cancel: "Cancel",
cancelled: "Cancelled",
click_to_edit: "click to edit",
complete: "Complete",
element_dirty_notice:
"This element has unsaved changes. Do you really want to fold it?",
help: "Help",
ok: "Ok",
page_dirty_notice:
"You have unsaved changes on this page. They will be lost if you continue.",
page_found: "Page found",
pages_found: "Pages found",
url_validation_failed: "The url has no valid format.",
warning: "Warning!",
"File is too large": "File is too large",
"File is too small": "File is too small",
"File type not allowed": "File type not allowed",
"Maximum number of files exceeded": "Maximum number of files exceeded.",
"Uploaded bytes exceed file size": "Uploaded bytes exceed file size",
formats: {
datetime: "Y-m-d H:i",
date: "Y-m-d",
time: "H:i",
time_24hr: false
}
}
32 changes: 0 additions & 32 deletions app/javascript/alchemy_admin/translations.js

This file was deleted.

4 changes: 2 additions & 2 deletions app/views/alchemy/admin/pages/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

<%= f.input :name, autofocus: true %>
<%= f.input :urlname, as: 'string', input_html: {value: @page.slug}, label: Alchemy::Page.human_attribute_name(:slug) %>
<alchemy-char-counter data-count="60">
<alchemy-char-counter max-chars="60">
<%= f.input :title %>
</alchemy-char-counter>

Expand All @@ -39,7 +39,7 @@
</div>
</div>

<alchemy-char-counter data-count="160">
<alchemy-char-counter max-chars="160">
<%= f.input :meta_description, as: 'text' %>
</alchemy-char-counter>

Expand Down
44 changes: 24 additions & 20 deletions app/views/alchemy/admin/styleguide/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,24 @@

<div class="input">
<label class="control-label" for="datetime_picker">Date Time Picker</label>
<input type="text" data-datepicker-type="datetime" id="datetime_picker">
<alchemy-datepicker type="datetime">
<input type="text" id="datetime_picker">
</alchemy-datepicker>
</div>

<div class="input">
<label class="control-label">Date & Time Pickers</label>
<div class="control_group">
<div class="input-row">
<div class="input-column">
<input type="text" data-datepicker-type="date" id="date_picker">
<alchemy-datepicker type="date">
<input type="text" id="date_picker">
</alchemy-datepicker>
</div>
<div class="input-column">
<input type="text" data-datepicker-type="time" id="time_picker">
<alchemy-datepicker type="time">
<input type="text" id="time_picker">
</alchemy-datepicker>
</div>
</div>
</div>
Expand All @@ -105,10 +111,12 @@
<input type="text" id="string_with_error">
<small class="error">Error message</small>
</div>
<div class="input">
<label class="control-label" for="string_with_counter">String with char counter</label>
<input data-alchemy-char-counter="60" type="text" id="string_with_counter">
</div>
<alchemy-char-counter max-chars="60">
<div class="input">
<label class="control-label" for="string_with_counter">String with char counter</label>
<input type="text" id="string_with_counter">
</div>
</alchemy-char-counter>

<div class="input check_boxes">
<label class="control-label">Check Boxes</label>
Expand All @@ -123,12 +131,12 @@
</label>
</div>
</div>

<div class="input text">
<label class="text control-label" for="textarea_with_counter">Textarea with char counter</label>
<textarea data-alchemy-char-counter="160" class="text" id="textarea_with_counter"></textarea>
</div>

<alchemy-char-counter max-chars="160">
<div class="input text">
<label class="text control-label" for="textarea_with_counter">Textarea with char counter</label>
<textarea class="text" id="textarea_with_counter"></textarea>
</div>
</alchemy-char-counter>
<div class="input text">
<label class="text control-label" for="textarea">Textarea</label>
<textarea class="text" id="textarea"></textarea>
Expand All @@ -137,7 +145,9 @@

<div class="input text tinymce_container">
<label class="text control-label" for="tinymce_1">Richtext editor</label>
<textarea class="text" id="tinymce_1"></textarea>
<alchemy-tinymce>
<textarea class="text" id="tinymce_1"></textarea>
</alchemy-tinymce>
</div>

<div class="submit">
Expand Down Expand Up @@ -230,9 +240,3 @@
<li>List item</li>
<li>List item</li>
</ol>

<%= content_for :javascripts do %>
<script>
Alchemy.Tinymce.init([1])
</script>
<% end %>
4 changes: 1 addition & 3 deletions app/views/layouts/alchemy/admin.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!DOCTYPE html>
<html class="no-js">
<html lang="<%= ::I18n.locale %>" class="no-js">
sascha-karnatz marked this conversation as resolved.
Show resolved Hide resolved
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
Expand Down Expand Up @@ -100,8 +100,6 @@
<%= yield %>
</div>
<script>
// Store current locale for javascript translations.
Alchemy.locale = '<%= ::I18n.locale %>';
// Setting the correct locale for select2 dropdown replacement.
$.extend($.fn.select2.defaults, $.fn.select2.locales['<%= ::I18n.locale %>']);
</script>
Expand Down
1 change: 1 addition & 0 deletions spec/dummy/app/assets/config/manifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
//= link application.css
//= link application.js
//= link_tree ../images
//= link tinymce/langs/de.js
4 changes: 4 additions & 0 deletions spec/dummy/config/environments/development.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
# Enable server timing
config.server_timing = true

# Configure available languages
config.i18n.default_locale = :en
config.i18n.available_locales = [:en, :de]

# Enable/disable caching. By default caching is disabled.
# Run rails dev:cache to toggle caching.
if Rails.root.join("tmp/caching-dev.txt").exist?
Expand Down

This file was deleted.

13 changes: 13 additions & 0 deletions spec/dummy/vendor/assets/javascripts/alchemy/admin/all.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// This is the AlchemyCMS javascript manifest that'll be compiled into alchemy/admin/all.js
//
// In order to add custom scripts to Alchemy's admin interface just require the files here.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require alchemy/admin
//= require alchemy_i18n/de
//= require select2_locale_de
Loading