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

Add a template tag #1056

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft

Conversation

Archmonger
Copy link
Contributor

@Archmonger Archmonger commented Jun 15, 2023

By submitting this pull request you agree that all contributions to this project are made under the MIT license.

Issues

Summary

Adds template tag support for all of our supported backends.

Checklist

  • Tests have been included for all bug fixes or added functionality.
  • The changelog.rst has been updated with any significant changes.

@Archmonger Archmonger changed the title Create template tag Add a template tag Jun 15, 2023
@Archmonger
Copy link
Contributor Author

Archmonger commented Jun 15, 2023

@rmorshea this PR contains the template tag itself, but not in a usable form due to

  • Needing modification to websocket URL patterns (new pattern: reactpy-ws-url/<uuid>?<kwargs>)
  • Missing JavaScript mount function
  • Missing support for Tornado, which does not use Jinja
  • Needs proper definitions for the constant vars in templatetag.py
  • Needs to verify if components have already been registered

I don't know if I'm going to have time to work on this in-between working on the docs, so feel free to commit directly to this branch if you feel like moving it forward.

@rmorshea
Copy link
Collaborator

rmorshea commented Jun 15, 2023

This might make more sense as a standalone reactpy-jinja package. It also shouldn't require any modification to the current server API. In short, this will require a system similar to Django's in which you registry views and have a single root view that knows how to route requests to the appropriate component.

The current server API accepts WS connections at _reactp/stream/<path:path>. As such, all you need to do is render views based on the path. That might (very roughly) look something like this:

import json
from urllib.parse import parse_qs, unquote

views: dict[str, Callable[[], Component]] = { ... }

@component
def app():
    loc = use_location()
    cmpt = views[loc.pathname]
    search = json.loads(parse_qs(loc.search[1:])
    args = json.loads(unquote(search.get("args", ["[]"])[0]))
    kwargs = json.loads(unquote(search.get("kwargs", ["{}"])[0]))
    return cmpt(*args, **kwargs)

So in the rough pseudo code above, connecting to a WS at:

_reactpy/stream/my_component?kwargs=%7B%22hello%22%3A%20%22world%22%7D

would effectively render views["my_component"](hello="world").

One could imagine user's interacting with this library in the following way:

from fastapi import FastAPI
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates

from reactpy.backend.fastapi import configure
import reactpy_jinja

@reactpy_jinja.register
def my_component(hello):
    ...

app = FastAPI()

@app.get("/", response_class=HTMLResponse)
async def index(request):
    return templates.TemplateResponse("index.html")

configure(app, reactpy_jinja.root)

Where index.html uses the component tag somewhere:

{% component "my_component" hello="world" %}

@Archmonger
Copy link
Contributor Author

Archmonger commented Jun 16, 2023

You think reactpy-jinja could be a good candidate to be contained in the monorepo?

Maybe we should call it reactpy-template-tag to allow for future expansion?

The decorator might be finnicky. Unlike ASGI views, users might not have all of their component functions imported into their main file. We should probably require a template_dirs: list[Glob] for us to automatically parse components from the available HTML templates.

Also do we even want to consider anything unique for Tornado, or do we force Tornado users to install jinja? I'm leaning towards the latter.

@Archmonger
Copy link
Contributor Author

I think we really should push for the template tag being built-in to ReactPy. In my opinion, it should be our main way of advertising how to use ReactPy.

@Archmonger Archmonger added the flag-blocked Currently cannot be resolved. label Jul 19, 2023
@rmorshea
Copy link
Collaborator

I think this work might be easier once we've consolidated around ASGI/WSGI implementations since it can build upon a more uniform application interface.

@Archmonger
Copy link
Contributor Author

Yep, that's why this issue is marked as blocked for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flag-blocked Currently cannot be resolved.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Embedding ReactPy via Template Tags
2 participants