- Start Date: 2022-01-22
- Implementation PR: (leave this empty)
- Evan's insanity spiral: 1/4
Summary
This RFC defines a configuration option to make astro viable in applications where custom elements and delimiters are needed.
Definitions
In <%= hi %>
,
- startDelimiter:
<%
- value:
= hi
- endDelimiter:
%>
Motivation
This RFC was driven by the lack of support for EJS style templating. This style of templates uses <%
, invalid html that astro correctly flags. It would be counterproductive to provide an exception to users of EJS, so I began thinking about how this need I have can be applied to needs others have. Through this RFC, users of templating engines regardless of what one they use feel first class.
In part two, this is extended to make templating support even better, and to introduce new renderers for executing code.
Levels
This RFC has been split into two levels, however both levels have multiple implementation steps that can be completed individually. Level one is more pressing than two.
-
Level one introduces basic support and language server support
- It works!
- Language server support
-
Level two adds support for renderers
- Base render support
- File name change API
Level One
Example
<%= hi %> <!-- This does not crash astro now, it also is syntax highlighted like ejs templates would be -->
<em>(Unsupported content elided by the Agora.)</em>{{This is its own thing, not javascript}}<em>(Unsupported content elided by the Agora.)</em>
Detailed design
In an implementation of this design, the config object is extended to introduce a new property
interface CustomElement {
/** RegExp for opening tag, closing tag
*
* For example, if you want to make `<% hi! %>` valid, you would set match to be `[/<%/,/%>/]`
*
* Or, if you wanted to do something more complex, say `<😂 to="the" world>:)</😂>`, you could write a regexp like `[/<😂.*?>/,/<\/😂>/]`
*/
delimiters: [RegExp,RegExp]
/**
* Syntax Highlighting Language
*
* Examples: `typescript`, `ejs`, `handlebars`
*/
language: string,
/**
* Include delimiters in output
*
* true: `<% Value %>`,
*
* false: ` Value `
*
* default: true
*/
includeDelimiters?: boolean
}
interface Options {
...
/**
* Define custom delimiters for syntax highlighting and telling the compiler to leave you alone.
*/
CustomElements?: [CustomElement]
}
There are actions taken in two places
Compiler
For delimiters that match, the compiler essentially leaves it be, so the output will be if (includeDelimiters) startDelimiter + value + if(includeDelimiters) endDelimiter
, it then stops processing and should not do any transformation of matched content.
This is effectively the same as <Fragment data-astro-raw>startDelimiter value endDelimiter </Fragement>
(Note: data-astro-raw
is currently broken, see compiler/#263)
Language Server
The contents within matched delimiters are syntax highlighted as specified in language
Additionally, while the API is subject to discussion, renderers should be able to instruct a built file's extension to be whatever it pleases instead of html
.
Drawbacks
- None
Alternatives
- None
Adoption strategy
There is little adoption cost. In terms of strategy, it should be implemented in consecutive order (level 1 bullet 1, level 1 bullet 2, level 2 bullet 1, etc). Level one bullet one (It works!) is high priority, numerous users on discord have asked about this and have been provided hacky solutions like changing delimiters
- public document at doc.anagora.org/custom-elements
- video call at meet.jit.si/custom-elements