Skip to content

Commit

Permalink
Handle translations in the webpack devel server
Browse files Browse the repository at this point in the history
  • Loading branch information
lslezak committed Jul 31, 2023
1 parent 4921861 commit 7810d34
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 1 deletion.
2 changes: 1 addition & 1 deletion web/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<!--
The Cockpit server returns "po.<LANG>.js" content for the "po.js" request,
the requested language is obtained from the "CockpitLang" cookie sent in
the HTTP header. For missing translations it returns an empty string.
the HTTP header. For missing translation files it returns an empty script.
-->
<script src="po.js" defer></script>
</body>
Expand Down
33 changes: 33 additions & 0 deletions web/src/lib/webpack-po-handler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const fs = require("fs");
const path = require("path");

// Cockpit internally returns the "po.<LANG>.js" file content for the
// "po.js" request, reimplement it with a simple redirection (the JS file
// only exists in the webpack memory, we cannot read it from disk)
//
// This function processes the webpack HTTP request.
//
// @param req HTTP request
// @param res HTTP response
module.exports = function (req, res) {
// the regexp was taken from the original Cockpit code :-)
const language = req.headers.cookie.replace(/(?:(?:^|.*;\s*)CockpitLang\s*=\s*([^;]*).*$)|^.*$/, "$1") || "";
// the cookie uses "pt-br" format while the PO file is "pt_BR" :-/
let [lang, country] = language.split("-");
country = country.toUpperCase();

// first check the full locale ("pt_BR") PO file
if (fs.existsSync(path.join(__dirname, "..", "..", "po", `${lang}_${country}.po`))) {
res.redirect(`/po.${lang}_${country}.js`);
} else {
// then check the language part only ("pt") PO file
if (fs.existsSync(path.join(__dirname, "..", "..", "po", `${lang}.po`))) {
res.redirect(`/po.${lang}.js`);
} else {
if (lang !== "en") console.log(`translation "${language}" not found`);
// Cockpit returns an empty script if the translation file is missing
res.set("Content-Type", "application/javascript");
res.send("");
}
}
};
7 changes: 7 additions & 0 deletions web/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const StylelintPlugin = require('stylelint-webpack-plugin');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const webpack = require('webpack');
const po_handler = require("./src/lib/webpack-po-handler");

/* A standard nodejs and webpack pattern */
const production = process.env.NODE_ENV === 'production';
Expand Down Expand Up @@ -114,6 +115,12 @@ module.exports = {
// hot replacement does not support wss:// transport when running over https://,
// as a workaround use sockjs (which uses standard https:// protocol)
webSocketServer: "sockjs",

// Cockpit handles the "po.js" requests specially
setupMiddlewares: (middlewares, devServer) => {
devServer.app.get("/po.js", (req, res) => po_handler(req, res));
return middlewares;
}
},
devtool: "source-map",
stats: "errors-warnings",
Expand Down

0 comments on commit 7810d34

Please sign in to comment.