Parcourir la source

add examples to search index

Falko Schindler il y a 1 an
Parent
commit
9ef0ab39a1

+ 2 - 1
website/documentation/__init__.py

@@ -1,4 +1,4 @@
-from . import content, registry
+from . import content, registry, search
 from .intro import create_intro
 from .intro import create_intro
 from .rendering import render_page
 from .rendering import render_page
 from .search import build_search_index
 from .search import build_search_index
@@ -13,4 +13,5 @@ __all__ = [
     'python_window',
     'python_window',
     'registry',
     'registry',
     'render_page',
     'render_page',
+    'search',
 ]
 ]

+ 8 - 0
website/documentation/search.py

@@ -1,6 +1,7 @@
 import json
 import json
 from pathlib import Path
 from pathlib import Path
 
 
+from ..examples import examples
 from . import registry
 from . import registry
 
 
 PATH = Path(__file__).parent.parent / 'static' / 'search_index.json'
 PATH = Path(__file__).parent.parent / 'static' / 'search_index.json'
@@ -16,5 +17,12 @@ def build_search_index() -> None:
         }
         }
         for documentation in registry.registry.values()
         for documentation in registry.registry.values()
         for part in documentation
         for part in documentation
+    ] + [
+        {
+            'title': f'Example: {example.title}',
+            'content': example.description,
+            'url': example.url,
+        }
+        for example in examples
     ]
     ]
     PATH.write_text(json.dumps(index, indent=2))
     PATH.write_text(json.dumps(index, indent=2))

+ 62 - 0
website/examples.py

@@ -0,0 +1,62 @@
+from dataclasses import dataclass, field
+from pathlib import Path
+from typing import List
+
+PATH = Path(__file__).parent.parent / 'examples'
+
+
+@dataclass
+class Example:
+    title: str
+    description: str
+    url: str = field(init=False)
+
+    def __post_init__(self) -> None:
+        """Post-initialization hook."""
+        name = self.title.lower().replace(' ', '_')
+        content = [p for p in (PATH / name).glob('*') if p.name != '__pycache__' and not p.name.startswith('.')]
+        filename = 'main.py' if len(content) == 1 else ''
+        self.url = f'https://github.com/zauberzeug/nicegui/tree/main/examples/{name}/{filename}'
+
+
+examples: List[Example] = [
+    Example('Slideshow', 'implements a keyboard-controlled image slideshow'),
+    Example('Authentication', 'shows how to use sessions to build a login screen'),
+    Example('Modularization', 'provides an example of how to modularize your application into multiple files and reuse code'),
+    Example('FastAPI', 'illustrates the integration of NiceGUI with an existing FastAPI application'),
+    Example('Map',
+            'demonstrates wrapping the JavaScript library [leaflet](https://leafletjs.com/) to display a map at specific locations'),
+    Example('AI Interface',
+            'utilizes the [replicate](https://replicate.com) library to perform voice-to-text transcription and generate images from prompts with Stable Diffusion'),
+    Example('3D Scene', 'creates a webGL view and loads an STL mesh illuminated with a spotlight'),
+    Example('Custom Vue Component', 'shows how to write and integrate a custom Vue component'),
+    Example('Image Mask Overlay', 'shows how to overlay an image with a mask'),
+    Example('Infinite Scroll', 'presents an infinitely scrolling image gallery'),
+    Example('OpenCV Webcam', 'uses OpenCV to capture images from a webcam'),
+    Example('SVG Clock', 'displays an analog clock by updating an SVG with `ui.timer`'),
+    Example('Progress', 'demonstrates a progress bar for heavy computations'),
+    Example('NGINX Subpath', 'shows the setup to serve an app behind a reverse proxy subpath'),
+    Example('Script Executor', 'executes scripts on selection and displays the output'),
+    Example('Local File Picker', 'demonstrates a dialog for selecting files locally on the server'),
+    Example('Search as you type', 'using public API of thecocktaildb.com to search for cocktails'),
+    Example('Menu and Tabs', 'uses Quasar to create foldable menu and tabs inside a header bar'),
+    Example('Todo list', 'shows a simple todo list with checkboxes and text input'),
+    Example('Trello Cards', 'shows Trello-like cards that can be dragged and dropped into columns'),
+    Example('Slots', 'shows how to use scoped slots to customize Quasar elements'),
+    Example('Table and slots', 'shows how to use component slots in a table'),
+    Example('Single Page App', 'navigate without reloading the page'),
+    Example('Chat App', 'a simple chat app'),
+    Example('Chat with AI', 'a simple chat app with AI'),
+    Example('SQLite Database', 'CRUD operations on a SQLite database with async-support through Tortoise ORM'),
+    Example('Pandas DataFrame', 'displays an editable [pandas](https://pandas.pydata.org) DataFrame'),
+    Example('Lightbox', 'a thumbnail gallery where each image can be clicked to enlarge'),
+    Example('ROS2', 'Using NiceGUI as web interface for a ROS2 robot'),
+    Example('Docker Image',
+            'use the official [zauberzeug/nicegui](https://hub.docker.com/r/zauberzeug/nicegui) docker image'),
+    Example('Download Text as File', 'providing in-memory data like strings as file download'),
+    Example('Generate PDF', 'create an SVG preview and PDF download from input form elements'),
+    Example('Custom Binding', 'create a custom binding for a label with a bindable background color'),
+    Example('Descope Auth', 'login form and user profile using [Descope](https://descope.com)'),
+    Example('Editable table', 'editable table allowing to add, edit, delete rows'),
+    Example('Editable AG Grid', 'editable AG Grid allowing to add, edit, delete rows'),
+]

