Skip to content

Commit

Permalink
fix #2026 allow to include css files
Browse files Browse the repository at this point in the history
  • Loading branch information
kmcb777 committed Feb 18, 2021
1 parent 15ba069 commit bafb24a
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
11 changes: 11 additions & 0 deletions doc/components_2.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,16 @@ You can wrap your external mjml files inside the default `mjml > mj-body`
</mjml>
```

You can also include external `css` files. They will be inserted the same way as when using a `mj-style`.
You need to specify that you're including a css file using the `type="css"` attribute.
If you want the css to be inlined, you can use the `css-inline="inline"` attribute.

```xml
<!-- main.mjml -->
<mj-include path="./styles.css" type="css" />
<mj-include path="./inline-styles.css" type="css" css-inline="inline" />
```


The `MJML` engine will then replace your included files before starting
the rendering process.
66 changes: 66 additions & 0 deletions packages/mjml-parser-xml/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,53 @@ export default function MJMLParser(xml, options = {}, includedIn = []) {
let cur = null
let inInclude = !!includedIn.length
let inEndingTag = 0
const cssIncludes = []
const currentEndingTagIndexes = { startIndex: 0, endIndex: 0 }

const findTag = (tagName, tree) => find(tree.children, { tagName })
const lineIndexes = indexesForNewLine(xml)

const handleCssInclude = (file, attrs, line) => {
const partialPath = path.resolve(cwd, file)
let content
try {
content = fs.readFileSync(partialPath, 'utf8')
} catch (e) {
const newNode = {
line,
file,
absoluteFilePath: path.resolve(cwd, actualPath),
parent: cur,
tagName: 'mj-raw',
content: `<!-- mj-include fails to read file : ${file} at ${partialPath} -->`,
children: [],
errors: [
{
type: 'include',
params: { file, partialPath },
},
],
}
cur.children.push(newNode)

return
}

const attributes =
attrs['css-inline'] === 'inline' ? { inline: 'inline' } : {}

const newNode = {
line,
file,
absoluteFilePath: path.resolve(cwd, actualPath),
tagName: 'mj-style',
content,
children: [],
attributes,
}
cssIncludes.push(newNode)
}

const handleInclude = (file, line) => {
const partialPath = path.resolve(cwd, file)
const curBeforeInclude = cur
Expand Down Expand Up @@ -181,6 +223,11 @@ export default function MJMLParser(xml, options = {}, includedIn = []) {
if (name === 'mj-include') {
if (ignoreIncludes || !isNode) return

if (attrs.type === 'css') {
handleCssInclude(decodeURIComponent(attrs.path), attrs, line)
return
}

inInclude = true
handleInclude(decodeURIComponent(attrs.path), line)
return
Expand Down Expand Up @@ -289,5 +336,24 @@ export default function MJMLParser(xml, options = {}, includedIn = []) {
setEmptyAttributes(mjml)
}

if (cssIncludes.length) {
const head = find(mjml.children, { tagName: 'mj-head' })

if (head) {
if (head.children) {
head.children = [...head.children, ...cssIncludes]
} else {
head.children = cssIncludes
}
} else {
mjml.children.push({
file: filePath,
line: 0,
tagName: 'mj-head',
children: cssIncludes,
})
}
}

return mjml
}

0 comments on commit bafb24a

Please sign in to comment.