Skip to content

Instantly share code, notes, and snippets.

@carmelodevuz
Last active May 29, 2024 22:36
Show Gist options
  • Save carmelodevuz/b2c50883a8d164aa4a13c53056caf568 to your computer and use it in GitHub Desktop.
Save carmelodevuz/b2c50883a8d164aa4a13c53056caf568 to your computer and use it in GitHub Desktop.
Keenthemes Metronic 8.038 RTL

RTL

  1. In file '/angular/demo{#}/src/assets/sass/style.angular.scss' comment the next rows [8, 9]:
  // @import "./core/vendors/plugins/prismjs";
  // @import "./core/vendors/plugins/formvalidation";

!!! THESE TWO PLUGINS AREN'T RTL READY !!!

  1. Add 'rtl.config.js' file into project (path should be: '/angular/demo{#}/rtl.config.js').

  2. In file 'package.json' add the next 'devDependencies':

"@types/sass-loader": "8.0.3",
"css-loader": "6.7.1",
"del": "6.0.0",
"mini-css-extract-plugin": "2.6.1",
"sass-loader": "13.0.2",
"webpack": "5.74.0",
"webpack-cli": "4.10.0"
  1. In file 'package.json' add the next scripts command:
"rtl": "webpack --config=rtl.config.js"
  1. Find and replace next attributes in the project: data-kt-menu-placement="bottom-start" => data-kt-menu-placement="bottom-end" data-kt-menu-placement="right-start" => data-kt-menu-placement="left-start"

  2. Run:

yarn install
  1. In file '/angular/demo{#}/src/index.html' change 'body' tag:
<body root id="kt_body" class="mat-typography" direction="rtl" dir="rtl" style="direction: rtl">
  1. Run:
yarn run rtl

!!! SHOULD CREATE THE NEXT FILE: '/angular/demo{#}/src/assets/css/style.rtl.css'. !!!

  1. In file '/angular/demo{#}/src/styles.scss' file change RTL import to the LTL one (row 2):
/* You can add global styles to this file, and also import other style files */
// @import "./assets/sass/style.scss";
// Replace above style with this css file to enable RTL styles
// @import './assets/sass/plugins.scss';
@import "./assets/css/style.rtl.css";
@import "./assets/sass/style.angular.scss";
  1. Run:
ng serve
const path = require('path')
const del = require('del')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const RtlCssPlugin = require('rtlcss-webpack-plugin')
// global variables
const rootPath = path.resolve(__dirname)
const distPath = rootPath + '/src/assets'
const entries = {
"css/style": "./src/assets/sass/style.scss",
}
// remove older folders and files
;(async () => {
await del(distPath + '/css', {force: true})
})()
module.exports = {
mode: 'development',
stats: 'verbose',
performance: {
hints: 'error',
maxAssetSize: 10000000,
maxEntrypointSize: 4000000,
},
entry: entries,
output: {
// main output path in assets folder
path: distPath,
// output path based on the entries' filename
filename: '[name].js',
},
resolve: {
extensions: ['.scss'],
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].rtl.css',
}),
new RtlCssPlugin({
filename: '[name].rtl.css',
}),
{
apply: (compiler) => {
// hook name
compiler.hooks.afterEmit.tap('AfterEmitPlugin', () => {
;(async () => {
await del(distPath + '/css/*.js', {force: true})
})()
})
},
},
],
module: {
rules: [
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'sass-loader',
options: {
sourceMap: true,
},
},
],
},
],
},
}
@obed-scriptit
Copy link

yarn run rtl
yarn run v1.22.19
$ webpack --config webpack-rtl.config.js
[webpack-cli] Failed to load '/Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/webpack-rtl.config.js' config
[webpack-cli] Error: Cannot find module 'del'
Require stack:

  • /Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/webpack-rtl.config.js
  • /Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/node_modules/webpack-cli/lib/webpack-cli.js
  • /Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/node_modules/webpack-cli/lib/bootstrap.js
  • /Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/node_modules/webpack-cli/bin/cli.js
  • /Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/node_modules/webpack/bin/webpack.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
    at Function.Module._load (node:internal/modules/cjs/loader:778:27)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object. (/Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/webpack-rtl.config.js:10:13)
    at Module._compile (node:internal/modules/cjs/loader:1105:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19) {
    code: 'MODULE_NOT_FOUND',
    requireStack: [
    '/Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/webpack-rtl.config.js',
    '/Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/node_modules/webpack-cli/lib/webpack-cli.js',
    '/Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/node_modules/webpack-cli/lib/bootstrap.js',
    '/Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/node_modules/webpack-cli/bin/cli.js',
    '/Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/node_modules/webpack/bin/webpack.js'
    ]
    }
    error Command failed with exit code 2.
    info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

