Skip to content

Commit 46598f8

Browse files
committed
Add ProcessWire language name to ConfiguredLanguageData object
1 parent 8f3a983 commit 46598f8

File tree

101 files changed

+2261
-21606
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+2261
-21606
lines changed

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,6 @@
11
node_modules
2-
.dev
2+
.dev
3+
.parcel-cache/
4+
parcel-trace-*
5+
*.log
6+
*.cache

.postcssrc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"plugins": {
3+
"postcss-import": {},
4+
"postcss-nesting": {}
5+
}
6+
}

.prettierrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
"singleQuote": true,
33
"arrowParens": "avoid",
44
"printWidth": 100
5-
}
5+
}

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,32 @@
11
# Fluency for ProcessWire Changelog
22

3+
## 2.2.0 2025-12-23
4+
5+
### Critical update. New features, Bugfixes/Compatability. Required for users of DeepL.
6+
7+
**Critical**: All users employing DeepL as the translation service must upgrade. DeepL API authentication requirements will change in January 2025 with previous methods deprecated. Using Fluency with DeepL after 2025-12-15 will cause all translations to fail with a translation service error displayed in the UI.
8+
9+
- Update DeepL authentication method to Auth header from deprecated URL paramter. More information in the DeepL API documentation [here](https://developers.deepl.com/docs/resources/breaking-changes-change-notices/march-2025-deprecating-get-requests-to-translate-and-authenticating-with-auth_key)
10+
- Add clarification to requirement of AdminThemeUikit to use Fluency in README
11+
- Add 'name' property to ConfiguredLangaugeData object that makes the ProcessWire name of the
12+
language available
13+
- Fix deprecated PHP 8.4 deprecated implicit null parameters in FluencyMarkup class. Credit to @BernhardBaumrock for finding/reporting
14+
- Add jQuery change event trigger when translated values are inserted in addition to native JavaScript change event. See note on change detection in RockPageBuilder fields below
15+
- Add additional TinyMCE compatability.
16+
- Replace Gulp with Parcel for asset bundling.
17+
- Replace Sass with CSS, replace Sass transpiler with PostCSS
18+
- Add compatibility with new AdminThemeUikit 3 theme and theme features. Remains backwards compatible with previous versions
19+
- UI design updates.
20+
- Updated README.md with documentation for theming Fluency
21+
- API usage table now shows used/limit/remaining numbers formatted with commas to more easily read when they're large
22+
- Remove legacy/unused code and files. Code cleanup. A little more docblocking.
23+
- Change console warnings about unrecognized fields when attempting to initialize translation to only show when debug is enabled so we aren't junking up the browser console
24+
- Added additional documentation for contributing and the tech stack for asset bundling
25+
26+
This release addresses issues with change detection in RockPageBuilder fields. Links to issues reported [here](https://processwire.com/talk/topic/24567-fluency-the-complete-translation-enhancement-suite-for-processwire/?do=findComment&comment=249741), and [here](https://processwire.com/talk/topic/24567-fluency-the-complete-translation-enhancement-suite-for-processwire/?do=findComment&comment=249746).
27+
28+
This release also contains the fix for incorrect `href` and `hreflang` when outputting language meta tags using `$fluency->renderAltLinkLanguageMetaTags()`. [Pull Request](https://github.com/SkyLundy/Fluency/pull/19) credit to @WebWorkingMan for reporting and bugfix
29+
330
## 2.1.1 2025-03-17
431

532
### Major Bugfix. Recommended for all users

Fluency.info.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
$info = [
88
'title' => 'Fluency',
9-
'version' => '211',
9+
'version' => '220',
1010
'href' => 'https://processwire.com/talk/topic/24567-fluency-the-complete-translation-enhancement-suite-for-processwire/',
1111
'icon' => 'language',
1212
'summary' => 'The complete translation enhancement suite for ProcessWire.',
@@ -17,6 +17,7 @@
1717
'LanguageSupport',
1818
'LanguageTabs',
1919
'ProcessWire>=300',
20+
'AdminThemeUikit',
2021
'PHP>=8.1',
2122
],
2223
'permission' => 'fluency-translate',

Fluency.module.php

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ public function init()
113113
return;
114114
}
115115

116-
$this->moduleJsPath = "{$this->urls->$this}assets/scripts/";
117-
$this->moduleCssPath = "{$this->urls->$this}assets/styles/";
116+
$this->moduleJsPath = "{$this->urls->$this}assets/bundle/scripts/";
117+
$this->moduleCssPath = "{$this->urls->$this}assets/bundle/css/";
118118

119119
$this->initializeCaches();
120120
$this->initializeTranslationEngine();
@@ -289,8 +289,8 @@ private function insertAdminAssets(): void
289289
*/
290290
private function insertCoreAssets(): void
291291
{
292-
$this->config->styles->add("{$this->moduleCssPath}fluency_core.min.css");
293-
$this->config->scripts->add("{$this->moduleJsPath}fluency.bundle.js");
292+
$this->config->styles->add("{$this->moduleCssPath}fluency_core.css");
293+
$this->config->scripts->add("{$this->moduleJsPath}fluency.js");
294294
}
295295

296296
/**
@@ -299,8 +299,8 @@ private function insertCoreAssets(): void
299299
private function insertFluencyConfigPageAssets(): void
300300
{
301301
if ($this->input->get->name === 'Fluency') {
302-
$this->config->styles->add("{$this->moduleCssPath}fluency_module_config.min.css");
303-
$this->config->scripts->add("{$this->moduleJsPath}fluency_module_config.bundle.js");
302+
$this->config->styles->add("{$this->moduleCssPath}fluency_module_config.css");
303+
$this->config->scripts->add("{$this->moduleJsPath}fluency_module_config.js");
304304
}
305305
}
306306

@@ -314,8 +314,8 @@ private function insertProcessWireLanguageTranslatorAssets(): void
314314
}
315315

316316
$this->config->js('fluency', $this->getClientData());
317-
$this->config->styles->add("{$this->moduleCssPath}fluency_core.min.css");
318-
$this->config->scripts->add("{$this->moduleJsPath}fluency_language_translator.bundle.js");
317+
$this->config->styles->add("{$this->moduleCssPath}fluency_core.css");
318+
$this->config->scripts->add("{$this->moduleJsPath}fluency_language_translator.js");
319319
}
320320

321321
/**
@@ -326,8 +326,8 @@ private function insertProcessWireLanguageTranslatorAssets(): void
326326
public function insertStandaloneTranslatorAssets(): void
327327
{
328328
$this->config->js('fluency', $this->getClientData());
329-
$this->config->scripts->add("{$this->moduleJsPath}fluency_standalone_translator.bundle.js");
330-
$this->config->styles->add("{$this->moduleCssPath}fluency_standalone_translator.min.css");
329+
$this->config->scripts->add("{$this->moduleJsPath}fluency_standalone_translator.js");
330+
$this->config->styles->add("{$this->moduleCssPath}fluency_standalone_translator.css");
331331
}
332332

333333
/**
@@ -338,8 +338,8 @@ public function insertStandaloneTranslatorAssets(): void
338338
public function insertApiUsageTableFieldsetAssets(): void
339339
{
340340
$this->config->js('fluency', $this->getClientData());
341-
$this->config->scripts->add("{$this->moduleJsPath}fluency_api_usage.bundle.js");
342-
$this->config->styles->add("{$this->moduleCssPath}fluency_api_usage.min.css");
341+
$this->config->scripts->add("{$this->moduleJsPath}fluency_api_usage.js");
342+
$this->config->styles->add("{$this->moduleCssPath}fluency_api_usage.css");
343343
}
344344

345345
/**
@@ -432,6 +432,7 @@ private function getConfiguredLanguageByProcessWireId(
432432
return ConfiguredLanguageData::fromArray([
433433
'id' => $processWireId,
434434
'title' => $pwTitle,
435+
'name' => $pwLanguage->name,
435436
'default' => $pwLanguage->name === 'default',
436437
'engineLanguage' => EngineLanguageData::fromJson($configuredLanguage),
437438
'isCurrentLanguage' => $pwLanguage === $userLanguage
@@ -790,7 +791,7 @@ classes: $classes,
790791
public function renderLanguageLinks(
791792
string|array|null $classes = null,
792793
string $id = '',
793-
string $divider = null,
794+
?string $divider = null,
794795
?string $activeClass = 'active',
795796
string $languageSource = 'fluency',
796797
): string {
@@ -1192,13 +1193,13 @@ public function execute(bool $renderToString = true): InputfieldWrapper|string
11921193

11931194
$this->initializeTranslationEngine();
11941195

1195-
$wrapper->import(StandaloneTranslatorFieldset::render());
1196+
$wrapper->import(StandaloneTranslatorFieldset::getFields());
11961197

11971198
if (
11981199
$this->translationEngineIsReady() &&
11991200
$this->translationEngineInfo->providesUsageData
12001201
) {
1201-
$wrapper->import(ApiUsageTableFieldset::render(true));
1202+
$wrapper->import(ApiUsageTableFieldset::getFields(true));
12021203
}
12031204

12041205
return $renderToString ? $wrapper->render() : $wrapper;

FluencyConfig.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ public function getInputFields(): InputfieldWrapper
362362
*/
363363

364364
if ($this->engineInfo->providesUsageData) {
365-
$inputfields->import(ApiUsageTableFieldset::render());
365+
$inputfields->import(ApiUsageTableFieldset::getFields());
366366
}
367367

368368
if (!$this->engineInfo->providesUsageData) {
@@ -477,7 +477,7 @@ function ($markup, $language) {
477477
'notes' => 'Translations remain cached forever until this cache is cleared.',
478478
'columnWidth' => 50,
479479
'defaultValue' => $this->getDefaults()['translation_cache_enabled'],
480-
'description' => __('Enabling caching can help keep API usage lower and increase the speed of translation when the same content is translated more than once.'),
480+
'description' => __('Translation caching reduces API usage and increases translation speed when the same content is translated more than once.'),
481481
'checkedValue' => 1,
482482
'uncheckedValue' => 0
483483
],
@@ -508,7 +508,7 @@ function ($markup, $language) {
508508
'translatable_languages_cache_management' => [
509509
'type' => 'InputfieldMarkup',
510510
'label' => __('Translatable Languages Cache Management'),
511-
'description' => __('Fluency caches the list of languages a third party supports. If a translation service introduces a language that is not available in Fluency, clear this cache.'),
511+
'description' => __('A cache of languages the translation service in use supports. Clear this cache if a translation service introduces a language that is not available in Fluency.'),
512512
'collapsed' => Inputfield::collapsedNever,
513513
'columnWidth' => 50,
514514
'themeBorder' => 'hide',

README.md

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,18 @@ Upgrading from earlier versions to 1.0.8 and earlier may cause errors to occur.
1717

1818
For support and community discussion about Fluency, visit [the module thread in the ProcessWire forums](https://processwire.com/talk/topic/24567-fluency-the-complete-translation-enhancement-suite-for-processwire/).
1919

20+
**IMPORTANT**
21+
22+
Fluency v2.2.0 or greater is required when using DeepL as the translation service. DeepL changed their API authentication method in January of 2025 and deprecated the previous method. Translation via DeepL in versions earlier to 2.2.0 will no longer work and result in a translation service error in the UI.
23+
2024
## Contents
2125

2226
- [Requirements](#requirements)
2327
- [Installing](#installing)
2428
- [Configuring](#configuring)
2529
- [Translation Engines](#translation-engines)
2630
- [Localizing Fluency](#localizing-fluency)
31+
- [Theming Fluency](#theming-fluency)
2732
- [Upgrading or Removing](#upgrading-or-removing)
2833
- [Features and Usage](#features-and-usage)
2934
- [Translating Inputfields](#translating-inputfields)
@@ -49,6 +54,7 @@ For support and community discussion about Fluency, visit [the module thread in
4954
- [Hooking](#hooking)
5055
- [Known Issues](#known-issues)
5156
- [Contributing](#contributing)
57+
- [Coding Standards](#coding-standards)
5258
- [Cost](#cost)
5359
- [Supporting Module Development](#supporting-module-development)
5460

@@ -106,6 +112,14 @@ All text for the Fluency UI elements can be translated including messages, error
106112

107113
All translatable texts are located in `Fluency/app/FluencyLocalization.php`
108114

115+
### Theming Fluency
116+
117+
Fluency is styled to match and complement AdminThemeUikit which is active by default when you install ProcessWire. It is also configured to work with AdminThemUikit v3 which adds built-in customizability for theming. When you choose a main color, or choose a custom main color, Fluency will match your theme choices.
118+
119+
CSS for Fluency UI elements may be customized for some styles. Fluency uses [CSS custom properties](https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Cascading_variables/Using_custom_properties) for values such as color in some rules.
120+
121+
You can refrence the available custom properties that you can set values for in `Fluency/resources/css/global/ft_variables.css`
122+
109123
### Upgrading Or Removing
110124

111125
Adding, upgrading, or removing Fluency from your ProcessWire application will not affect content. At most, you _may_ (but not always) need to update or reconfigure your Fluency module config. Settings are saved individually for each translation engine, so it is possible to switch between engines without losing your configurations for each.
@@ -172,7 +186,7 @@ When content in a ProcessWire field changes, Fluency italicizes and adds a green
172186

173187
![fluency_translation_caching](https://github.com/SkyLundy/Fluency/assets/61801600/605aa092-5f72-4eab-9593-e72724892c40)
174188

175-
All translations are cached by default for a period of one month. This helps reduce API account usage where the same content is translated more than once and significantly increases translation speed. Caching can be toggled on/off on the Fluency module config page. The translation cache can also be manually cleared either on the module config page, via the [Fluency module API](#managing-cache), or via an AJAX request using the [Fluency admin REST API](#admin-rest-api-endpoints).
189+
All translations are cached indefinitely. This helps reduce API account usage where the same content is translated more than once and significantly increases translation speed. Caching may be toggled on/off on the Fluency module config page. The translation cache can also be manually cleared either on the module config page, via the [Fluency module API](#managing-cache), or via an AJAX request using the [Fluency admin REST API](#admin-rest-api-endpoints).
176190

177191
Translation caching relies on _exact_ value matching including punctuation, spelling, and capitalization. This ensures that an exact translation is always returned accurately. Translations that contain multiple strings are cached together.
178192

@@ -791,6 +805,8 @@ Note: This will only work if the language is recognized by the translation servi
791805
```php
792806
<?php namespace ProcessWire;
793807

808+
// /site/ready.php
809+
794810
use Fluency\DataTransferObjects\{EngineLanguageData, EngineTranslatableLanguagesData};
795811

796812
// Hook after Fluency gets the available languages from the DeepL API
@@ -833,10 +849,33 @@ Feature suggestions are welcome. In fact, Fluency has been made better thanks to
833849

834850
Fluency is modular in that it contains a framework for adding additional third party services as "Translation Engines". You can choose which Translation Engine you prefer and provide the credentials to connect via their API. As this project is open source, contributions for new third party services as Translation Engines are welcome. If you would like to request a new third party service, [file an issue in the Fluency GitHub repository](https://github.com/SkyLundy/Fluency/issues)
835851

836-
If you'd like to develop one for yourself, feel free to fork Fluency, build a new Translation Engine, and create a pull request.
852+
If you'd like to develop a new translation engine, feel free to fork Fluency, build a new Translation Engine, and create a pull request. Please reference
853+
854+
Every effort has been made to make Fluency robustly documented within the code. Full docblocks with information have been added in all files. Additional docblock markup that is parsed by the ProcessWire API Explorer has been added with descriptions and example usage for all primary module methods. JavaScript files are also well documented with docblocks on each method and each object. [ProDevTools](https://processwire.com/talk/store/product/22-prodevtools/)
837855

838856
Developer documentation for integrating third party translation services as Translation Engines is located in `Fluency/app/Engines/DEVDOC.md`. _Documentation is a work in progress_. If you need help or more information, feel free to send me a PM on the [ProcessWire forum](https://processwire.com/talk/).
839857

858+
### Tech Stack
859+
860+
Aside from build tools, Fluency is intentionally built without libraries and external dependencies to ensure that the module is stable long-term. Vanilla JavaScript and CSS are used exclusively. To make use of more advanced features, bundle assets, and optimize output, [Parcel](https://parceljs.org/) is used for JavaScript and CSS.
861+
862+
CSS is processed by PostCSS to add import bundling and nested rules.
863+
864+
**Using Parcel**
865+
866+
In the Fluency module directory, execute the following commands in a terminal instance for development:
867+
868+
`npm install`
869+
`npm run dev`
870+
871+
To build for production execute:
872+
873+
`npm run build`
874+
875+
### Coding Standards
876+
877+
Code contributins and bugfixes are welcome via pull requests. Please ensure that your PHP code adheres to [PSR-12 standards](https://www.php-fig.org/psr/psr-12/), JavaScript matches the common conventions followed in existing files, and CSS is formatted and clear.
878+
840879
## Cost
841880

842881
Fluency is free to use. There is no cost for this module and it can be used on any site that you build with ProcessWire. This module is provided as a thank you to the outstanding ProcessWire community and as a contribution alongside other module developers who help everyone build great websites and applications.

app/Components/ApiUsageTableFieldset.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class ApiUsageTableFieldset
1414
{
1515
use GeneratesFieldsetsTrait;
1616

17-
public static function render(bool $collapsed = false): InputfieldWrapper
17+
public static function getFields(bool $collapsed = false): InputfieldWrapper
1818
{
1919
$collapsed ? Inputfield::collapsedYes : Inputfield::collapsedNever;
2020
$uiText = FluencyLocalization::getFor('usage');

app/Components/StandaloneTranslatorFieldset.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class StandaloneTranslatorFieldset
1414
{
1515
use GeneratesFieldsetsTrait;
1616

17-
public static function render(bool $collapsed = false): InputfieldWrapper
17+
public static function getFields(bool $collapsed = false): InputfieldWrapper
1818
{
1919
$fluencyConfig = (new FluencyConfig())->getConfigData();
2020
$modules = wire('modules');
@@ -75,7 +75,7 @@ public static function render(bool $collapsed = false): InputfieldWrapper
7575
'options' => $sourceLanguageSelectOptions->options,
7676
'optionAttributes' => $sourceLanguageSelectOptions->attributes,
7777
],
78-
'ft_swap_languages' => [
78+
'ft_swap_languages_markup' => [
7979
'type' => 'InputfieldMarkup',
8080
'label' => ' ',
8181
'collapsed' => Inputfield::collapsedNever,
@@ -91,6 +91,7 @@ public static function render(bool $collapsed = false): InputfieldWrapper
9191
'name' => "swap_languages",
9292
'value' => 1,
9393
'attributes' => [
94+
'name' => 'ft_swap_languages',
9495
'icon' => 'exchange',
9596
'class' => self::appendInputfieldClasses('InputfieldSubmit', 'js-ft-swap-languages')
9697
]

0 commit comments

Comments
 (0)