+ 3 - 43
website/main_page.py

@@ -1,6 +1,7 @@
 from nicegui import context, ui
 from nicegui import context, ui
 
 
 from . import documentation, example_card, svg
 from . import documentation, example_card, svg
+from .examples import examples
 from .header import add_head_html, add_header
 from .header import add_head_html, add_header
 from .style import example_link, features, heading, link_target, section_heading, subtitle, title
 from .style import example_link, features, heading, link_target, section_heading, subtitle, title
 
 
@@ -155,49 +156,8 @@ def create() -> None:
         link_target('examples', '-50px')
         link_target('examples', '-50px')
         section_heading('In-depth examples', 'Pick your *solution*')
         section_heading('In-depth examples', 'Pick your *solution*')
         with ui.row().classes('w-full text-lg leading-tight grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-4'):
         with ui.row().classes('w-full text-lg leading-tight grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-4'):
-            example_link('Slideshow', 'implements a keyboard-controlled image slideshow')
-            example_link('Authentication', 'shows how to use sessions to build a login screen')
-            example_link('Modularization',
-                         'provides an example of how to modularize your application into multiple files and reuse code')
-            example_link('FastAPI', 'illustrates the integration of NiceGUI with an existing FastAPI application')
-            example_link('Map',
-                         'demonstrates wrapping the JavaScript library [leaflet](https://leafletjs.com/) '
-                         'to display a map at specific locations')
-            example_link('AI Interface',
-                         'utilizes the [replicate](https://replicate.com) library to perform voice-to-text '
-                         'transcription and generate images from prompts with Stable Diffusion')
-            example_link('3D Scene', 'creates a webGL view and loads an STL mesh illuminated with a spotlight')
-            example_link('Custom Vue Component', 'shows how to write and integrate a custom Vue component')
-            example_link('Image Mask Overlay', 'shows how to overlay an image with a mask')
-            example_link('Infinite Scroll', 'presents an infinitely scrolling image gallery')
-            example_link('OpenCV Webcam', 'uses OpenCV to capture images from a webcam')
-            example_link('SVG Clock', 'displays an analog clock by updating an SVG with `ui.timer`')
-            example_link('Progress', 'demonstrates a progress bar for heavy computations')
-            example_link('NGINX Subpath', 'shows the setup to serve an app behind a reverse proxy subpath')
-            example_link('Script Executor', 'executes scripts on selection and displays the output')
-            example_link('Local File Picker', 'demonstrates a dialog for selecting files locally on the server')
-            example_link('Search as you type', 'using public API of thecocktaildb.com to search for cocktails')
-            example_link('Menu and Tabs', 'uses Quasar to create foldable menu and tabs inside a header bar')
-            example_link('Todo list', 'shows a simple todo list with checkboxes and text input')
-            example_link('Trello Cards', 'shows Trello-like cards that can be dragged and dropped into columns')
-            example_link('Slots', 'shows how to use scoped slots to customize Quasar elements')
-            example_link('Table and slots', 'shows how to use component slots in a table')
-            example_link('Single Page App', 'navigate without reloading the page')
-            example_link('Chat App', 'a simple chat app')
-            example_link('Chat with AI', 'a simple chat app with AI')
-            example_link('SQLite Database', 'CRUD operations on a SQLite database with async-support through Tortoise ORM')
-            example_link('Pandas DataFrame', 'displays an editable [pandas](https://pandas.pydata.org) DataFrame')
-            example_link('Lightbox', 'A thumbnail gallery where each image can be clicked to enlarge')
-            example_link('ROS2', 'Using NiceGUI as web interface for a ROS2 robot')
-            example_link('Docker Image',
-                         'Demonstrate using the official '
-                         '[zauberzeug/nicegui](https://hub.docker.com/r/zauberzeug/nicegui) docker image')
-            example_link('Download Text as File', 'providing in-memory data like strings as file download')
-            example_link('Generate PDF', 'create SVG preview and PDF download from input form elements')
-            example_link('Custom Binding', 'create a custom binding for a label with a bindable background color')
-            example_link('Descope Auth', 'login form and user profile using [Descope](https://descope.com)')
-            example_link('Editable table', 'editable table allowing to add, edit, delete rows')
-            example_link('Editable AG Grid', 'editable AG Grid allowing to add, edit, delete rows')
+            for example in examples:
+                example_link(example)
 
 
     with ui.row().classes('dark-box min-h-screen mt-16'):
     with ui.row().classes('dark-box min-h-screen mt-16'):
         link_target('why')
         link_target('why')

