forked from liferay/liferay-portal
-
Notifications
You must be signed in to change notification settings - Fork 1
LPD-52709 Part 6: language request handler #5219
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
Open
izaera
wants to merge
11
commits into
liferay-frontend:master
Choose a base branch
from
izaera:LPD-52709-6
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
d3b9f58
LPD-52709 Remove LPD-11848 feature flag and disable LanguageFilter fo…
izaera 2503179
LPD-52709 Remove language servlet
izaera bca34ea
LPD-52709 Add configuration option for I18N labels modules
izaera 7f180ac
LPD-52709 Add a frontend resource request handler for I18N labels mod…
izaera 3578612
LPD-52709 Add tests
izaera 2f8cde4
LPD-52709 Hashify loader.js so that it can be infinitely cached
izaera 7a60653
LPD-52709 Implement translation of portlet JS files to avoid breaking…
izaera 4864b8b
LPD-52709 Support URL parameters in portlet CSS files
izaera 9842056
LPD-52709 We don't need "nocombo:" special protocol for portlet resou…
izaera 85c80e7
LPD-52709 Add/expand tests
izaera f12c4be
LPD-52709 Uncomment test
izaera File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 29 additions & 2 deletions
31
modules/apps/frontend-js/frontend-js-loader-modules-extender/build.gradle
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
99 changes: 99 additions & 0 deletions
99
...c/main/java/com/liferay/frontend/js/web/internal/resource/JavaScriptFrontendResource.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| /** | ||
| * SPDX-FileCopyrightText: (c) 2025 Liferay, Inc. https://liferay.com | ||
| * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06 | ||
| */ | ||
|
|
||
| package com.liferay.frontend.js.web.internal.resource; | ||
|
|
||
| import com.liferay.petra.io.StreamUtil; | ||
| import com.liferay.portal.kernel.language.Language; | ||
| import com.liferay.portal.kernel.util.ContentTypes; | ||
|
|
||
| import java.io.ByteArrayInputStream; | ||
| import java.io.IOException; | ||
| import java.io.InputStream; | ||
|
|
||
| import java.net.URL; | ||
|
|
||
| import java.nio.charset.StandardCharsets; | ||
|
|
||
| import java.util.ResourceBundle; | ||
|
|
||
| /** | ||
| * @author Iván Zaera Avellón | ||
| */ | ||
| public class JavaScriptFrontendResource implements FrontendResource { | ||
|
|
||
| public JavaScriptFrontendResource( | ||
| String eTag, boolean immutable, Language language, long maxAge, | ||
| ResourceBundle resourceBundle, boolean sendNoCache, URL url) { | ||
|
|
||
| if (resourceBundle != null) { | ||
| if (eTag != null) { | ||
| throw new IllegalArgumentException( | ||
| "Translated resources cannot have an eTag"); | ||
| } | ||
|
|
||
| if (immutable) { | ||
| throw new IllegalArgumentException( | ||
| "Translated resources cannot be immutable"); | ||
| } | ||
| } | ||
|
|
||
| _eTag = eTag; | ||
| _immutable = immutable; | ||
| _language = language; | ||
| _maxAge = maxAge; | ||
| _resourceBundle = resourceBundle; | ||
| _sendNoCache = sendNoCache; | ||
| _url = url; | ||
| } | ||
|
|
||
| @Override | ||
| public String getContentType() { | ||
| return ContentTypes.APPLICATION_JAVASCRIPT; | ||
| } | ||
|
|
||
| @Override | ||
| public String getETag() { | ||
| return _eTag; | ||
| } | ||
|
|
||
| @Override | ||
| public InputStream getInputStream() throws IOException { | ||
| if (_resourceBundle == null) { | ||
| return _url.openStream(); | ||
| } | ||
|
|
||
| String content = _language.process( | ||
| () -> _resourceBundle, _resourceBundle.getLocale(), | ||
| StreamUtil.toString(_url.openStream())); | ||
|
|
||
| return new ByteArrayInputStream( | ||
| content.getBytes(StandardCharsets.UTF_8)); | ||
| } | ||
|
|
||
| @Override | ||
| public long getMaxAge() { | ||
| return _maxAge; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean isImmutable() { | ||
| return _immutable; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean isSendNoCache() { | ||
| return _sendNoCache; | ||
| } | ||
|
|
||
| private final String _eTag; | ||
| private final boolean _immutable; | ||
| private final Language _language; | ||
| private final long _maxAge; | ||
| private final ResourceBundle _resourceBundle; | ||
| private final boolean _sendNoCache; | ||
| private final URL _url; | ||
|
|
||
| } |
144 changes: 144 additions & 0 deletions
144
...src/main/java/com/liferay/frontend/js/web/internal/resource/LanguageFrontendResource.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,144 @@ | ||
| /** | ||
| * SPDX-FileCopyrightText: (c) 2025 Liferay, Inc. https://liferay.com | ||
| * SPDX-License-Identifier: LGPL-2.1-or-later OR LicenseRef-Liferay-DXP-EULA-2.0.0-2023-06 | ||
| */ | ||
|
|
||
| package com.liferay.frontend.js.web.internal.resource; | ||
|
|
||
| import com.liferay.petra.string.StringPool; | ||
| import com.liferay.portal.kernel.json.JSONArray; | ||
| import com.liferay.portal.kernel.json.JSONException; | ||
| import com.liferay.portal.kernel.json.JSONFactory; | ||
| import com.liferay.portal.kernel.json.JSONObject; | ||
| import com.liferay.portal.kernel.language.Language; | ||
| import com.liferay.portal.kernel.log.Log; | ||
| import com.liferay.portal.kernel.log.LogFactoryUtil; | ||
| import com.liferay.portal.kernel.util.ContentTypes; | ||
| import com.liferay.portal.kernel.util.LocaleUtil; | ||
| import com.liferay.portal.kernel.util.StringUtil; | ||
| import com.liferay.portal.kernel.util.URLUtil; | ||
|
|
||
| import java.io.ByteArrayInputStream; | ||
| import java.io.IOException; | ||
| import java.io.InputStream; | ||
|
|
||
| import java.net.URL; | ||
|
|
||
| import java.nio.charset.StandardCharsets; | ||
|
|
||
| import java.util.Locale; | ||
|
|
||
| /** | ||
| * @author Iván Zaera Avellón | ||
| */ | ||
| public class LanguageFrontendResource implements FrontendResource { | ||
|
|
||
| public LanguageFrontendResource( | ||
| JSONFactory jsonFactory, Language language, String languageId, | ||
| long maxAge, boolean sendNoCache, URL url) { | ||
|
|
||
| _jsonFactory = jsonFactory; | ||
| _language = language; | ||
| _languageId = languageId; | ||
| _maxAge = maxAge; | ||
| _sendNoCache = sendNoCache; | ||
| _url = url; | ||
| } | ||
|
|
||
| @Override | ||
| public String getContentType() { | ||
| return ContentTypes.TEXT_JAVASCRIPT; | ||
| } | ||
|
|
||
| @Override | ||
| public String getETag() { | ||
| return null; | ||
| } | ||
|
|
||
| @Override | ||
| public InputStream getInputStream() throws IOException { | ||
| JSONArray languageKeysJSONArray = _getLanguageKeysJSONArray(); | ||
|
|
||
| StringBuilder sb = new StringBuilder(); | ||
|
|
||
| Locale locale = LocaleUtil.fromLanguageId(_languageId); | ||
|
|
||
| for (int i = 0; i < languageKeysJSONArray.length(); i++) { | ||
| String key = languageKeysJSONArray.getString(i); | ||
|
|
||
| String label = _language.get(locale, key); | ||
|
|
||
| sb.append(StringPool.APOSTROPHE); | ||
| sb.append(key.replaceAll("'", "\\\\'")); | ||
| sb.append("':'"); | ||
| sb.append(label.replaceAll("'", "\\\\'")); | ||
| sb.append("',\n"); | ||
| } | ||
|
|
||
| String content = StringUtil.replace( | ||
| _TPL_JAVA_SCRIPT, new String[] {"[$LABELS$]"}, | ||
| new String[] {sb.toString()}); | ||
|
|
||
| return new ByteArrayInputStream( | ||
| content.getBytes(StandardCharsets.UTF_8)); | ||
| } | ||
|
|
||
| @Override | ||
| public long getMaxAge() { | ||
| return _maxAge; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean isImmutable() { | ||
| return false; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean isSendNoCache() { | ||
| return _sendNoCache; | ||
| } | ||
|
|
||
| private static String _loadTemplate(String name) { | ||
| try (InputStream inputStream = | ||
| LanguageFrontendResource.class.getResourceAsStream( | ||
| "dependencies/" + name)) { | ||
|
|
||
| return StringUtil.read(inputStream); | ||
| } | ||
| catch (Exception exception) { | ||
| _log.error("Unable to read template " + name, exception); | ||
| } | ||
|
|
||
| return StringPool.BLANK; | ||
| } | ||
izaera marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| private JSONArray _getLanguageKeysJSONArray() throws IOException { | ||
| try { | ||
| JSONObject jsonObject = _jsonFactory.createJSONObject( | ||
| URLUtil.toString(_url)); | ||
|
|
||
| return jsonObject.getJSONArray("keys"); | ||
| } | ||
| catch (JSONException jsonException) { | ||
| throw new IOException( | ||
| "Invalid language JSON file " + _url, jsonException); | ||
| } | ||
| } | ||
|
|
||
| private static final String _TPL_JAVA_SCRIPT; | ||
|
|
||
| private static final Log _log = LogFactoryUtil.getLog( | ||
| LanguageFrontendResource.class); | ||
|
|
||
| static { | ||
| _TPL_JAVA_SCRIPT = _loadTemplate("all.js.tpl"); | ||
| } | ||
|
|
||
| private final JSONFactory _jsonFactory; | ||
| private final Language _language; | ||
| private final String _languageId; | ||
| private final long _maxAge; | ||
| private final boolean _sendNoCache; | ||
| private final URL _url; | ||
|
|
||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.