Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pluggable architecture #178

Open
nippur72 opened this issue Jul 31, 2016 · 2 comments
Open

pluggable architecture #178

nippur72 opened this issue Jul 31, 2016 · 2 comments

Comments

@nippur72
Copy link
Contributor

react-templates could be modified to accept "plugins" in order to increase its flexibility and extendibility.

For example an user needing a new feature could simply write a plugin in the form of a javascript module and use it to extend the way react-templates process templates.

There could be a "pre" plugin that works on the "DOM" after it's loaded and before it's processed, and a "post" plugin that is applied after the normal process.

The result of compilation should be also accessible with plugins.

@erichulburd
Copy link

I was hoping for the exact same functionality when I experienced my #185 issue. Pre/post plugins would solve that issue and many more.

I will likely be open to working on this PR it the community is open to it within the next couple of weeks. I'd close #185 as well.

@nippur72
Copy link
Contributor Author

I am already working on a PR for this, but I've put it on hold because there's another PR waiting to be reviewed that introduces lot of changes and I want to avoid merging nightmares.

Let's discuss about the possible API:

The plugin would be specified via command line with:

$ rt ... --plugin mypluginpath

myplugin should be a module that exports the following object:

interface Plugin {
   onBeforeVisit?: (node: CheerioElement) => void;  // before visiting the whole tree
   onAfterVisit?: (node: CheerioElement) => void;   // after visited the whole tree
   onBeforeTag?: (node: CheerioElement) => bool;    // visting a <tag>, before visiting its children, return false to stop visiting nodes
   onAfterTag?: (node: CheerioElement) => void;     // visting a <tag>, after visiting its children
   onStyle?: (node: CheerioElement) => void;        // visting a <style> node
   onText?: (node: CheerioElement) => void;         // visting a text node, node.data holds the text string
   onComment?: (node: CheerioElement) => void;      // visting a <!-- comment --> node

   // possibly also:
   // onAttributeExpression
   // onTextExpression

   // this is triggered after rt does its own visit
   onBeforeCode?: ({
        renderFunction: string      // the render() function as string    
        requirePaths: string[],     // list of paths to import
        AMDArguments: string[],     // argument names for AMD modules
        AMDSubstitutions: string[], // AMD argument renamed to avoid name clashes          
        vars: string[],             // imports 
        name: string                // name to give to render function when AMD or Globals
   }) => void;

   onAfterCode?: (code: string) => string;  // after the code is generated, before it's written to file

   // context object for sharing data among function calls. Comes already filled with:
   context: {
      fileName: string                              // readonly: name of source file
      html: string                                  // readonly: source HTML file as string
      currentNode: CheerioElement                   // readonly: the node currently visiting during `on` events 
   };
}

The only part that needs to be worked on is onBeforeCode() because the actual react-templates code needs refactoring due to how different module systems are emitted (in other words: it's a mess).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants