Skip to content

Commit

Permalink
Add translate all feature to core translation pages
Browse files Browse the repository at this point in the history
  • Loading branch information
SkyLundy committed Dec 17, 2023
1 parent 27accb1 commit f5a8377
Show file tree
Hide file tree
Showing 14 changed files with 611 additions and 246 deletions.
15 changes: 13 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
# Fluency for ProcessWire Changelog

## 1.0.2 2023-12-17

### Enhancement, Documentation, Bugfix

- Added single-click translation for ProcessWire core translation pages. Any module or file using
`__()` can be translated with one click.
- Expanded README to include documentation on using the markup output features for front end HTML
- Expanded README to include additional details on interacting with Fluency programmatically
- Expanded README to include additional information on caching, performance, and usage
- Fixed issue where separators in language link list markup were not rendering correctly

## 1.0.1 2023-12-12

## Documentation & Fixes
### Documentation & Fixes

- Updated README.md with current module information
- Fix spelling errors in Fluency module docblock
- Remove JS debug logging from development

## 1.0.0 2023-12-02

## Enhancement, Bugfixes, Potential breaking changes
### Enhancement, Bugfixes, Potential breaking changes

- Added the ability to enable a "Translate to all languages" button for inputfields. This enables
cross-language translation to all languages with one click. The old style of per-field buttons
Expand Down
4 changes: 2 additions & 2 deletions Fluency.info.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

$info = [
'title' => 'Fluency',
'version' => '100',
'version' => '102',
'href' => 'https://processwire.com/talk/topic/24567-fluency-integrated-deepl-powered-content-translation',
'icon' => 'language',
'summary' => 'The complete translation suite for ProcessWire.',
'summary' => 'The complete translation enhancement suite for ProcessWire.',
'autoload' => true,
'singular' => true,
'requires' => [
Expand Down
12 changes: 8 additions & 4 deletions Fluency.module.php
Original file line number Diff line number Diff line change
Expand Up @@ -580,20 +580,24 @@ public function renderLanguageLinks(
string|array|null $classes = null,
string $id = '',
string $divider = null,
string $languageSource = 'fluency'
?string $activeClass = 'active',
string $languageSource = 'fluency',
): string {
$languages = $this->getLanguagesForMarkup($languageSource);

$items = array_reduce($languages, function($tags, $language) {
$items = array_reduce($languages, function($tags, $language) use ($activeClass, $divider) {
$tags[] = Markup::a(
href: $this->page->localUrl($language->id),
content: $language->title
content: $language->title,
classes: $language->isCurrentLanguage ? $activeClass : null
);

$divider && $tags[] = $divider;

return $tags;
}, []);

$divider && $items = implode($divider, $items);
end($items) === $divider && array_pop($items);

return Markup::ul(
items: Markup::li($items),
Expand Down
335 changes: 316 additions & 19 deletions README.md

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions app/FluencyLocalization.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ public static function getAll(): object {
'clickToCopy' => __('Click to Copy'),
'copied' => __('Copied!')
],
'languageTranslator' => [
'translateAllButton' => __('Click To Translate All'),
],
'usage' => [
'title' => __('Translation Service Usage Information'),
'description' => __('Click Refresh to get usage information'),
Expand Down
2 changes: 1 addition & 1 deletion app/FluencyMarkup.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public static function p(string|array $values, string|array $classes = []): stri
public static function a(
string $href,
string $content,
string|array $classes = [],
string|array|null $classes = [],
string $target = '_self',
string|array $rel = []
): string {
Expand Down
2 changes: 1 addition & 1 deletion assets/scripts/fluency.bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion assets/scripts/fluency_language_translator.bundle.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion assets/scripts/maps/fluency.bundle.js.map

Large diffs are not rendered by default.

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion gulpfile.babel.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ const watch = async function () {
Scripts.compileFluency,
// Scripts.compileStandaloneTranslator,
// Scripts.compileApiUsage,
// Scripts.compileLanguageTranslator,
Scripts.compileLanguageTranslator,
// Scripts.compileModuleConfig,
),
);
Expand Down
86 changes: 78 additions & 8 deletions src/scripts/global/FtConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ const FtConfig = (function () {

const fieldInitializedAttr = 'data-ft-initialized';

const translationActionTypes = {
each: 'translate_each_language',
all: 'translate_to_all_languages',
};

// Private properties

/**
Expand All @@ -22,6 +27,27 @@ const FtConfig = (function () {
*/
const localizedStrings = config.localization;

/**
* Classes for elements created in UI
* @type {Object}
*/
const elementClasses = {
translateButton: {
container: 'ft-translate-button-container',
button: 'ft-translate-button',
},
translateAllButton: {
container: 'Inputfield InputfieldHeaderHidden',
content: 'InputfieldContent',
button: 'ft-translate-all-button',
},
statusPlaceholder: {
container: 'ft-translation-status-container',
label: 'ft-translation-status',
},
icon: 'ft-icon',
};

/**
* Objects interface with the Fluency config object so that changes to the object
* structure from the back end do not break the UI. Use the public methods below
Expand All @@ -39,6 +65,7 @@ const FtConfig = (function () {
standaloneTranslator: localizedStrings.standaloneTranslator,
usage: localizedStrings.usage,
errors: localizedStrings.errors,
languageTranslator: localizedStrings.languageTranslator,
};

/**
Expand Down Expand Up @@ -77,22 +104,48 @@ const FtConfig = (function () {
* Languages
*/

/**
* Get all configured languages
* @return {object}
*/
const getConfiguredLanguages = () => configuredLanguages;

/**
* Returns ProcessWire's default language
* @return {object}
*/
const getDefaultLanguage = () =>
getConfiguredLanguages().reduce(
(defaultLang, lang) => (lang.default ? lang : defaultLang),
null,
);

/**
* Determines if the language with a given ProcessWire ID can be translated
* @param {int|string} languageId ProcessWire language ID
* @return {bool}
*/
const languageIsTranslatable = languageId =>
!getUnconfiguredLanguages().includes(parseInt(languageId, 10));

/**
* Get all languages not configured in Fluency
* @return {object}
*/
const getUnconfiguredLanguages = () => unconfiguredLanguages;

/**
* Gets total count of configured and unconfigured languages
* @return {int}
*/
const getLanguageCount = () =>
getConfiguredLanguages().length + getUnconfiguredLanguages().length;

/**
* Get a configured language by it's ProcessWire ID
* @param {string|int} pwLanguageId ProcessWire language ID
* @return {object}
*/
const getLanguageForId = pwLanguageId => {
pwLanguageId = parseInt(pwLanguageId, 10);

Expand All @@ -106,38 +159,55 @@ const FtConfig = (function () {
* Localization
*/

/**
* Accessor method for localized UI strings
* @param {string} key Object key
* @return {string}
*/
const getUiTextFor = key => strings[key];

/**
* Module Configuration/State
*/

/**
* Determines if Fluency JS should initialize based on whether languages have
* been configured
* @return {bool}
*/
const moduleShouldInitialize = () => getConfiguredLanguages().length > 1;

/**
* Returns the translation engine config object for the engine configured in Fluency
* @return {object|null}
*/
const getEngineInfo = () => config.engine;

/**
* Does this engine provide usage data?
* @return {bool}
*/
const getEngineProvidesUsageData = () => getEngineInfo().providesUsageData;

const getTranslationAction = () => config.interface.inputfieldTranslationAction;

/**
* Translation types. No magic strings.
* Gets the type of translation action chosen in the Flunecy module config
* @return {string}
*/
const translationActionTypes = {
each: 'translate_each_language',
all: 'translate_to_all_languages',
};
const getTranslationAction = () => config.interface.inputfieldTranslationAction;

const getElementClassesFor = element => elementClasses[element];

return {
fieldInitializedAttr,
getApiEndpointFor,
getConfiguredLanguages,
getDefaultLanguage,
getElementClassesFor,
getEngineInfo,
getEngineProvidesUsageData,
getTranslationAction,
getLanguageCount,
getLanguageForId,
getTranslationAction,
getUiTextFor,
getUnconfiguredLanguages,
languageIsTranslatable,
Expand Down
Loading

0 comments on commit f5a8377

Please sign in to comment.