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

Syntax similar to JSX #918

Open
Archmonger opened this issue Feb 9, 2023 · 13 comments
Open

Syntax similar to JSX #918

Archmonger opened this issue Feb 9, 2023 · 13 comments
Labels
priority-2-moderate Should be resolved on a reasonable timeline.

Comments

@Archmonger
Copy link
Contributor

Archmonger commented Feb 9, 2023

Current Situation

ReactJS has a method of HTML templating called JSX. We currently do not have an equivalent.

There is a WIP tag string PEP that proposes adding template literals to Python. We will need this to write JSX in Python in the same way it has been used to do so in Javascript.

While the tag string PEP remains in development, an interim transpiler has been proposed that would allow us to use a similar syntax before the PEP is accepted, and in older versions of Python. The syntax would look something like this:

button_style = {"font_style": "bold"}
button_text = "Click me!"
view = html @ f"<button on_click={lambda event: ...} style={button_text}>{button_text}</button>"
reveal_type(view)  # revealed type is: VdomDict

Proposed Actions

Aid in the development of this proposed transpiler and then develop an html tag function. An initial implementation of an html tag can be found here.

@Archmonger Archmonger added flag-triage Not prioritized. priority-2-moderate Should be resolved on a reasonable timeline. and removed flag-triage Not prioritized. labels Feb 9, 2023
@Archmonger Archmonger added this to the Speculative milestone Feb 9, 2023
@rmorshea rmorshea removed this from the Speculative milestone Feb 21, 2023
@bitnom
Copy link

bitnom commented Feb 25, 2023

If a transpiler is required to get the same sort of syntax as JSX, then how would template literals be any better than fstrings?

@rmorshea
Copy link
Collaborator

rmorshea commented Feb 25, 2023

The main purpose of template literals is to have a dedicated syntax. Transpilers allow you to write any syntax you'd like in your Python files, and at least for JSX, that's already been done. The problem, and the reason I suspect Pyxl never saw wide adoption, is because it breaks all the tools you would normally use with a Python file (e.g. black, flake8, pylint, mypy, the list goes on...). You could as I proposed above, co-opt an existing syntax which is seen infrequently (e.g. tag @ f"..."), but without standardization, no one is going to create tooling that understands that bespoke syntax and provides highlighting and auto-completions.

@rmorshea
Copy link
Collaborator

I've published an import-time transpiler that implements that aforementioned tag string spec.

$ pip install tagstr
# tagstr: on
name = "world"
print @ f"hello {name}!"
hello  (<function <lambda> at 0x7f7a8586b920>, 'name', None, None) !

I don't think this is ready for production yet, but with some more work behind this I think it provides a promising alternative to the current, and rather disjointed, patterns for constructing views in ReactPy. Integrating this into ReactPy could also act as a compelling real-world use case for the Tag String PEP itself.

@mtrunkbear
Copy link

That could be PSX python syntax extension, or PYX python XML

@mtrunkbear
Copy link

@rmorshea Very good work bro, i was reading the tag string docs and tutorial and i think that is a very useful aproximation.

@aranega
Copy link

aranega commented Jul 13, 2023

Just for the sake of "state of the art", there is also this project named packed that is similar to pyxl3, but the syntax looks a little bit more like like tsx syntax on some small aspects. I guess the same criticisms apply to this project about the lake of syntax highlight,...

@zx013
Copy link

zx013 commented Jan 30, 2024

I use BeautifulSoup analyse xml, then it can work below.

@component
def DataList(items, functest=None, filter_by_priority=None, sort_by_priority=False):
    if filter_by_priority is not None:
        items = [i for i in items if i["priority"] <= filter_by_priority]
    if sort_by_priority:
        items = sorted(items, key=lambda i: i["priority"])
    list_item_elements = [f"""<li key="{i["id"]}">{i["text"]}</li>""" for i in items]
    test = "<sdfa>"
    return """
        <ul>
            abcdedfe
            {functest()}
            {"".join(list_item_elements)}
            {test}
            {test}
            def
            ""{""}""
            <div>test</div>
        </ul>
    """

@component
def TodoList(text=""):
    def functest():
        return ("test-----------------------abc")
    tasks = [
        {"id": 0, "text": f"{text} Make breakfast3", "priority": 0},
        {"id": 1, "text": f"{text} Feed the dog", "priority": 0},
        {"id": 2, "text": f"{text} Do laundry", "priority": 2},
    ]
    return """
        <section>
            <h1>My Todo List</h1>
            <DataList items={tasks} functest={functest} filter_by_priority={1} sort_by_priority={True} />
        </section>
    """

@component
def Test():
    a = 2
    b = 3
    return """
        <h1 id="1" class_name="abc">My Todo List {a + b} Test PSX</h1>
        <ul id="2">
            <li id="5">"Design {23} a cool new app</li>
            <li id="4">Build"</li>
            <li>"Share it with the world!</li>
        </ul>
        <TodoList class_name="abc" />
        <TodoList text="abcd">
            <div>abc</div>
        </TodoList>
        <img
            src="https://picsum.photos/id/237/500/300"
            class="img-fluid"
            style="width: 50%; margin-left: 25%;"
            alt="Billie Holiday"
            tabindex="0"
        />
    """

@hasansezertasan
Copy link

hasansezertasan commented Feb 2, 2024

There is a project that this issue brought to my mind.

RudreshVeerkhare/ReactPy: React implementation in Python 3, which runs on the client-side.

I have never used this project, but I have examined its examples. It allows creating files with the .pyx extension and in these files, you can write HTML with Python, without doing any string formatting.

And I also want to highlight these resources:

And finally, I love Python syntax and hate micro-syntaxes (Jinja counts).

@zx013
Copy link

zx013 commented Feb 3, 2024

There is a project that this issue brought to my mind.

RudreshVeerkhare/ReactPy: React implementation in Python 3, which runs on the client-side.

I have never used this project, but I have examined its examples. It allows creating files with the .pyx extension and in these files, you can write HTML with Python, without doing any string formatting.

And I also want to highlight these resources:

And finally, I love Python syntax and hate micro-syntaxes (Jinja counts).

ReactPy is client side but reactpy is server side. There are two ways to analyze pyx, BeautifulSoup and pypeg2. Then how to use js/ts. component library may be important, reactpy get the easy way get it.

@hasansezertasan
Copy link

ReactPy is client side but reactpy is server side. There are two ways to analyze pyx, BeautifulSoup and pypeg2. Then how to use js/ts. component library may be important, reactpy get the easy way get it.

Yep, thanks for informing 🤩.

@hasansezertasan
Copy link

I just discovered another package that lets you write HTML inside python, check it out: twidi/mixt: Write html components directly in python and you have a beautiful but controversial MIXTure

@Archmonger
Copy link
Contributor Author

I can see there's a pretty heavy want for a JSX style syntax for ReactPy.

Ideally we would have added support for this once Python and code editors (such as VS Code) add support for syntax highlighting on strings. But perhaps we should release support for it for early adopters to test it out.

@arindampradhan
Copy link

arindampradhan commented May 18, 2024

Any progress related to this

Need a transpiler with .pyx extension

Currently rust has it already implemented in their yew framework https://yew.rs/docs/concepts/html
Javascript has jsx already

There will be a need for transpilers so that a python file can import json, css as string
Without a transpiler this project this library is very hard to use

(
    <div>
        <div data-key="abc"></div>
        <div class="parent">
            <span class="child" value="anything"></span>
            <label for="first-name">{ "First Name" }</label>
            <input type="text" id="first-name" value="placeholder" />
            <input type="checkbox" checked=true />
            <textarea value="write a story" />
            <select name="status">
                <option selected=true disabled=false value="">{ "Selected" }</option>
                <option selected=false disabled=true value="">{ "Unselected" }</option>
            </select>
        </div>
    </div>
)

With transpiler

import reactpy import render

def hello_world():
    return <h1>Hello world</h1>

render(hello_world, '#root')

Should transpile to

import reactpy import render

def hello_world():
    return h('h1', 'Hello world')

render(hello_world, '#root')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority-2-moderate Should be resolved on a reasonable timeline.
Projects
None yet
Development

No branches or pull requests

8 participants