Skip to content

Commit e2ff9da

Browse files
More shiki cleanup (#1093)
* More shiki cleanup * intro page * use a shiki markdown based wrapper * fix ref * minor refactor
1 parent 7d4e807 commit e2ff9da

File tree

9 files changed

+50
-24
lines changed

9 files changed

+50
-24
lines changed

blog/2024-10-8-self-hosting-reflex-with-docker.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ meta: [
3030
]
3131
---
3232

33+
```python exec
34+
from pcweb.flexdown import markdown_with_shiki
35+
```
36+
3337
Reflex offers a powerful way to build reactive web apps in pure Python, complete with one-line deployment for easy hosting. For those who want to self host on their own infra we'll explore how to leverage Docker to containerize and deploy your app, taking your Reflex app from development to production.
3438

3539

@@ -100,7 +104,7 @@ import reflex as rx
100104
rx.accordion.root(
101105
rx.accordion.item(
102106
header=rx.text("Explanation of the compose.yml file", color=rx.color("slate", 12), weight="regular"),
103-
content=rx.markdown("""Here we define three services: `backend`, `frontend`, and `redis`. The `backend` service will run the Reflex app, the `frontend` service will run the web server, and the `redis` service will run the Redis server. The `depends_on` key specifies the order in which the services will be started.
107+
content=markdown_with_shiki("""Here we define three services: `backend`, `frontend`, and `redis`. The `backend` service will run the Reflex app, the `frontend` service will run the web server, and the `redis` service will run the Redis server. The `depends_on` key specifies the order in which the services will be started.
104108
105109
The first to be run is the `redis` service. We use Redis for the state manager and it is good to put in its own container, so that its easy to differenatiate the resource usage from a cache and the actual web server. It pulls the docker image for redis and runs the image as a container. If we wanted a specific tag then we can specify it in the image key, i.e. `image: redis:7.4.0`.
106110
@@ -138,7 +142,7 @@ ENTRYPOINT ["reflex", "run", "--env", "prod", "--backend-only", "--loglevel", "d
138142
rx.accordion.root(
139143
rx.accordion.item(
140144
header=rx.text("Explanation of the Dockerfile file", color=rx.color("slate", 12), weight="regular"),
141-
content=rx.markdown("""We start from the python image of 3.12.
145+
content=markdown_with_shiki("""We start from the python image of 3.12.
142146
143147
Docker compose makes all the services accessible to each via their service name. Therefore `redis://` is the protocol, `redis` is the url and is easily accessible to all other services and therefore we access the redis container. If you are using a self hosted redis then you would put the actual url here instead of redis i.e. `REDIS_URL=redis://sjc04rdsdb01.your.cloud.provider.com`. `PYTHONUNBUFFERED=1` ensures that stdout and stderr go to the terminal.
144148
@@ -175,7 +179,7 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf
175179
rx.accordion.root(
176180
rx.accordion.item(
177181
header=rx.text("Explanation of the web.Dockerfile file", color=rx.color("slate", 12), weight="regular"),
178-
content=rx.markdown("""We import `python:3.12` and build on top of it and the name of this build step is `builder` which we can then reference later as needed. The `WORKDIR`, `COPY`, `RUN pip install` commands are the same as in the `Dockerfile`. The `reflex export --frontend-only --no-zip` command exports the frontend assets to the `.web/_static` directory. The `builder` step encompasses all lines until we reach the next `FROM` statement. After this the `builder` step is complete and ready to be used in later steps.
182+
content=markdown_with_shiki("""We import `python:3.12` and build on top of it and the name of this build step is `builder` which we can then reference later as needed. The `WORKDIR`, `COPY`, `RUN pip install` commands are the same as in the `Dockerfile`. The `reflex export --frontend-only --no-zip` command exports the frontend assets to the `.web/_static` directory. The `builder` step encompasses all lines until we reach the next `FROM` statement. After this the `builder` step is complete and ready to be used in later steps.
179183
180184
`nginx` is an image that we import and there is no need for an entrypoint as we plan to utilize the existing one that comes with the image.
181185
@@ -234,7 +238,7 @@ server {
234238
rx.accordion.root(
235239
rx.accordion.item(
236240
header=rx.heading("Explanation of the nginx.conf file", color=rx.color("slate", 12), weight="regular", size='5'),
237-
content=rx.markdown("""The `listen 80;` and `listen [::]:80;` lines specify that the server should listen on port 80 ([::] is for ipv6).
241+
content=markdown_with_shiki("""The `listen 80;` and `listen [::]:80;` lines specify that the server should listen on port 80 ([::] is for ipv6).
238242
239243
The `location /_event` block is used to proxy websocket connections to the backend server. The `proxy_pass http://backend:8000;` line specifies that the requests should be forwarded to the `backend` service on port 8000. Anything that hits the frontend on the 3 pages (`/_event`, `/ping`, `/_upload`) are passed on to the backend and then the backend will respond and the front end will pass that straight back to the user.
240244

docs/custom-components/command-reference.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ The `init` command uses the current enclosing folder name to construct a python
6161
The `init` command creates a set of files and folders prefilled with the package name and other details. During the init, the `custom_component` folder is installed locally in editable mode, so a developer can incrementally develop and test with ease. The changes in component implementation is automatically reflected where it is used. Below is the folder structure after the `init` command.
6262

6363
```python eval
64-
rx.code_block("""
64+
rx._x.code_block("""
6565
google_auth/
6666
├── pyproject.toml
6767
├── README.md

docs/getting_started/introduction.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ from pcweb import constants, styles
44
from pcweb.pages.docs import getting_started
55
from pcweb.pages.docs import wrapping_react
66
from pcweb.pages.docs.library import library
7-
from pcweb.pages.docs import pages
7+
from pcweb.pages.docs import pages
88
from pcweb.pages.docs import vars
99
from pcweb.styles.colors import c_color
1010
from pcweb.styles.fonts import base
11+
from pcweb.flexdown import markdown_with_shiki
1112
```
1213

1314
<!-- TODO how do we consistently rename page title? -->
@@ -79,7 +80,7 @@ def tabs():
7980
),
8081
),
8182
rx.tabs.content(
82-
rx.markdown(
83+
markdown_with_shiki(
8384
"""The frontend is built declaratively using Reflex components. Components are compiled down to JS and served to the users browser, therefore:
8485
8586
- Only use Reflex components, vars, and var operations when building your UI. Any other logic should be put in your `State` (backend).
@@ -91,15 +92,15 @@ def tabs():
9192
class_name="pt-4"
9293
),
9394
rx.tabs.content(
94-
rx.markdown(
95+
markdown_with_shiki(
9596
"""Write your backend in the `State` class. Here you can define functions and variables that can be referenced in the frontend. This code runs directly on the server and is not compiled, so there are no special caveats. Here you can use any Python external library and call any method/function.
9697
""",
9798
),
9899
value="tab2",
99100
class_name="pt-4"
100101
),
101102
rx.tabs.content(
102-
rx.markdown(
103+
markdown_with_shiki(
103104
f"""Each page is a Python function that returns a Reflex component. You can define multiple pages and navigate between them, see the [Routing]({pages.routes.path}) section for more information.
104105
105106
- Start with a single page and scale to 100s of pages.
@@ -142,11 +143,11 @@ tabs()
142143

143144
```python demo box
144145
rx.box(
145-
rx.code_block(
146+
rx._x.code_block(
146147
"""import reflex as rx """,
147148
class_name="code-block !bg-transparent !border-none",
148149
),
149-
rx.code_block(
150+
rx._x.code_block(
150151
"""class State(rx.State):
151152
count: int = 0
152153
@@ -167,7 +168,7 @@ rx.box(
167168
),
168169
class_name="code-block",
169170
),
170-
rx.code_block(
171+
rx._x.code_block(
171172
"""def index():
172173
return rx.hstack(
173174
rx.button(
@@ -195,7 +196,7 @@ rx.box(
195196
),
196197
class_name="code-block",
197198
),
198-
rx.code_block(
199+
rx._x.code_block(
199200
"""app = rx.App()
200201
app.add_page(index)""",
201202
background=rx.cond(

docs/library/forms/form-ll.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ In this example, the `rx.input` has an attribute `type="email"` and the `form.me
143143
## Form Anatomy
144144

145145
```python eval
146-
rx.code_block(
146+
rx._x.code_block(
147147
"""form.root(
148148
form.field(
149149
form.label(...),

errors.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
```python exec
22
import reflex as rx
3+
from pcweb.flexdown import markdown_with_shiki
34
```
45

56
```python exec
@@ -20,7 +21,7 @@ def h4_comp_error(text: rx.Var[str]) -> rx.Component:
2021
@rx.memo
2122
def code_block_error(code: str):
2223
return rx.box(
23-
rx.code_block(
24+
rx._x.code_block(
2425
code,
2526
language="python",
2627
class_name="code-block !bg-slate-1",
@@ -30,7 +31,7 @@ def code_block_error(code: str):
3031

3132
@rx.memo
3233
def markdown_error(text: str):
33-
return rx.markdown(
34+
return markdown_with_shiki(
3435
text,
3536
class_name="font-small text-slate-11 text-start markdown-code",
3637
)

pcweb/flexdown.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ def render(self, env) -> rx.Component:
111111
color=f"{rx.color(color, 11)}",
112112
),
113113
(
114-
rx.markdown(
114+
markdown_with_shiki(
115115
title, margin_y="0px", style=get_code_style(color)
116116
)
117117
if title
@@ -171,7 +171,7 @@ def render(self, env) -> rx.Component:
171171
),
172172
color=f"{rx.color(color, 11)}",
173173
),
174-
rx.markdown(
174+
markdown_with_shiki(
175175
title,
176176
color=f"{rx.color(color, 11)}",
177177
margin_y="0px",
@@ -369,13 +369,13 @@ def render(self, env) -> rx.Component:
369369
rc.accordion_button(
370370
rx.hstack(
371371
(
372-
rx.markdown(
372+
markdown_with_shiki(
373373
title,
374374
margin_y="0px",
375375
style=get_code_style(color),
376376
)
377377
if title
378-
else rx.markdown("Video Description")
378+
else markdown_with_shiki("Video Description")
379379
),
380380
rx.spacer(),
381381
rc.accordion_icon(color=f"{rx.color(color, 11)}"),
@@ -534,3 +534,21 @@ def render(self, env) -> rx.Component:
534534

535535
def markdown(text):
536536
return xd.get_default_block().render_fn(content=text)
537+
538+
539+
def markdown_with_shiki(*args, **kwargs):
540+
"""
541+
Wrapper for the markdown component with a customized component map.
542+
Uses the experimental Shiki-based code block (rx._x.code_block)
543+
instead of the default CodeBlock component for code blocks.
544+
545+
Note: This wrapper should be removed once the default codeblock
546+
in rx.markdown component map is updated to the Shiki-based code block.
547+
"""
548+
return rx.markdown(
549+
*args,
550+
component_map={
551+
"codeblock": lambda value, **props: rx._x.code_block(value, **props)
552+
},
553+
**kwargs
554+
)

pcweb/pages/changelog.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from pcweb.templates.webpage import webpage
44
from pcweb.components.icons.icons import get_icon
55
from pcweb.components.webpage.comps import h1_title
6-
6+
from pcweb.flexdown import markdown_with_shiki
77

88
def change(
99
date: str, version: str, description: str, points: list[str], link: str
@@ -33,7 +33,7 @@ def change(
3333
rx.el.ul(
3434
*[
3535
rx.el.li(
36-
rx.markdown(d, class_name="markdown-code"),
36+
markdown_with_shiki(d, class_name="markdown-code"),
3737
class_name="font-small text-slate-11",
3838
)
3939
for d in points

pcweb/pages/faq.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from pcweb.templates.webpage import webpage
66
from pcweb.constants import DISCORD_URL, CONTRIBUTING_URL
77
from pcweb.components.webpage.comps import h1_title
8+
from pcweb.flexdown import markdown_with_shiki
89
import reflex_chakra as rc
910

1011
faq_items = [
@@ -75,7 +76,7 @@
7576
},
7677
{
7778
"Q": "What usage data is collected?",
78-
"A": rx.markdown(
79+
"A": markdown_with_shiki(
7980
"""
8081
Anonymous usage data allows us to understand how Reflex is used and how we can improve the product.
8182

pcweb/pages/page404.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import reflex as rx
22
from pcweb.templates.webpage import webpage
3+
from pcweb.flexdown import markdown_with_shiki
34

45
contents = f"""
56
# Page Not Found
@@ -12,7 +13,7 @@
1213
def page404():
1314
return rx.center(
1415
rx.vstack(
15-
rx.markdown(contents),
16+
markdown_with_shiki(contents),
1617
rx.spacer(),
1718
),
1819
class_name="h-[80vh] w-full",

0 commit comments

Comments
 (0)