TranscryptOrg / Transcrypt

Python 3.9 to JavaScript compiler - Lean, fast, open!
https://www.transcrypt.org
Apache License 2.0
2.82k stars 215 forks source link

Embedded HTML similar to JSX #834

Closed tomkcook closed 1 year ago

tomkcook commented 1 year ago

This PR currently depends on a development version of aroberge/ideas - see https://github.com/aroberge/ideas/pull/42 for the latest version.

This adds HTML embedded in Python, between delimiters >>| and |<<. HTML elements are converted into a function call to el(element_name, attrs_dict, children_list). So this function:

def some_html():
    return >>|
        <div class="div-class">
            Some Text
            <a href="http://google.com">
                A Link
            </a>
        </div>
    |<<

is rendered as:

def some_html():
    return el("div", {"class": "div-class"}, [
        "Some Text",
        el("a", {"href": "http://google.com"}, [
            "A Link"
        ])
    ])

The el() function is not provided and must be already available in the context where the HTML appears. Its signature is intended to enable this use:

react = require("react")
el = react.createElement

I'm posting this PR to get feedback; if there is a possibility it will be merged, please say so and I will add some unit tests etc and get it into proper shape. If there is no interest in this sort of PR, please let me know.

My apologies for a relatively large number of whitespace changes. My editor regularised a number of line endings and removed whitespace at the end of lines.

JennaSys commented 1 year ago

I appreciate the PR submission and what you are trying to accomplish with it, but will unfortunately have to decline it as it is adding a specific use case to Transcrypt which is intended to remain more use-case agnostic. The added dependency on the ideas library is also not ideal.

Have you looked at using the Transcrypt xtrans compiler directive to shell out to an external transpiler for the JSX? I experimented with this myself in the past and got it working on Linux, but had issues with getting it to work on Windows for some reason. If you are interested in this approach, start a new topic in the discussion area and I'll see if I can dig up the code I used for you.

Since I also use Transcrypt with React myself, I have a number of opinions/ideas on how to work with it and would welcome discussions on that topic as well. One thing in particular that I did was to create a decorator so that I didn't need to use the el()s all over the place:

def component(react_component):
    def react_element(props, *children):
        return React.createElement(react_component, props, *children)

    return react_element

This simple React tutorial demo shows it in use, and I also did a write-up on it a while back.