@obed-scriptit
Copy link

npm install del

npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve
npm ERR!
npm ERR! While resolving: @angular-eslint/schematics@13.2.1
npm ERR! Found: @angular/cli@14.0.0
npm ERR! node_modules/@angular/cli
npm ERR! dev @angular/cli@"14.0.0" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer @angular/cli@">= 13.0.0 < 14.0.0" from @angular-eslint/schematics@13.2.1
npm ERR! node_modules/@angular-eslint/schematics
npm ERR! dev @angular-eslint/schematics@"13.2.1" from the root project
npm ERR!
npm ERR! Conflicting peer dependency: @angular/cli@13.3.9
npm ERR! node_modules/@angular/cli
npm ERR! peer @angular/cli@">= 13.0.0 < 14.0.0" from @angular-eslint/schematics@13.2.1
npm ERR! node_modules/@angular-eslint/schematics
npm ERR! dev @angular-eslint/schematics@"13.2.1" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR! See /Users/ahmedalobed/.npm/eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
npm ERR! /Users/ahmedalobed/.npm/_logs/2022-08-04T07_47_44_888Z-debug-0.log

@obed-scriptit
Copy link

yarn run rtl
yarn run v1.22.19
$ webpack --config webpack-rtl.config.js
[webpack-cli] Failed to load '/Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/webpack-rtl.config.js' config
[webpack-cli] Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/node_modules/del/index.js from /Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/webpack-rtl.config.js not supported.
Instead change the require of index.js in /Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/webpack-rtl.config.js to a dynamic import() which is available in all CommonJS modules.
at Object. (/Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/webpack-rtl.config.js:10:13)
at async Promise.all (index 0)
at async WebpackCLI.tryRequireThenImport (/Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/node_modules/webpack-cli/lib/webpack-cli.js:254:18)
at async loadConfigByPath (/Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/node_modules/webpack-cli/lib/webpack-cli.js:1712:19)
at async Promise.all (index 0)
at async WebpackCLI.loadConfig (/Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/node_modules/webpack-cli/lib/webpack-cli.js:1765:29)
at async WebpackCLI.createCompiler (/Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/node_modules/webpack-cli/lib/webpack-cli.js:2187:18)
at async WebpackCLI.runWebpack (/Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/node_modules/webpack-cli/lib/webpack-cli.js:2323:16)
at async Command. (/Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/node_modules/webpack-cli/lib/webpack-cli.js:1060:13)
at async Promise.all (index 1)
at async Command. (/Users/ahmedalobed/Documents/script_projects/metronic-edunet-master/node_modules/webpack-cli/lib/webpack-cli.js:1674:7) {
code: 'ERR_REQUIRE_ESM'
}
error Command failed with exit code 2.

@carmelodevuz
Copy link
Author

I've updated the config file and packages versions.

@shakoorattari
Copy link

Is it working now?

@naji-makhoul
Copy link

npm run rtl

demo1@8.1.7 rtl
webpack --config rtl.config.js

[webpack-cli] Failed to load 'C:\00\metronic_angular_v8.1.8_demo1\metronic_angular_v8.1.8_demo1\demo1\rtl.config.js' config
[webpack-cli] Error [ERR_REQUIRE_ESM]: require() of ES Module C:\00\metronic_angular_v8.1.8_demo1\metronic_angular_v8.1.8_demo1\demo1\node_modules\del\index.js from C:\00\metronic_angular_v8.1.8_demo1\metronic_angular_v8.1.8_demo1\demo1\rtl.config.js not supported.
Instead change the require of index.js in C:\00\metronic_angular_v8.1.8_demo1\metronic_angular_v8.1.8_demo1\demo1\rtl.config.js to a dynamic import() which is available in all CommonJS modules.
at Object. (C:\00\metronic_angular_v8.1.8_demo1\metronic_angular_v8.1.8_demo1\demo1\rtl.config.js:2:11) {
code: 'ERR_REQUIRE_ESM'
}

@said-grich
Copy link

