Explorar el Código

Add class-demo to modularization example and improved structure (#2944)

* add class-demo to modularization example and improved structure

* note that name of decorated function can be anything

* code review

---------

Co-authored-by: Falko Schindler <falko@zauberzeug.com>
Rodja Trappe hace 1 año
padre
commit
828692738a

+ 24 - 0
examples/modularization/api_router_example.py

@@ -0,0 +1,24 @@
+import theme
+from message import message
+
+from nicegui import APIRouter, ui
+
+# NOTE: the APIRouter does not yet work with NiceGUI On Air (see https://github.com/zauberzeug/nicegui/discussions/2792)
+router = APIRouter(prefix='/c')
+
+
+@router.page('/')
+def example_page():
+    with theme.frame('- Page C -'):
+        message('Page C')
+        ui.label('This page and its subpages are created using an APIRouter.')
+        ui.link('Item 1', '/c/items/1').classes('text-xl text-grey-8')
+        ui.link('Item 2', '/c/items/2').classes('text-xl text-grey-8')
+        ui.link('Item 3', '/c/items/3').classes('text-xl text-grey-8')
+
+
+@router.page('/items/{id}', dark=True)
+def item(item_id: str):
+    with theme.frame(f'- Page C{item_id} -'):
+        message(f'Item  #{item_id}')
+        ui.link('go back', router.prefix).classes('text-xl text-grey-8')

+ 18 - 0
examples/modularization/class_example.py

@@ -0,0 +1,18 @@
+import theme
+from message import message
+
+from nicegui import ui
+
+
+class ClassExample:
+
+    def __init__(self) -> None:
+        """The page is created as soon as the class is instantiated.
+
+        This can obviously also be done in a method, if you want to decouple the instantiation of the object from the page creation.
+        """
+        @ui.page('/b')
+        def page_b():
+            with theme.frame('- Page B -'):
+                message('Page B')
+                ui.label('This page is defined in a class.')

+ 0 - 21
examples/modularization/example_c.py

@@ -1,21 +0,0 @@
-import theme
-from message import message
-
-from nicegui import APIRouter, ui
-
-router = APIRouter(prefix='/c')
-
-
-@router.page('/')
-def example_page():
-    with theme.frame('- Example C -'):
-        message('Example C')
-        for i in range(1, 4):
-            ui.link(f'Item {i}', f'/c/items/{i}').classes('text-xl text-grey-8')
-
-
-@router.page('/items/{id}', dark=True)
-def item(id: str):
-    with theme.frame(f'- Example C{id} -'):
-        message(f'Item  #{id}')
-        ui.link('go back', router.prefix).classes('text-xl text-grey-8')

+ 0 - 17
examples/modularization/example_pages.py

@@ -1,17 +0,0 @@
-import theme
-from message import message
-
-from nicegui import ui
-
-
-def create() -> None:
-
-    @ui.page('/a')
-    def example_page_a():
-        with theme.frame('- Example A -'):
-            message('Example A')
-
-    @ui.page('/b')
-    def example_page_b():
-        with theme.frame('- Example B -'):
-            message('Example B')

+ 12 - 0
examples/modularization/function_example.py

@@ -0,0 +1,12 @@
+import theme
+from message import message
+
+from nicegui import ui
+
+
+def create() -> None:
+    @ui.page('/a')
+    def page_a():
+        with theme.frame('- Page A -'):
+            message('Page A')
+            ui.label('This page is defined in a function.')

+ 3 - 0
examples/modularization/home_page.py

@@ -1,5 +1,8 @@
 from message import message
 from message import message
 
 
+from nicegui import ui
+
 
 
 def content() -> None:
 def content() -> None:
     message('This is the home page.').classes('font-bold')
     message('This is the home page.').classes('font-bold')
+    ui.label('Use the menu on the top right to navigate.')

+ 11 - 7
examples/modularization/main.py

@@ -1,23 +1,27 @@
 #!/usr/bin/env python3
 #!/usr/bin/env python3
-import example_c
-import example_pages
+import api_router_example
+import class_example
+import function_example
 import home_page
 import home_page
 import theme
 import theme
 
 
 from nicegui import app, ui
 from nicegui import app, ui
 
 
 
 
-# here we use our custom page decorator directly and just put the content creation into a separate function
+# Example 1: use a custom page decorator directly and putting the content creation into a separate function
 @ui.page('/')
 @ui.page('/')
 def index_page() -> None:
 def index_page() -> None:
     with theme.frame('Homepage'):
     with theme.frame('Homepage'):
         home_page.content()
         home_page.content()
 
 
 
 
-# this call shows that you can also move the whole page creation into a separate file
-example_pages.create()
+# Example 2: use a function to move the whole page creation into a separate file
+function_example.create()
 
 
-# we can also use the APIRouter as described in https://nicegui.io/documentation/page#modularize_with_apirouter
-app.include_router(example_c.router)
+# Example 3: use a class to move the whole page creation into a separate file
+class_example.ClassExample()
+
+# Example 4: use APIRouter as described in https://nicegui.io/documentation/page#modularize_with_apirouter
+app.include_router(api_router_example.router)
 
 
 ui.run(title='Modularization Example')
 ui.run(title='Modularization Example')

+ 5 - 3
examples/modularization/theme.py

@@ -6,12 +6,14 @@ from nicegui import ui
 
 
 
 
 @contextmanager
 @contextmanager
-def frame(navtitle: str):
+def frame(navigation_title: str):
     """Custom page frame to share the same styling and behavior across all pages"""
     """Custom page frame to share the same styling and behavior across all pages"""
     ui.colors(primary='#6E93D6', secondary='#53B689', accent='#111B1E', positive='#53B689')
     ui.colors(primary='#6E93D6', secondary='#53B689', accent='#111B1E', positive='#53B689')
-    with ui.header().classes('justify-between text-white'):
+    with ui.header():
         ui.label('Modularization Example').classes('font-bold')
         ui.label('Modularization Example').classes('font-bold')
-        ui.label(navtitle)
+        ui.space()
+        ui.label(navigation_title)
+        ui.space()
         with ui.row():
         with ui.row():
             menu()
             menu()
     with ui.column().classes('absolute-center items-center'):
     with ui.column().classes('absolute-center items-center'):

+ 4 - 0
nicegui/page.py

@@ -40,6 +40,10 @@ class page:
         This means it is private to the user and not shared with others
         This means it is private to the user and not shared with others
         (as it is done `when placing elements outside of a page decorator <https://nicegui.io/documentation/section_pages_routing#auto-index_page>`_).
         (as it is done `when placing elements outside of a page decorator <https://nicegui.io/documentation/section_pages_routing#auto-index_page>`_).
 
 
+        Note:
+        The name of the decorated function is unused and can be anything.
+        The page route is determined by the `path` argument and registered globally.
+
         :param path: route of the new page (path must start with '/')
         :param path: route of the new page (path must start with '/')
         :param title: optional page title
         :param title: optional page title
         :param viewport: optional viewport meta tag content
         :param viewport: optional viewport meta tag content

+ 1 - 1
website/documentation/content/section_action_events.py

@@ -72,7 +72,7 @@ doc.intro(generic_events_documentation)
     This is useful for long-running computations that would otherwise block the event loop and make the UI unresponsive.
     This is useful for long-running computations that would otherwise block the event loop and make the UI unresponsive.
     The function returns a future that can be awaited.
     The function returns a future that can be awaited.
 
 
-    **Note:**
+    Note:
     The function needs to transfer the whole state of the passed function to the process, which is done with pickle.
     The function needs to transfer the whole state of the passed function to the process, which is done with pickle.
     It is encouraged to create free functions or static methods which get all the data as simple parameters (i.e. no class or UI logic)
     It is encouraged to create free functions or static methods which get all the data as simple parameters (i.e. no class or UI logic)
     and return the result, instead of writing it in class properties or global variables.
     and return the result, instead of writing it in class properties or global variables.

+ 1 - 1
website/documentation/content/section_configuration_deployment.py

@@ -243,7 +243,7 @@ def install_pyinstaller():
 
 
 
 
 doc.text('', '''
 doc.text('', '''
-    **Note:**
+    Note:
     If you're getting an error "TypeError: a bytes-like object is required, not 'str'", try adding the following lines to the top of your `main.py` file:
     If you're getting an error "TypeError: a bytes-like object is required, not 'str'", try adding the following lines to the top of your `main.py` file:
     ```py
     ```py
     import sys
     import sys