+ 6 - 9
website/style.py

@@ -1,9 +1,10 @@
 import re
 import re
-from pathlib import Path
 from typing import List, Optional
 from typing import List, Optional
 
 
 from nicegui import context, ui
 from nicegui import context, ui
 
 
+from .examples import Example
+
 SPECIAL_CHARACTERS = re.compile('[^(a-z)(A-Z)(0-9)-]')
 SPECIAL_CHARACTERS = re.compile('[^(a-z)(A-Z)(0-9)-]')
 
 
 
 
@@ -36,17 +37,13 @@ def subtitle(content: str) -> ui.markdown:
     return ui.markdown(content).classes('text-xl sm:text-2xl md:text-3xl leading-7')
     return ui.markdown(content).classes('text-xl sm:text-2xl md:text-3xl leading-7')
 
 
 
 
-def example_link(title_: str, description: str) -> None:
+def example_link(example: Example) -> None:
     """Render a link to an example."""
     """Render a link to an example."""
-    name = title_.lower().replace(' ', '_')
-    directory = Path(__file__).parent.parent / 'examples' / name
-    content = [p for p in directory.glob('*') if p.name != '__pycache__' and not p.name.startswith('.')]
-    filename = 'main.py' if len(content) == 1 else ''
-    with ui.link(target=f'https://github.com/zauberzeug/nicegui/tree/main/examples/{name}/{filename}') \
+    with ui.link(target=example.url) \
             .classes('bg-[#5898d420] p-4 self-stretch rounded flex flex-col gap-2') \
             .classes('bg-[#5898d420] p-4 self-stretch rounded flex flex-col gap-2') \
             .style('box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1)'):
             .style('box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1)'):
-        ui.label(title_).classes(replace='font-bold')
-        ui.markdown(description).classes(replace='bold-links arrow-links')
+        ui.label(example.title).classes(replace='font-bold')
+        ui.markdown(example.description).classes(replace='bold-links arrow-links')
 
 
 
 
 def features(icon: str, title_: str, items: List[str]) -> None:
 def features(icon: str, title_: str, items: List[str]) -> None: