mjml icon indicating copy to clipboard operation
mjml copied to clipboard

Right to Left support

Open hadifarnoud opened this issue 8 years ago • 28 comments

I could not find anything on RTL support.

hadifarnoud avatar May 06 '16 13:05 hadifarnoud

hey @hadifarnoud, maybe you can help us implement RTL support?

Would love to see how we can do that or even better, a contribution from your side?

ngarnier avatar May 09 '16 15:05 ngarnier

Sure! let me know where to begin and what to do. I'm not how you guys are going to add that to mjml.

hadifarnoud avatar May 10 '16 05:05 hadifarnoud

We have no specific experience with RTL support; do you? We would love to benefit from someone's experience on this!

ngarnier avatar May 16 '16 15:05 ngarnier

I do @ngarnier. It's easy to do with direction:rtl and text-align:right in CSS. just implement something and I'll help test and refine it :)

hadifarnoud avatar May 24 '16 07:05 hadifarnoud

Hey @hadifarnoud, thanks for your answer!

RTL's not the priority right now as we're working on incremental improvements and new features (especially components) but we'll welcome any contribution to support it!

ngarnier avatar May 26 '16 09:05 ngarnier

I can see how RTL would be useful especially for transactional messaging and B2C messages. Would be a great attribute to add to miml-text component direction="l2r" or "direction="r2l" with probably "l2r" being the default.

Would it be more useful to add it to the whole column? I can see that being useful but it may break other things where as adding it to the text should be safe.

@ngarnier We need an "MJML Labs" where we can see components that are in progress ;)

f4f343w4tcfwv4tz5tb5 avatar Jun 02 '16 19:06 f4f343w4tcfwv4tz5tb5

It could be used in column, text, invoice, button, hero, and table. 

If someone does it for one of these, I can figure out how to do it for others. 

On Thu, 02 Jun 2016 at 23:30 zrb0529

< mailto:zrb0529 [email protected]

wrote:

I can see how RTL would be useful especially for transactional messaging and B2C messages. Would be a great attribute to add to miml-text component direction="l2r" or "direction="r2l" with probably "l2r" being the default.

Would it be more useful to add it to the whole column? I can see that being useful but it may break other things where as adding it to the text should be safe.

https://github.com/ngarnier We need an "MJML Labs" where we can see components that are in progress ;)

You are receiving this because you were mentioned.

Reply to this email directly, https://github.com/mjmlio/mjml/issues/230#issuecomment-223389167 , or https://github.com/notifications/unsubscribe/AAj_8MiIcY52jZItqeOzDL6n7Ow9-irBks5qHyg_gaJpZM4IY4z_ .

https://github.com/mjmlio/mjml/issues/230#issuecomment-223389167

hadifarnoud avatar Jun 02 '16 20:06 hadifarnoud

Indeed, the best way would probably to add a direction attribute that would be set to l2r by default to text components such as text and button (mj-attributes would then help setting it a default direction).

@zrb0529, one way to see what we're working on is to check the Work in Progress label :-)

ngarnier avatar Jun 03 '16 08:06 ngarnier

I used the following as a workaround to generate an RTL template.

  <mj-head>
    <mj-style>
      * { direction: rtl; text-align: right !important; }
    </mj-style>
  </mj-head>

of course you can define more granular css rules if you want only some elements to be rtl.
In general - I would expect a direction="ltr" attribute to just add an inline style direction:rtl;
or a dir="rtl" attribute to generated html the element.

I don't know much about MJML (yet) as I just started using it today, but I would be happy to contribute in the future.

rubinsh avatar Feb 21 '17 11:02 rubinsh

That's actually a very nice workaround, thanks for sharing @rubinsh! Just a quick note, you might want to add inline="inline" as an attribute to mj-style so it's inlined instead of added in the head.

  <mj-head>
    <mj-style inline="inline">
      * { direction: rtl; text-align: right !important; }
    </mj-style>
  </mj-head>

ngarnier avatar Feb 22 '17 08:02 ngarnier

nice to have a workaround for now. still, would be cool to have rtl natively

hadifarnoud avatar Mar 07 '17 08:03 hadifarnoud

this method overrides text align everywhere. even if I set align="center". any idea how to fix it?

hadifarnoud avatar Apr 16 '17 08:04 hadifarnoud

@hadifarnoud did you try
text-align: center !important

rubinsh avatar Apr 16 '17 10:04 rubinsh

I have but still the other one seems to be considered

hadifarnoud avatar Apr 16 '17 12:04 hadifarnoud

When is this issue planed to be developed? Thanks!

aganglada avatar Nov 07 '17 11:11 aganglada

Well the best workaround is to use mj-style with css-class as said earlier.

I don't think we can go deeper than this (adding an attribute on every component would be painful to manage ?)

iRyusa avatar Nov 07 '17 11:11 iRyusa

I think adding RTL support is very important. without that this framework cannot be used in many big projects that have to support multiple languages. the current solution is a dirty fix. attribute is more clean way of doing it

hadifarnoud avatar Nov 07 '17 14:11 hadifarnoud

Only issue is, an rtl attribute would conflict with most of align attribute i think ? We might need a little help with starting a PR on this one and trying some implementation so we could discuss on it.

iRyusa avatar Nov 07 '17 14:11 iRyusa

Is there a way to make direction="rtl" applied to a section, work in grouped columns too? Right now it seems it doesn't work: https://mjml.io/try-it-live/SkXSfqCPE

damianvila avatar Mar 19 '19 16:03 damianvila

@damianvila direction only applies on section's direct children, but for what you want you can set direction on mj-group

kmcb777 avatar Mar 19 '19 16:03 kmcb777

@kmcb777 That seems to be undocumented, right? It works, though. Thanks!

damianvila avatar Mar 22 '19 09:03 damianvila

@damianvila, i was looking for support on this as well. I found out the only ~hack~ way is to add in the direction: bla bla property in the compiled html, instead of mjml directly.

lucidkodo avatar Jun 26 '19 01:06 lucidkodo

any news on this?

isaaacme avatar Aug 30 '21 01:08 isaaacme

you don't see the docs update? they added the support https://documentation.mjml.io/#mj-group

hadifarnoud avatar Aug 30 '21 06:08 hadifarnoud

right to left text isn't the same as direction attribute on group/section as it's only here to control the display order on mobile/desktop.

No one in the team is experienced with RTL text support, so we're open on PR here. There's a chance that everything can be done exclusively in CSS with mj-style or with inline style but if there's anything that can be done to improve this for non LTR then let's go for it

iRyusa avatar Aug 30 '21 13:08 iRyusa

Usually it's enough to introduce "logical" units instead of physical. Examples are start/end instead of left/right. Then this logical units might be swapped when you switch between rtl/ltr version. This is how actual web standarts handle this issue. CSS Logical Properties, also Flexbox and Grid avoiding any physical units in favor of 'flex-end/flex-start' etc.

I'm using mjml with a preprocessor, and implemented RTL this way:

<mj-head>
  <mj-style inline="inline">
      * { direction: <%~ it.dir %>; }
  </mj-style>
  <mj-attributes>
     <!--Overrides defaults on mj-text -->
     <mj-text align="<%~ it.dir == 'ltr' ? 'left' : 'right' %>"/>

     <!-- Introduce Logical Start/End-->
     <mj-class name="align-start" align="<%~ it.dir == 'ltr' ? 'left' : 'right' %>"/>
     <mj-class name="align-end"   align="<%~ it.dir != 'ltr' ? 'left' : 'right' %>"/>
  </mj-attributes>

  <mj-body>
     <!-- Use logical units instead of physical left/right -->
    <mj-image  mj-class="align-start"  ...  />
  </mj-body>
</mj-head>

timofei-iatsenko avatar Mar 17 '22 13:03 timofei-iatsenko

@thekip I like that approach. Which preprocessor are you using?

Cuhadari-Deniz avatar Jul 27 '23 07:07 Cuhadari-Deniz

I'm using Eta

Here is our snippet:

import * as Eta from 'eta';
import mjml2html from 'mjml';

async function renderFileToString(
  filePath: string,
  overrideFolder: string,
  data: unknown,
): Promise<string> {
  let mjmlFull: string;

  try {
    mjmlFull = (await Eta.renderFileAsync(filePath, data, {
      views: [overrideFolder, basePath],
    })) as string;
  } catch (e) {
    console.error('Error while parsing Eta template :', filePath, overrideFolder, e as any);
    process.exit(1);
  }

  const html = mjml2html(mjmlFull, {
    fonts: {},
    actualPath: filePath,
  });

  if (html.errors.length) {
    html.errors.forEach((error) => {
      console.error(error.formattedMessage + '\n');
    });

    process.exit(1);
  }

  return html.html;
}

Logic with "overrides" is related to our app, you can omit it.

timofei-iatsenko avatar Jul 27 '23 08:07 timofei-iatsenko