Update base template (#2027)
This commit is contained in:
parent
f66c6c3361
commit
8133aa10c9
72
reflex/.templates/apps/base/README.md
Normal file
72
reflex/.templates/apps/base/README.md
Normal file
@ -0,0 +1,72 @@
|
||||
# Welcome to Reflex!
|
||||
|
||||
This is the base Reflex template - installed when you run `reflex init`.
|
||||
|
||||
If you want to use a different template, pass the `--template` flag to `reflex init`.
|
||||
For example, if you want a more basic starting point, you can run:
|
||||
|
||||
```bash
|
||||
reflex init --template blank
|
||||
```
|
||||
|
||||
## About this Template
|
||||
|
||||
This template has the following directory structure:
|
||||
|
||||
```bash
|
||||
.
|
||||
├── assets
|
||||
├── requirements.txt
|
||||
├── rxconfig.py
|
||||
└── {your_app}
|
||||
├── __init__.py
|
||||
├── components
|
||||
│ └── sidebar.py
|
||||
├── pages
|
||||
│ ├── __init__.py
|
||||
│ ├── dashboard.py
|
||||
│ ├── index.py
|
||||
│ ├── settings.py
|
||||
│ └── template.py
|
||||
├── state.py
|
||||
├── styles.py
|
||||
└── {your_app}.py
|
||||
|
||||
```
|
||||
|
||||
See the [Project Structure docs](https://reflex.dev/docs/getting-started/project-structure/) for more information on general Reflex project structure.
|
||||
|
||||
### Adding Pages
|
||||
|
||||
In this template, the pages in your app are defined in `{your_app}/pages/`.
|
||||
Each page is a function that returns a Reflex component.
|
||||
For example, to edit this page you can modify `{your_app}/pages/index.py`.
|
||||
See the [pages docs](https://reflex.dev/docs/components/pages/) for more information on pages.
|
||||
|
||||
In this template, instead of using `rx.add_page` or the `@rx.page` decorator,
|
||||
we use the `@template` decorator from `{your_app}/pages/template.py`.
|
||||
|
||||
To add a new page:
|
||||
|
||||
1. Add a new file in `{your_app}/pages/`. We recommend using one file per page, but you can also group pages in a single file.
|
||||
2. Add a new function with the `@template` decorator, which takes the same arguments as `@rx.page`.
|
||||
3. Import the page in your `{your_app}/{your_app}.py` file and it will automatically be added to the app.
|
||||
|
||||
|
||||
### Adding Components
|
||||
|
||||
In order to keep your code organized, we recommend putting components that are
|
||||
used across multiple pages in the `{your_app}/components/` directory.
|
||||
|
||||
In this template, we have a sidebar component in `{your_app}/components/sidebar.py`.
|
||||
|
||||
### Adding State
|
||||
|
||||
In this template, we define the base state of the app in `{your_app}/state.py`.
|
||||
The base state is useful for general app state that is used across multiple pages.
|
||||
|
||||
In this template, the base state handles the toggle for the sidebar.
|
||||
|
||||
As your app grows, we recommend using [substates](https://reflex.dev/docs/state/substates/)
|
||||
to organize your state. You can either define substates in their own files, or if the state is
|
||||
specific to a page, you can define it in the page file itself.
|
@ -1,101 +1,12 @@
|
||||
"""Welcome to Reflex! This file outlines the steps to create a basic app."""
|
||||
from typing import Callable
|
||||
"""Welcome to Reflex!."""
|
||||
|
||||
from code import styles
|
||||
|
||||
# Import all the pages.
|
||||
from code.pages import *
|
||||
|
||||
import reflex as rx
|
||||
|
||||
from .pages import dashboard_page, home_page, settings_page
|
||||
from .sidebar import sidebar
|
||||
from .state import State
|
||||
from .styles import *
|
||||
|
||||
meta = [
|
||||
{
|
||||
"name": "viewport",
|
||||
"content": "width=device-width, shrink-to-fit=no, initial-scale=1",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def template(main_content: Callable[[], rx.Component]) -> rx.Component:
|
||||
"""The template for each page of the app.
|
||||
|
||||
Args:
|
||||
main_content (Callable[[], rx.Component]): The main content of the page.
|
||||
|
||||
Returns:
|
||||
rx.Component: The template for each page of the app.
|
||||
"""
|
||||
menu_button = rx.box(
|
||||
rx.menu(
|
||||
rx.menu_button(
|
||||
rx.icon(
|
||||
tag="hamburger",
|
||||
size="4em",
|
||||
color=text_color,
|
||||
),
|
||||
),
|
||||
rx.menu_list(
|
||||
rx.menu_item(rx.link("Home", href="/", width="100%")),
|
||||
rx.menu_divider(),
|
||||
rx.menu_item(
|
||||
rx.link("About", href="https://github.com/reflex-dev", width="100%")
|
||||
),
|
||||
rx.menu_item(
|
||||
rx.link("Contact", href="mailto:founders@=reflex.dev", width="100%")
|
||||
),
|
||||
),
|
||||
),
|
||||
position="fixed",
|
||||
right="1.5em",
|
||||
top="1.5em",
|
||||
z_index="500",
|
||||
)
|
||||
|
||||
return rx.hstack(
|
||||
sidebar(),
|
||||
main_content(),
|
||||
rx.spacer(),
|
||||
menu_button,
|
||||
align_items="flex-start",
|
||||
transition="left 0.5s, width 0.5s",
|
||||
position="relative",
|
||||
left=rx.cond(State.sidebar_displayed, "0px", f"-{sidebar_width}"),
|
||||
)
|
||||
|
||||
|
||||
@rx.page("/", meta=meta)
|
||||
@template
|
||||
def home() -> rx.Component:
|
||||
"""Home page.
|
||||
|
||||
Returns:
|
||||
rx.Component: The home page.
|
||||
"""
|
||||
return home_page()
|
||||
|
||||
|
||||
@rx.page("/settings", meta=meta)
|
||||
@template
|
||||
def settings() -> rx.Component:
|
||||
"""Settings page.
|
||||
|
||||
Returns:
|
||||
rx.Component: The settings page.
|
||||
"""
|
||||
return settings_page()
|
||||
|
||||
|
||||
@rx.page("/dashboard", meta=meta)
|
||||
@template
|
||||
def dashboard() -> rx.Component:
|
||||
"""Dashboard page.
|
||||
|
||||
Returns:
|
||||
rx.Component: The dashboard page.
|
||||
"""
|
||||
return dashboard_page()
|
||||
|
||||
|
||||
# Add state and page to the app.
|
||||
app = rx.App(style=base_style)
|
||||
# Create the app and compile it.
|
||||
app = rx.App(style=styles.base_style)
|
||||
app.compile()
|
||||
|
@ -1,23 +1,25 @@
|
||||
"""Sidebar component for the app."""
|
||||
|
||||
import reflex as rx
|
||||
from code import styles
|
||||
from code.state import State
|
||||
|
||||
from .state import State
|
||||
from .styles import *
|
||||
import reflex as rx
|
||||
|
||||
|
||||
def sidebar_header() -> rx.Component:
|
||||
"""Sidebar header.
|
||||
|
||||
Returns:
|
||||
rx.Component: The sidebar header component.
|
||||
The sidebar header component.
|
||||
"""
|
||||
return rx.hstack(
|
||||
# The logo.
|
||||
rx.image(
|
||||
src="/icon.svg",
|
||||
height="2em",
|
||||
),
|
||||
rx.spacer(),
|
||||
# Link to Reflex GitHub repo.
|
||||
rx.link(
|
||||
rx.center(
|
||||
rx.image(
|
||||
@ -25,17 +27,17 @@ def sidebar_header() -> rx.Component:
|
||||
height="3em",
|
||||
padding="0.5em",
|
||||
),
|
||||
box_shadow=box_shadow,
|
||||
box_shadow=styles.box_shadow,
|
||||
bg="transparent",
|
||||
border_radius=border_radius,
|
||||
border_radius=styles.border_radius,
|
||||
_hover={
|
||||
"bg": accent_color,
|
||||
"bg": styles.accent_color,
|
||||
},
|
||||
),
|
||||
href="https://github.com/reflex-dev/reflex",
|
||||
),
|
||||
width="100%",
|
||||
border_bottom=border,
|
||||
border_bottom=styles.border,
|
||||
padding="1em",
|
||||
)
|
||||
|
||||
@ -44,7 +46,7 @@ def sidebar_footer() -> rx.Component:
|
||||
"""Sidebar footer.
|
||||
|
||||
Returns:
|
||||
rx.Component: The sidebar footer component.
|
||||
The sidebar footer component.
|
||||
"""
|
||||
return rx.hstack(
|
||||
rx.link(
|
||||
@ -55,15 +57,15 @@ def sidebar_footer() -> rx.Component:
|
||||
padding="0.5em",
|
||||
),
|
||||
bg="transparent",
|
||||
border_radius=border_radius,
|
||||
**hover_accent_bg,
|
||||
border_radius=styles.border_radius,
|
||||
**styles.hover_accent_bg,
|
||||
),
|
||||
on_click=State.toggle_sidebar_displayed,
|
||||
transform=rx.cond(~State.sidebar_displayed, "rotate(180deg)", ""),
|
||||
transition="transform 0.5s, left 0.5s",
|
||||
position="relative",
|
||||
left=rx.cond(State.sidebar_displayed, "0px", "20.5em"),
|
||||
**overlapping_button_style,
|
||||
**styles.overlapping_button_style,
|
||||
),
|
||||
rx.spacer(),
|
||||
rx.link(
|
||||
@ -79,7 +81,7 @@ def sidebar_footer() -> rx.Component:
|
||||
href="https://reflex.dev/blog/",
|
||||
),
|
||||
width="100%",
|
||||
border_top=border,
|
||||
border_top=styles.border,
|
||||
padding="1em",
|
||||
)
|
||||
|
||||
@ -88,13 +90,18 @@ def sidebar_item(text: str, icon: str, url: str) -> rx.Component:
|
||||
"""Sidebar item.
|
||||
|
||||
Args:
|
||||
text (str): The text of the item.
|
||||
icon (str): The icon of the item.
|
||||
url (str): The URL of the item.
|
||||
text: The text of the item.
|
||||
icon: The icon of the item.
|
||||
url: The URL of the item.
|
||||
|
||||
Returns:
|
||||
rx.Component: The sidebar item component.
|
||||
"""
|
||||
# Whether the item is active.
|
||||
active = (State.router.page.path == f"/{text.lower()}") | (
|
||||
(State.router.page.path == "/") & text == "Home"
|
||||
)
|
||||
|
||||
return rx.link(
|
||||
rx.hstack(
|
||||
rx.image(
|
||||
@ -106,17 +113,17 @@ def sidebar_item(text: str, icon: str, url: str) -> rx.Component:
|
||||
text,
|
||||
),
|
||||
bg=rx.cond(
|
||||
State.origin_url == f"/{text.lower()}/",
|
||||
accent_color,
|
||||
active,
|
||||
styles.accent_color,
|
||||
"transparent",
|
||||
),
|
||||
color=rx.cond(
|
||||
State.origin_url == f"/{text.lower()}/",
|
||||
accent_text_color,
|
||||
text_color,
|
||||
active,
|
||||
styles.accent_text_color,
|
||||
styles.text_color,
|
||||
),
|
||||
border_radius=border_radius,
|
||||
box_shadow=box_shadow,
|
||||
border_radius=styles.border_radius,
|
||||
box_shadow=styles.box_shadow,
|
||||
width="100%",
|
||||
padding_x="1em",
|
||||
),
|
||||
@ -126,25 +133,26 @@ def sidebar_item(text: str, icon: str, url: str) -> rx.Component:
|
||||
|
||||
|
||||
def sidebar() -> rx.Component:
|
||||
"""Sidebar.
|
||||
"""The sidebar.
|
||||
|
||||
Returns:
|
||||
rx.Component: The sidebar component.
|
||||
The sidebar component.
|
||||
"""
|
||||
# Get all the decorated pages and add them to the sidebar.
|
||||
from reflex.page import get_decorated_pages
|
||||
|
||||
return rx.box(
|
||||
rx.vstack(
|
||||
sidebar_header(),
|
||||
rx.vstack(
|
||||
sidebar_item(
|
||||
"Dashboard",
|
||||
"/github.svg",
|
||||
"/dashboard",
|
||||
),
|
||||
sidebar_item(
|
||||
"Settings",
|
||||
"/github.svg",
|
||||
"/settings",
|
||||
),
|
||||
*[
|
||||
sidebar_item(
|
||||
text=page.get("title", page["route"].strip("/").capitalize()),
|
||||
icon=page.get("image", "/github.svg"),
|
||||
url=page["route"],
|
||||
)
|
||||
for page in get_decorated_pages()
|
||||
],
|
||||
width="100%",
|
||||
overflow_y="auto",
|
||||
align_items="flex-start",
|
||||
@ -154,9 +162,9 @@ def sidebar() -> rx.Component:
|
||||
sidebar_footer(),
|
||||
height="100dvh",
|
||||
),
|
||||
min_width=sidebar_width,
|
||||
min_width=styles.sidebar_width,
|
||||
height="100%",
|
||||
position="sticky",
|
||||
top="0px",
|
||||
border_right=border,
|
||||
border_right=styles.border,
|
||||
)
|
@ -1,4 +1,3 @@
|
||||
"""The pages of the app."""
|
||||
from .dashboard import dashboard_page
|
||||
from .home import home_page
|
||||
from .settings import settings_page
|
||||
from .dashboard import dashboard
|
||||
from .index import index
|
||||
from .settings import settings
|
||||
|
@ -1,28 +1,21 @@
|
||||
"""The dashboard page for the template."""
|
||||
"""The dashboard page."""
|
||||
from code.templates import template
|
||||
|
||||
import reflex as rx
|
||||
|
||||
from ..styles import *
|
||||
|
||||
|
||||
def dashboard_page() -> rx.Component:
|
||||
"""The UI for the dashboard page.
|
||||
@template(route="/dashboard", title="Dashboard")
|
||||
def dashboard() -> rx.Component:
|
||||
"""The dashboard page.
|
||||
|
||||
Returns:
|
||||
rx.Component: The UI for the dashboard page.
|
||||
The UI for the dashboard page.
|
||||
"""
|
||||
return rx.box(
|
||||
rx.vstack(
|
||||
rx.heading(
|
||||
"Dashboard",
|
||||
font_size="3em",
|
||||
),
|
||||
rx.text(
|
||||
"Welcome to Reflex!",
|
||||
),
|
||||
rx.text(
|
||||
"You can use this template to get started with Reflex.",
|
||||
),
|
||||
style=template_content_style,
|
||||
return rx.vstack(
|
||||
rx.heading("Dashboard", font_size="3em"),
|
||||
rx.text("Welcome to Reflex!"),
|
||||
rx.text(
|
||||
"You can edit this page in ",
|
||||
rx.code("{your_app}/pages/dashboard.py"),
|
||||
),
|
||||
style=template_page_style,
|
||||
)
|
||||
|
@ -1,28 +0,0 @@
|
||||
"""The home page of the app."""
|
||||
import reflex as rx
|
||||
|
||||
from ..styles import *
|
||||
|
||||
|
||||
def home_page() -> rx.Component:
|
||||
"""The UI for the home page.
|
||||
|
||||
Returns:
|
||||
rx.Component: The UI for the home page.
|
||||
"""
|
||||
return rx.box(
|
||||
rx.vstack(
|
||||
rx.heading(
|
||||
"Home",
|
||||
font_size="3em",
|
||||
),
|
||||
rx.text(
|
||||
"Welcome to Reflex!",
|
||||
),
|
||||
rx.text(
|
||||
"You can use this template to get started with Reflex.",
|
||||
),
|
||||
style=template_content_style,
|
||||
),
|
||||
style=template_page_style,
|
||||
)
|
18
reflex/.templates/apps/base/code/pages/index.py
Normal file
18
reflex/.templates/apps/base/code/pages/index.py
Normal file
@ -0,0 +1,18 @@
|
||||
"""The home page of the app."""
|
||||
|
||||
from code import styles
|
||||
from code.templates import template
|
||||
|
||||
import reflex as rx
|
||||
|
||||
|
||||
@template(route="/", title="Home", image="/logo.svg")
|
||||
def index() -> rx.Component:
|
||||
"""The home page.
|
||||
|
||||
Returns:
|
||||
The UI for the home page.
|
||||
"""
|
||||
with open("README.md") as readme:
|
||||
content = readme.read()
|
||||
return rx.markdown(content, component_map=styles.markdown_style)
|
@ -1,28 +1,22 @@
|
||||
"""The settings page for the template."""
|
||||
"""The settings page."""
|
||||
|
||||
from code.templates import template
|
||||
|
||||
import reflex as rx
|
||||
|
||||
from ..styles import *
|
||||
|
||||
|
||||
def settings_page() -> rx.Component:
|
||||
"""The UI for the settings page.
|
||||
@template(route="/settings", title="Settings")
|
||||
def settings() -> rx.Component:
|
||||
"""The settings page.
|
||||
|
||||
Returns:
|
||||
rx.Component: The UI for the settings page.
|
||||
The UI for the settings page.
|
||||
"""
|
||||
return rx.box(
|
||||
rx.vstack(
|
||||
rx.heading(
|
||||
"Settings",
|
||||
font_size="3em",
|
||||
),
|
||||
rx.text(
|
||||
"Welcome to Reflex!",
|
||||
),
|
||||
rx.text(
|
||||
"You can use this template to get started with Reflex.",
|
||||
),
|
||||
style=template_content_style,
|
||||
return rx.vstack(
|
||||
rx.heading("Settings", font_size="3em"),
|
||||
rx.text("Welcome to Reflex!"),
|
||||
rx.text(
|
||||
"You can edit this page in ",
|
||||
rx.code("{your_app}/pages/settings.py"),
|
||||
),
|
||||
style=template_page_style,
|
||||
)
|
||||
|
@ -6,17 +6,9 @@ import reflex as rx
|
||||
class State(rx.State):
|
||||
"""State for the app."""
|
||||
|
||||
# Whether the sidebar is displayed.
|
||||
sidebar_displayed: bool = True
|
||||
|
||||
@rx.var
|
||||
def origin_url(self) -> str:
|
||||
"""Get the url of the current page.
|
||||
|
||||
Returns:
|
||||
str: The url of the current page.
|
||||
"""
|
||||
return self.router_data.get("asPath", "")
|
||||
|
||||
def toggle_sidebar_displayed(self) -> None:
|
||||
"""Toggle the sidebar displayed."""
|
||||
self.sidebar_displayed = not self.sidebar_displayed
|
||||
|
@ -1,7 +1,7 @@
|
||||
"""Styles for the app."""
|
||||
import reflex as rx
|
||||
from code.state import State
|
||||
|
||||
from .state import State
|
||||
import reflex as rx
|
||||
|
||||
border_radius = "0.375rem"
|
||||
box_shadow = "0px 0px 0px 1px rgba(84, 82, 95, 0.14)"
|
||||
@ -53,3 +53,20 @@ base_style = {
|
||||
},
|
||||
rx.MenuItem: hover_accent_bg,
|
||||
}
|
||||
|
||||
markdown_style = {
|
||||
"code": lambda text: rx.code(text, color="#1F1944", bg="#EAE4FD"),
|
||||
"a": lambda text, **props: rx.link(
|
||||
text,
|
||||
**props,
|
||||
font_weight="bold",
|
||||
color="#03030B",
|
||||
text_decoration="underline",
|
||||
text_decoration_color="#AD9BF8",
|
||||
_hover={
|
||||
"color": "#AD9BF8",
|
||||
"text_decoration": "underline",
|
||||
"text_decoration_color": "#03030B",
|
||||
},
|
||||
),
|
||||
}
|
||||
|
1
reflex/.templates/apps/base/code/templates/__init__.py
Normal file
1
reflex/.templates/apps/base/code/templates/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from .template import template
|
99
reflex/.templates/apps/base/code/templates/template.py
Normal file
99
reflex/.templates/apps/base/code/templates/template.py
Normal file
@ -0,0 +1,99 @@
|
||||
"""Common templates used between pages in the app."""
|
||||
|
||||
from code import styles
|
||||
from code.components.sidebar import sidebar
|
||||
from code.state import State
|
||||
from typing import Callable
|
||||
|
||||
import reflex as rx
|
||||
|
||||
# Meta tags for the app.
|
||||
default_meta = [
|
||||
{
|
||||
"name": "viewport",
|
||||
"content": "width=device-width, shrink-to-fit=no, initial-scale=1",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def menu_button() -> rx.Component:
|
||||
"""The menu button on the top right of the page.
|
||||
|
||||
Returns:
|
||||
The menu button component.
|
||||
"""
|
||||
return rx.box(
|
||||
rx.menu(
|
||||
rx.menu_button(
|
||||
rx.icon(
|
||||
tag="hamburger",
|
||||
size="4em",
|
||||
color=styles.text_color,
|
||||
),
|
||||
),
|
||||
rx.menu_list(
|
||||
rx.menu_item(rx.link("Home", href="/", width="100%")),
|
||||
rx.menu_divider(),
|
||||
rx.menu_item(
|
||||
rx.link("About", href="https://github.com/reflex-dev", width="100%")
|
||||
),
|
||||
rx.menu_item(
|
||||
rx.link("Contact", href="mailto:founders@=reflex.dev", width="100%")
|
||||
),
|
||||
),
|
||||
),
|
||||
position="fixed",
|
||||
right="1.5em",
|
||||
top="1.5em",
|
||||
z_index="500",
|
||||
)
|
||||
|
||||
|
||||
def template(
|
||||
**page_kwargs: dict,
|
||||
) -> Callable[[Callable[[], rx.Component]], rx.Component]:
|
||||
"""The template for each page of the app.
|
||||
|
||||
Args:
|
||||
page_kwargs: Keyword arguments to pass to the page.
|
||||
|
||||
Returns:
|
||||
The template with the page content.
|
||||
"""
|
||||
|
||||
def decorator(page_content: Callable[[], rx.Component]) -> rx.Component:
|
||||
"""The template for each page of the app.
|
||||
|
||||
Args:
|
||||
page_content: The content of the page.
|
||||
|
||||
Returns:
|
||||
The template with the page content.
|
||||
"""
|
||||
# Get the meta tags for the page.
|
||||
page_kwargs["meta"] = [*default_meta, *page_kwargs.get("meta", [])]
|
||||
|
||||
@rx.page(**page_kwargs)
|
||||
def templated_page():
|
||||
return rx.hstack(
|
||||
sidebar(),
|
||||
rx.box(
|
||||
rx.box(
|
||||
page_content(),
|
||||
**styles.template_content_style,
|
||||
),
|
||||
**styles.template_page_style,
|
||||
),
|
||||
rx.spacer(),
|
||||
menu_button(),
|
||||
align_items="flex-start",
|
||||
transition="left 0.5s, width 0.5s",
|
||||
position="relative",
|
||||
left=rx.cond(
|
||||
State.sidebar_displayed, "0px", f"-{styles.sidebar_width}"
|
||||
),
|
||||
)
|
||||
|
||||
return templated_page
|
||||
|
||||
return decorator
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
0
reflex/.templates/apps/blank/code/__init__.py
Normal file
0
reflex/.templates/apps/blank/code/__init__.py
Normal file
@ -62,7 +62,7 @@ def get_base_component_map() -> dict[str, Callable]:
|
||||
"p": lambda value: Text.create(value, margin_y="1em"),
|
||||
"ul": lambda value: UnorderedList.create(value, margin_y="1em"), # type: ignore
|
||||
"ol": lambda value: OrderedList.create(value, margin_y="1em"), # type: ignore
|
||||
"li": lambda value: ListItem.create(value),
|
||||
"li": lambda value: ListItem.create(value, margin_y="0.5em"),
|
||||
"a": lambda value: Link.create(value),
|
||||
"code": lambda value: Code.create(value),
|
||||
"codeblock": lambda *_, **props: CodeBlock.create(
|
||||
|
@ -89,6 +89,8 @@ class Templates(SimpleNamespace):
|
||||
WEB_TEMPLATE = os.path.join(BASE, "web")
|
||||
# The jinja template directory.
|
||||
JINJA_TEMPLATE = os.path.join(BASE, "jinja")
|
||||
# Where the code for the templates is stored.
|
||||
CODE = "code"
|
||||
|
||||
|
||||
class Next(SimpleNamespace):
|
||||
|
@ -61,3 +61,15 @@ def page(
|
||||
return render_fn
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
def get_decorated_pages() -> list[dict]:
|
||||
"""Get the decorated pages.
|
||||
|
||||
Returns:
|
||||
The decorated pages.
|
||||
"""
|
||||
return sorted(
|
||||
[page_data for render_fn, page_data in DECORATED_PAGES],
|
||||
key=lambda x: x["route"],
|
||||
)
|
||||
|
@ -71,7 +71,7 @@ def init(
|
||||
None, metavar="APP_NAME", help="The name of the app to initialize."
|
||||
),
|
||||
template: constants.Templates.Kind = typer.Option(
|
||||
constants.Templates.Kind.DEFAULT.value,
|
||||
constants.Templates.Kind.BASE.value,
|
||||
help="The template to initialize the app with.",
|
||||
),
|
||||
loglevel: constants.LogLevel = typer.Option(
|
||||
|
@ -154,7 +154,7 @@ class AppHarness:
|
||||
with chdir(self.app_path):
|
||||
reflex.reflex.init(
|
||||
name=self.app_name,
|
||||
template=reflex.constants.Templates.Kind.DEFAULT,
|
||||
template=reflex.constants.Templates.Kind.BLANK,
|
||||
loglevel=reflex.constants.LogLevel.INFO,
|
||||
)
|
||||
self.app_module_path.write_text(source_code)
|
||||
|
@ -34,7 +34,7 @@ def detect_package_change(json_file_path: str) -> str:
|
||||
"""Calculates the SHA-256 hash of a JSON file and returns it as a hexadecimal string.
|
||||
|
||||
Args:
|
||||
json_file_path (str): The path to the JSON file to be hashed.
|
||||
json_file_path: The path to the JSON file to be hashed.
|
||||
|
||||
Returns:
|
||||
str: The SHA-256 hash of the JSON file as a hexadecimal string.
|
||||
|
@ -4,6 +4,7 @@ from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
@ -173,3 +174,21 @@ def update_json_file(file_path: str, update_dict: dict[str, int | str]):
|
||||
# Write the updated json object to the file
|
||||
with open(fp, "w") as f:
|
||||
json.dump(json_object, f, ensure_ascii=False)
|
||||
|
||||
|
||||
def find_replace(directory: str, find: str, replace: str):
|
||||
"""Recursively find and replace text in files in a directory.
|
||||
|
||||
Args:
|
||||
directory: The directory to search.
|
||||
find: The text to find.
|
||||
replace: The text to replace.
|
||||
"""
|
||||
for root, _dirs, files in os.walk(directory):
|
||||
for file in files:
|
||||
filepath = os.path.join(root, file)
|
||||
with open(filepath, "r", encoding="utf-8") as f:
|
||||
text = f.read()
|
||||
text = re.sub(find, replace, text)
|
||||
with open(filepath, "w") as f:
|
||||
f.write(text)
|
||||
|
@ -249,17 +249,25 @@ def initialize_app_directory(app_name: str, template: constants.Templates.Kind):
|
||||
template: The template to use.
|
||||
"""
|
||||
console.log("Initializing the app directory.")
|
||||
path_ops.cp(
|
||||
os.path.join(constants.Templates.Dirs.BASE, "apps", template.value, "code"),
|
||||
app_name,
|
||||
)
|
||||
|
||||
# Copy the template to the current directory.
|
||||
template_dir = os.path.join(constants.Templates.Dirs.BASE, "apps", template.value)
|
||||
for file in os.listdir(template_dir):
|
||||
# Copy the file but keep the name the same.
|
||||
path_ops.cp(os.path.join(template_dir, file), file)
|
||||
|
||||
# Rename the template app to the app name.
|
||||
path_ops.mv(constants.Templates.Dirs.CODE, app_name)
|
||||
path_ops.mv(
|
||||
os.path.join(app_name, template.value + ".py"),
|
||||
os.path.join(app_name, template.value + constants.Ext.PY),
|
||||
os.path.join(app_name, app_name + constants.Ext.PY),
|
||||
)
|
||||
path_ops.cp(
|
||||
os.path.join(constants.Templates.Dirs.BASE, "apps", template.value, "assets"),
|
||||
constants.Dirs.APP_ASSETS,
|
||||
|
||||
# Fix up the imports.
|
||||
path_ops.find_replace(
|
||||
app_name,
|
||||
f"from {constants.Templates.Dirs.CODE}",
|
||||
f"from {app_name}",
|
||||
)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user