260 | // Exports
261 | /* harmony default export */ const WEBPACK_DEFAULT_EXPORT = (CSS_LOADER_EXPORT);
262 |
at processResult (C:\Users\Dev5\thaoffices\demo2\node_modules\webpack\lib\NormalModule.js:758:19)
at C:\Users\Dev5\thaoffices\demo2\node_modules\webpack\lib\NormalModule.js:860:5
at C:\Users\Dev5\thaoffices\demo2\node_modules\loader-runner\lib\LoaderRunner.js:400:11
at C:\Users\Dev5\thaoffices\demo2\node_modules\loader-runner\lib\LoaderRunner.js:195:20
at context.callback (C:\Users\Dev5\thaoffices\demo2\node_modules\loader-runner\lib\LoaderRunner.js:124:13)
at C:\Users\Dev5\thaoffices\demo2\node_modules\mini-css-extract-plugin\dist\loader.js:275:9
at C:\Users\Dev5\thaoffices\demo2\node_modules\webpack\lib\dependencies\LoaderPlugin.js:208:27
at C:\Users\Dev5\thaoffices\demo2\node_modules\webpack\lib\Compilation.js:5092:17
at symbolIterator (C:\Users\Dev5\thaoffices\demo2\node_modules\neo-async\async.js:3485:9)
at process.processTicksAndRejections (node:internal/process/task_queues:77:11)

@ADNANALK
Copy link

ADNANALK commented May 11, 2023

Hi, I fix the issue by updating the rtl.config.js file. even if you got some warning when you run rtl command, it should be working well
Here is the update:
rtl.config.js
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const RtlCssPlugin = require('rtlcss-webpack-plugin');

// global variables
const rootPath = path.resolve(__dirname);
const distPath = rootPath + '/src/assets';
const entries = {
"css/style": "./src/assets/sass/style.scss",
};

module.exports = {
mode: 'development',
stats: 'verbose',
performance: {
hints: 'error',
maxAssetSize: 10000000,
maxEntrypointSize: 4000000,
},
entry: entries,
output: {
// main output path in assets folder
path: distPath,
// output path based on the entries' filename
filename: '[name].js',
},
resolve: {
extensions: ['.scss'],
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].rtl.css',
}),
new RtlCssPlugin({
filename: '[name].rtl.css',
}),
{
apply: (compiler) => {
// hook name
compiler.hooks.afterEmit.tap('AfterEmitPlugin', async (compilation) => {
const delModule = await import('del');
await delModule.default(distPath + '/css/*.js', { force: true });
await delModule.default(distPath + '/css', { force: true });
});
},
},
],
module: {
rules: [
{
test: /.scss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'sass-loader',
options: {
sourceMap: true,
},
},
],
},
],
},
};
image

@said-grich
Copy link

Hi, I fix the issue by updating the rtl.config.js file. even if you got some warning when you run rtl command, it should be working well Here is the update: rtl.config.js const path = require('path'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const RtlCssPlugin = require('rtlcss-webpack-plugin');

// global variables const rootPath = path.resolve(__dirname); const distPath = rootPath + '/src/assets'; const entries = { "css/style": "./src/assets/sass/style.scss", };

module.exports = { mode: 'development', stats: 'verbose', performance: { hints: 'error', maxAssetSize: 10000000, maxEntrypointSize: 4000000, }, entry: entries, output: { // main output path in assets folder path: distPath, // output path based on the entries' filename filename: '[name].js', }, resolve: { extensions: ['.scss'], }, plugins: [ new MiniCssExtractPlugin({ filename: '[name].rtl.css', }), new RtlCssPlugin({ filename: '[name].rtl.css', }), { apply: (compiler) => { // hook name compiler.hooks.afterEmit.tap('AfterEmitPlugin', async (compilation) => { const delModule = await import('del'); await delModule.default(distPath + '/css/*.js', { force: true }); await delModule.default(distPath + '/css', { force: true }); }); }, }, ], module: { rules: [ { test: /.scss$/, use: [ MiniCssExtractPlugin.loader, 'css-loader', { loader: 'sass-loader', options: { sourceMap: true, }, }, ], }, ], }, }; image

hi ADNANALK i try with your solution but i steal have the same prob :
image

@said-grich
Copy link

@ADNANALK can you please explain more

@AliHaydari
Copy link

Hi
For me, these errors are due to "del": "7.0.0" in package.json file
according this release note we must use 6 version because in 7 has breaking change to use pure esm.
change del package version to 6 and run yarn run rtl

@shakoorattari
Copy link

shakoorattari commented May 31, 2023

I've updated the rtl.config.js file. If someone needs.


const path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const RtlCssPlugin = require('rtlcss-webpack-plugin')

// global variables
const rootPath = path.resolve(__dirname)
const distPath = rootPath + '/src/assets'
const entries = {
  "css/style": "./src/assets/sass/style.scss",
}

module.exports = {
  mode: 'development',
  stats: 'verbose',
  performance: {
    hints: 'error',
    maxAssetSize: 10000000,
    maxEntrypointSize: 4000000,
  },
  entry: entries,
  output: {
    // main output path in assets folder
    path: distPath,
    // output path based on the entries' filename
    filename: '[name].js',
  },
  resolve: {
    extensions: ['.scss'],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].rtl.css',
    }),
    new RtlCssPlugin({
      filename: '[name].rtl.css',
    }),
    {
      apply: (compiler) => {
        // hook name
        compiler.hooks.afterEmit.tap('AfterEmitPlugin', async () => {
          const del = await import('del');
          await del.default(distPath + '/css/*.js', { force: true });
        });
      },
    },
  ],
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          {
            loader: 'sass-loader',
            options: {
              sourceMap: true,
            },
          },
        ],
      },
    ],
  },
}

@Unknown1125
Copy link

Unknown1125 commented Oct 21, 2023

please can you help me @shakoorattari
I want to add this import

  <link rel="stylesheet" href="./assets/sass/style.scss">
  <link rel="stylesheet" href="./assets/sass/plugins.scss">

by condition to index.html in angular

but it's not work

I want to change style to rtl or ltr by selected language so i change import scss file in index.html

style rtl is

<link rel="stylesheet" href="./assets/sass/style.angular.scss">
<link rel="stylesheet" href="./assets/css/style.rtl.css">

style ltr is

<link rel="stylesheet" href="./assets/sass/style.scss">
<link rel="stylesheet" href="./assets/sass/plugins.scss">

@Amir-MP
Copy link

Amir-MP commented Oct 21, 2023

worked fine , didn't create CSS RTL but did the job , thanks

@castell0riz0n
Copy link

please can you help me @shakoorattari I want to add this import

  <link rel="stylesheet" href="./assets/sass/style.scss">
  <link rel="stylesheet" href="./assets/sass/plugins.scss">

by condition to index.html in angular

but it's not work

I want to change style to rtl or ltr by selected language so i change import scss file in index.html

style rtl is

<link rel="stylesheet" href="./assets/sass/style.angular.scss">
<link rel="stylesheet" href="./assets/css/style.rtl.css">

style ltr is

<link rel="stylesheet" href="./assets/sass/style.scss">
<link rel="stylesheet" href="./assets/sass/plugins.scss">

If you want to conditionally inject styles based on your language, you can follow these steps:

  1. In your angular.json file, add the following lines to the styles array:

    {
      "input": "src/assets/scss/style.rtl.css",
      "bundleName": "rtl",
      "inject": false
    },
    {
      "input": "src/assets/scss/style.scss",
      "bundleName": "ltr",
      "inject": false
    }
  2. In app.component.ts, add the following function:

    loadStyle() {
      this.currentLang = this.localization.currentLanguage;
      this.direction = this.currentLang.isRightToLeft ? 'rtl.css' : 'ltr.css';
    
      const html = this.document.getElementsByTagName('html')[0];
      html.dir = this.currentLang.isRightToLeft ? 'rtl' : 'ltr';
    
      const body = this.document.getElementsByTagName('body')[0];
      body.dir = this.currentLang.isRightToLeft ? 'rtl' : 'ltr';
    
      const head = this.document.getElementsByTagName('head')[0];
      let themeLink = this.document.getElementById('client-theme') as HTMLLinkElement;
    
      if (themeLink) {
        themeLink.href = this.direction;
      } else {
        const style = this.document.createElement('link');
        style.id = 'client-theme';
        style.rel = 'stylesheet';
        style.href = `${this.direction}`;
        head.appendChild(style);
      }
    }
  3. Finally, change the constructor to something like this:

    direction: 'rtl.css' | 'ltr.css';
    
    constructor(
      @Inject(DOCUMENT) private document: Document,
    ) {
      this.loadStyle();
    }

If you have any further questions, feel free to ask!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment