Skip to content

Commit

Permalink
Merge pull request #37 from DavidBerger98/add-router-example
Browse files Browse the repository at this point in the history
Add vue-router helper classes and example
  • Loading branch information
jourdain committed Feb 1, 2022
2 parents 7ce2c53 + d08ae7c commit 94c613a
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 17 deletions.
64 changes: 64 additions & 0 deletions examples/PlainPython/Router/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
from trame.layouts import SinglePageWithDrawer
from trame.html import Template, vuetify, router

layout = SinglePageWithDrawer("Multi-Page demo")
layout.title.set_text("Multi-Page demo")

# There are two ways to register a route
home_template = vuetify.VCard()
with home_template:
vuetify.VCardTitle("This is home")

foo_template = vuetify.VCard()
with foo_template:
vuetify.VCardTitle("This is foo")
with vuetify.VCardText():
vuetify.VBtn("Take me back", click="$router.back()")

# You can add a route with add_route
layout.add_route("home", "/", home_template)
layout.add_route("foo", "/foo", foo_template)

# or use the contextmanager 'with_route'
with layout.with_route("bar", "/bar/:id", vuetify.VCard()):
vuetify.VCardTitle("This is bar with ID '{{ $route.params.id }}'")

# add <router-view />
with layout.content:
with vuetify.VContainer():
router.RouterView()

# add router buttons to the drawer
with layout.drawer:
with vuetify.VList(shaped=True, v_model=("selectedRoute", 0)):
vuetify.VSubheader("Routes")

with vuetify.VListItem(to="/"):
with vuetify.VListItemIcon():
vuetify.VIcon("mdi-home")
with vuetify.VListItemContent():
vuetify.VListItemTitle("Home")

with vuetify.VListItem(to="/foo"):
with vuetify.VListItemIcon():
vuetify.VIcon("mdi-food")
with vuetify.VListItemContent():
vuetify.VListItemTitle("Foo")

with vuetify.VListGroup(value=("true",), sub_group=True):
with Template(v_slot_activator=True):
vuetify.VListItemTitle("Bars")
with vuetify.VListItemContent():
with vuetify.VListItem(v_for="id in [1,2,3]", to=("'/bar/' + id",)):
with vuetify.VListItemIcon():
vuetify.VIcon("mdi-peanut-outline")
with vuetify.VListItemContent():
vuetify.VListItemTitle("Bar")
vuetify.VListItemSubtitle("ID '{{id}}'")

# -----------------------------------------------------------------------------
# Main
# -----------------------------------------------------------------------------

if __name__ == "__main__":
layout.start()
18 changes: 18 additions & 0 deletions trame/html/router/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from trame.internal.app import get_app_instance
from trame.html import AbstractElement
from pywebvue.modules import Router

# Make sure used module is available
_app = get_app_instance()
_app.enable_module(Router)


class RouterView(AbstractElement):
def __init__(self, children=None, **kwargs):
super().__init__("router-view", children=children, **kwargs)


class RouterLink(AbstractElement):
def __init__(self, children=None, **kwargs):
super().__init__("router-link", children=children, **kwargs)
self._attr_names += ["to"]
66 changes: 49 additions & 17 deletions trame/layouts/core.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import asyncio
import os
from contextlib import contextmanager
from pywebvue.utils import read_file_as_base64_url
from trame.html import Span, vuetify, Triggers
from trame.html import AbstractElement, Span, vuetify, Triggers

import pywebvue
import trame as tr
Expand Down Expand Up @@ -80,6 +81,24 @@ def flush_content(self):
_app = tri.get_app_instance()
_app.layout = self.html

def _init_app(self, _app):
_app.name = self.name
_app.layout = self.html

if self.favicon:
_app.favicon = self.favicon

# Evaluate html for added routes
for route in _app.routes:
component = route.get("component", None)
if component is None:
continue
template = component.get("template", None)
if template is None:
continue
if isinstance(template, AbstractElement):
route["component"]["template"] = template.html

def start(self, port=None, debug=None):
"""
Start the application server.
Expand All @@ -92,21 +111,19 @@ def start(self, port=None, debug=None):
"""
_app = tri.get_app_instance()

self._init_app(_app)

if debug is None:
parser = _app.cli_parser
args, _unknown = parser.parse_known_args()
debug = args.dev

_app._debug = debug

_app.name = self.name
_app.layout = self.html
_app.on_ready = tri.print_server_info()

if self.favicon:
_app.favicon = self.favicon
if self.on_ready:
_app.on_ready = tri.print_server_info(self.on_ready)
else:
_app.on_ready = tri.print_server_info()

# Dev validation
tri.validate_key_names()
Expand All @@ -117,11 +134,8 @@ def start_thread(
self, port=None, print_server_info=False, on_server_listening=None, **kwargs
):
_app = tri.get_app_instance()
_app.name = self.name
_app.layout = self.html

if self.favicon:
_app.favicon = self.favicon

self._init_app(_app)

if print_server_info:
_app.on_ready = tri.print_server_info(
Expand All @@ -142,8 +156,8 @@ def start_desktop_window(self, on_msg=None, **kwargs):
_msg_queue = Queue()

_app = tri.get_app_instance()
_app.name = self.name
_app.layout = self.html

self._init_app(_app)

async def process_msg():
keep_processing = True
Expand All @@ -159,9 +173,6 @@ async def process_msg():

asyncio.get_event_loop().create_task(process_msg())

if self.favicon:
_app.favicon = self.favicon

def start_client(**_):
client_process = tri.ClientWindowProcess(
title=_app.name, port=_app.server_port, msg_queue=_msg_queue, **kwargs
Expand All @@ -175,6 +186,27 @@ def start_client(**_):

_app.run_server(port=0)

def add_route(self, name, path, template):
_app = tri.get_app_instance()
# TODO: Check if route already exists?
_app.routes.append(
{
"name": name,
"path": path,
"component": {
"template": template,
},
}
)

@contextmanager
def with_route(self, name, path, root):
try:
with root:
yield
finally:
self.add_route(name, path, root)


class FullScreenPage(AbstractLayout):
"""
Expand Down

0 comments on commit 94c613a

Please sign in to comment.