From 9010a687af200d68b5494f808f68b58611f4362d Mon Sep 17 00:00:00 2001 From: Daniel Chen Date: Tue, 22 Apr 2025 12:53:30 -0700 Subject: [PATCH 1/9] ci: attempt to add lychee link checking --- .github/workflows/deploy-docs.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index f4220215..46eeb1e9 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -5,6 +5,8 @@ on: branches: [main] pull_request: workflow_dispatch: + schedule: + - cron: "0 3 * * 1" # every Monday at 3 AM UTC env: QUARTO_VERSION: 1.6.42 @@ -114,3 +116,23 @@ jobs: env: ${{ steps.deployment.outputs.env }} env_url: "https://${{ steps.deployment.outputs.env }}--pyshiny.netlify.app" logs: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}" + + - name: Upload site artifact + uses: actions/upload-artifact@v4 + with: + name: rendered-site + path: _build + + check-links: + runs-on: ubuntu-latest + needs: build + steps: + - uses: actions/download-artifact@v4 + with: + name: rendered-site + path: _build + + - name: Run lychee link checker + uses: lycheeverse/lychee-action@v2 + with: + args: --verbose ./_build From 8936c7e3ad262515556aedbdd87d41a6bd581e8a Mon Sep 17 00:00:00 2001 From: Daniel Chen Date: Tue, 22 Apr 2025 13:34:04 -0700 Subject: [PATCH 2/9] ci[lychee]: ignore qmd links in _build --- .github/workflows/deploy-docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 46eeb1e9..2f8ab5d4 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -135,4 +135,4 @@ jobs: - name: Run lychee link checker uses: lycheeverse/lychee-action@v2 with: - args: --verbose ./_build + args: --verbose ./_build --exclude '.*\.qmd$' From e90cab942588822bf1818532852642afb5f86e2a Mon Sep 17 00:00:00 2001 From: Daniel Chen Date: Tue, 22 Apr 2025 13:42:31 -0700 Subject: [PATCH 3/9] ci[lychee]: exclude edit/main pages (usually quarto and may not be in the repo) --- .github/workflows/deploy-docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index 2f8ab5d4..bed99b9f 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -135,4 +135,4 @@ jobs: - name: Run lychee link checker uses: lycheeverse/lychee-action@v2 with: - args: --verbose ./_build --exclude '.*\.qmd$' + args: --verbose ./_build --exclude '.*\.qmd$' --exclude '^https://github.com/posit-dev/py-shiny-site/edit/main/.*' From 52f15b2bef23a4cd74b3014363723df724a373eb Mon Sep 17 00:00:00 2001 From: Daniel Chen Date: Tue, 22 Apr 2025 14:26:50 -0700 Subject: [PATCH 4/9] ci[lychee]: use lychee.toml to config --- .github/workflows/deploy-docs.yml | 2 +- lychee.toml | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 lychee.toml diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index bed99b9f..f1e20dd3 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -135,4 +135,4 @@ jobs: - name: Run lychee link checker uses: lycheeverse/lychee-action@v2 with: - args: --verbose ./_build --exclude '.*\.qmd$' --exclude '^https://github.com/posit-dev/py-shiny-site/edit/main/.*' + args: --verbose --config ./lychee.toml ./_build diff --git a/lychee.toml b/lychee.toml new file mode 100644 index 00000000..ad9a3307 --- /dev/null +++ b/lychee.toml @@ -0,0 +1,18 @@ +# Enable link caching. This can be helpful to avoid checking the same links on +# multiple runs. +cache = true + +# Discard all cached requests older than this duration. +max_cache_age = "2d" + +############################# Exclusions ########################## + +# Check links inside `` and `
` blocks as well as Markdown code
+# blocks.
+include_verbatim = false
+
+# Exclude URLs and mail addresses from checking (supports regex).
+exclude = [
+  '^https://github.com/posit-dev/py-shiny-site/edit/main/.*',
+  '^file:.*',
+]

From 10c5308995ef756074d5af268196a96d23d0a024 Mon Sep 17 00:00:00 2001
From: Daniel Chen 
Date: Tue, 22 Apr 2025 14:59:03 -0700
Subject: [PATCH 5/9] ci[lychee]: check out the repo to find the config file

---
 .github/workflows/deploy-docs.yml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml
index f1e20dd3..32e272d4 100644
--- a/.github/workflows/deploy-docs.yml
+++ b/.github/workflows/deploy-docs.yml
@@ -127,6 +127,8 @@ jobs:
     runs-on: ubuntu-latest
     needs: build
     steps:
+      - uses: actions/checkout@v4
+
       - uses: actions/download-artifact@v4
         with:
           name: rendered-site

From e6ed177d42a4a78c3fda926cb66b8a43cb2b71f7 Mon Sep 17 00:00:00 2001
From: Daniel Chen 
Date: Thu, 24 Apr 2025 14:29:45 -0700
Subject: [PATCH 6/9] ignore support.posit.co and reference API URLS
 (redirects)

---
 lychee.toml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/lychee.toml b/lychee.toml
index ad9a3307..33b24613 100644
--- a/lychee.toml
+++ b/lychee.toml
@@ -15,4 +15,6 @@ include_verbatim = false
 exclude = [
   '^https://github.com/posit-dev/py-shiny-site/edit/main/.*',
   '^file:.*',
+  "^https://support.posit.co",
+  "^ https://shiny.posit.co/py/api/",
 ]

From eb884911f383e3d530085702d13f041ca0e9e0fd Mon Sep 17 00:00:00 2001
From: Daniel Chen 
Date: Thu, 24 Apr 2025 17:40:52 -0700
Subject: [PATCH 7/9] fix broken URLS

---
 docs/deploy-on-prem.qmd           |  2 +-
 docs/jupyter-widgets.qmd          |  2 +-
 layouts/arrange/index.qmd         |  2 +-
 layouts/navbars/index.qmd         |  6 +++---
 layouts/tabs/index.qmd            | 10 +++++-----
 templates/basic-chatbot/index.qmd |  4 ++--
 6 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/docs/deploy-on-prem.qmd b/docs/deploy-on-prem.qmd
index 9625f7bf..1fd1b7db 100644
--- a/docs/deploy-on-prem.qmd
+++ b/docs/deploy-on-prem.qmd
@@ -134,7 +134,7 @@ Finally, you will need to [restart](https://docs.posit.co/shiny-server/#stopping
 Not working for you?
 Look for clues in `/var/log/shiny-server.log` and `/var/log/shiny-server/*.log`.
 
-See the [Shiny Server Administrator's Guide](https://docs.posit.co/shiny-server//) for other options.
+See the [Shiny Server Administrator's Guide](https://docs.posit.co/shiny-server/) for other options.
 (Note that the Admin Guide includes documentation for the commercially licensed Professional edition of Shiny Server, and includes features marked "Pro Only". Shiny Server Professional is no longer available for new customers, and doesn't support Shiny for Python; our commercially licensed on-premises server these days is Posit Connect.)
 
 ## Other hosting options
diff --git a/docs/jupyter-widgets.qmd b/docs/jupyter-widgets.qmd
index b7f412b0..e645530e 100644
--- a/docs/jupyter-widgets.qmd
+++ b/docs/jupyter-widgets.qmd
@@ -373,7 +373,7 @@ Under the hood, `reactive_read()` uses [ipywidgets' `observe()` method](https://
 :::
 
 Some widgets have attributes that _contain_ observable traits.
-One practical example of this is the `selections` attribute of altair's `JupyterChart` class, which has an [observable `point` trait](https://altair-viz.github.io/user_guide/jupyter_chart.html#point-selections).
+One practical example of this is the `selections` attribute of altair's `JupyterChart` class, which has an [observable `point` trait](https://altair-viz.github.io/user_guide/interactions/jupyter_chart.html#point-selections).
 
 ```{shinylive-python}
 #| standalone: true
diff --git a/layouts/arrange/index.qmd b/layouts/arrange/index.qmd
index 61af13fb..856e22d6 100644
--- a/layouts/arrange/index.qmd
+++ b/layouts/arrange/index.qmd
@@ -119,7 +119,7 @@ There's a lot more that `layout_columns()` can do with `col_widths` to make high
 
 -   Insert empty space between items with a negative column width, e.g. `col_widths=c(4, -4, 4)` creates two columns 4 units wide with an empty space of 4 units between them.
 
-Learn more in the API reference: [Express](https://shiny.posit.co/py/api/express/ui.layout_columns.html) \| [Core](https://shiny.posit.co/py/api/core/ui.layout_columns.html)
+Learn more in the API reference: [Express](https://shiny.posit.co/py/api/express/express.ui.layout_columns.html) \| [Core](https://shiny.posit.co/py/api/core/ui.layout_columns.html)
 :::
 
 
diff --git a/layouts/navbars/index.qmd b/layouts/navbars/index.qmd
index 97578d99..d10cd9c3 100644
--- a/layouts/navbars/index.qmd
+++ b/layouts/navbars/index.qmd
@@ -9,7 +9,7 @@ listing:
   template: ../../components/_partials/components-detail-relevant-functions.ejs
   contents:
   - title: ui.page_navbar
-    href: https://shiny.posit.co/py/api/ui.page_navbar.html
+    href: https://shiny.posit.co/py/api/core/ui.page_navbar.html
     signature: ui.page_navbar(*args, title=None, id=None, selected=None, sidebar=None, fillable=True, fillable_mobile=False, gap=None, padding=None, position='static-top', header=None, footer=None, bg=None, inverse=False, underline=True, collapsible=True, fluid=True, window_title=MISSING, lang=None)
   - title: ui.nav
     href: https://shiny.posit.co/py/api/ui.nav.html
@@ -47,7 +47,7 @@ Follow these steps to add a navbar to the top of your app:
 
   1. Define a navbar page layout with `ui.page_navbar()`.
 
-  2. Pass nav items (e.g., [`ui.nav_panel()`](https://shiny.posit.co/py/api/ui.nav.html) and [`ui.nav_menu()`](https://shiny.posit.co/py/api/ui.nav_menu.html)) to `ui.page_navbar()` to control the items displayed in the navbar.
+  2. Pass nav items (e.g., [`ui.nav_panel()`](https://shiny.posit.co/py/api/core/ui.nav_panel.html) and [`ui.nav_menu()`](https://shiny.posit.co/py/api/core/ui.nav_menu.html)) to `ui.page_navbar()` to control the items displayed in the navbar.
 
   3. Set the `title` argument of `ui.page_navbar()` to set the browser window title.
 
@@ -74,7 +74,7 @@ Follow these steps to add a navbar to the bottom of your app:
 
   1. Define a navbar page layout with `ui.page_navbar()`.
 
-  2. Pass nav items (e.g., [`ui.nav_panel()`](https://shiny.posit.co/py/api/ui.nav.html) and [`ui.nav_menu()`](https://shiny.posit.co/py/api/ui.nav_menu.html)) to `ui.page_navbar()` to control the items displayed in the navbar.
+  2. Pass nav items (e.g., [`ui.nav_panel()`](https://shiny.posit.co/py/api/core/ui.nav_panel.html) and [`ui.nav_menu()`](https://shiny.posit.co/py/api/core/ui.nav_menu.html)) to `ui.page_navbar()` to control the items displayed in the navbar.
 
   3. Set the `position` parameter of `ui.page_navbar()` to `"fixed-bottom"` to pin the navbar to the bottom of the app. By default, `position` is `"static-top"`, which causes the navbar to display at the top with normal scrolling behavior. You can also pin the navbar to the top (`position="fixed-top"`).
 
diff --git a/layouts/tabs/index.qmd b/layouts/tabs/index.qmd
index 198d362e..223244e1 100644
--- a/layouts/tabs/index.qmd
+++ b/layouts/tabs/index.qmd
@@ -67,7 +67,7 @@ Follow these steps to create an app with a tabset with pill navigation layout:
 
   1. Add `ui.navset_pill()` inside any Shiny UI page method (e.g., `ui.page_fluid()`). `ui.navset_pill()` creates a pillset.
 
-  2. Pass nav items (e.g., [`ui.nav_panel()`](https://shiny.posit.co/py/api/ui.nav.html) and [`ui.nav_menu()`](https://shiny.posit.co/py/api/ui.nav_menu.html)) to `ui.navset_pill()` to set the items displayed in the navset.
+  2. Pass nav items (e.g., [`ui.nav_panel()`](https://shiny.posit.co/py/api/core/ui.nav_panel.html) and [`ui.nav_menu()`](https://shiny.posit.co/py/api/core/ui.nav_menu.html)) to `ui.navset_pill()` to set the items displayed in the navset.
 
   3. Pass arguments to the nav items to control each item's title, appearance, and associated content. For example, set the `title` argument of `ui.nav_panel()` to control the displayed title of the nav item. Pass UI elements as additional arguments to `ui.nav_panel()`. These elements will be displayed when the tab is active.
 
@@ -91,7 +91,7 @@ Follow these steps to create an app with a pill list navigation layout. A pill l
 
   1. Add `ui.navset_pill_list()` inside any Shiny UI page method (e.g., `ui.page_fluid()`). `ui.navset_pill()` creates a pill list.
 
-  2. Pass nav items (e.g., [`ui.nav_panel()`](https://shiny.posit.co/py/api/ui.nav.html) and [`ui.nav_menu()`](https://shiny.posit.co/py/api/ui.nav_menu.html)) to `ui.navset_pill_list()` to set the items displayed in the pillset.
+  2. Pass nav items (e.g., [`ui.nav_panel()`](https://shiny.posit.co/py/api/core/ui.nav_panel.html) and [`ui.nav_menu()`](https://shiny.posit.co/py/api/core/ui.nav_menu.html)) to `ui.navset_pill_list()` to set the items displayed in the pillset.
 
   3. Pass arguments to the nav items to control each item's title, appearance, and associated content. For example, set the `title` argument of `ui.nav_panel()` to control the displayed title of the nav item. Pass UI elements as additional arguments to `ui.nav_panel()`. These elements will be displayed when the tab is active.
 
@@ -115,7 +115,7 @@ Follow these steps to create an app with a tab navigation layout:
 
   1. Add `ui.navset_tab()` inside any Shiny UI page method (e.g., `ui.page_fluid()`). `ui.navset_tab()` creates a tabset.
 
-  2. Pass nav items (e.g., [`ui.nav_panel()`](https://shiny.posit.co/py/api/ui.nav.html) and [`ui.nav_menu()`](https://shiny.posit.co/py/api/ui.nav_menu.html)) to `ui.navset_tab()` to set the items displayed in the tabset.
+  2. Pass nav items (e.g., [`ui.nav_panel()`](https://shiny.posit.co/py/api/core/ui.nav_panel.html) and [`ui.nav_menu()`](https://shiny.posit.co/py/api/core/ui.nav_menu.html)) to `ui.navset_tab()` to set the items displayed in the tabset.
 
   3. Pass arguments to the nav items to control each item's title, appearance, and associated content. For example, set the `title` argument of `ui.nav_panel()` to control the displayed title of the nav item. Pass UI elements as additional arguments to `ui.nav_panel()`. These elements will be displayed when the tab is active.
 
@@ -139,7 +139,7 @@ Follow these steps to add a card with a tabbed tabset to your app:
 
   1. Add `ui.navset_card_tab()` inside any Shiny UI page method (e.g., `ui.page_fluid()`). `ui.navset_card_tab()` creates a tabset inside a card.
 
-  2. Pass nav items (e.g., [`ui.nav_panel()`](https://shiny.posit.co/py/api/ui.nav.html) and [`ui.nav_menu()`](https://shiny.posit.co/py/api/ui.nav_menu.html)) to `ui.navset_card_tab()` to set the items displayed in the tabset inside the card.
+  2. Pass nav items (e.g., [`ui.nav_panel()`](https://shiny.posit.co/py/api/core/ui.nav_panel.html) and [`ui.nav_menu()`](https://shiny.posit.co/py/api/core/ui.nav_menu.html)) to `ui.navset_card_tab()` to set the items displayed in the tabset inside the card.
 
   3. Pass arguments to the nav items to control each item's title, appearance, and associated content. For example, set the `title` argument of `ui.nav_panel()` to control the displayed title of the nav item. Pass UI elements as additional arguments to `ui.nav_panel()`. These elements will be displayed when the tab is active.
 
@@ -163,7 +163,7 @@ Follow these steps to add a card with a pill tabset to your app:
 
   1. Add `ui.navset_card_pill()` inside any Shiny UI page method (e.g., `ui.page_fluid()`). `ui.navset_card_pill()` creates a pillset inside a card.
 
-  2. Pass nav items (e.g., [`ui.nav_panel()`](https://shiny.posit.co/py/api/ui.nav.html) and [`ui.nav_menu()`](https://shiny.posit.co/py/api/ui.nav_menu.html)) to `ui.navset_card_pill()` to set the items displayed in the pillset inside the card.
+  2. Pass nav items (e.g., [`ui.nav_panel()`](https://shiny.posit.co/py/api/core/ui.nav_panel.html) and [`ui.nav_menu()`](https://shiny.posit.co/py/api/core/ui.nav_menu.html)) to `ui.navset_card_pill()` to set the items displayed in the pillset inside the card.
 
   3. Pass arguments to the nav items to control each item's title, appearance, and associated content. For example, set the `title` argument of `ui.nav_panel()` to control the displayed title of the nav item. Pass UI elements as additional arguments to `ui.nav_panel()`. These elements will be displayed when the tab is active.
 
diff --git a/templates/basic-chatbot/index.qmd b/templates/basic-chatbot/index.qmd
index c1c99d53..a295f662 100644
--- a/templates/basic-chatbot/index.qmd
+++ b/templates/basic-chatbot/index.qmd
@@ -5,8 +5,8 @@ date:         2025-03-25
 image:        thumbnail.png
 imagealt:     "A screenshot of the basic-chatbot template"
 app-height:   600px
-appurl:       https://posit-ai.basic-chatbot.share.connect.posit.cloud/
-sourceurl:    https://github.com/posit-dev/py-shiny-templates/tree/main/gen-ai/basic-chatbot
+appurl:       https://posit-ai-basic-chat.share.connect.posit.cloud/
+sourceurl:    https://github.com/posit-dev/py-shiny-templates/tree/main/gen-ai/basic-chat
 ---
 
 ::: {.panel-tabset .shiny-mode-tabset  group="shiny-app-mode"}

From 7cddd2ee1a449d286e06cd208c3e3c31ebdc13e4 Mon Sep 17 00:00:00 2001
From: Daniel Chen 
Date: Thu, 24 Apr 2025 17:42:20 -0700
Subject: [PATCH 8/9] actually, do check the API URLs

---
 lychee.toml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lychee.toml b/lychee.toml
index 33b24613..93cf15c3 100644
--- a/lychee.toml
+++ b/lychee.toml
@@ -16,5 +16,4 @@ exclude = [
   '^https://github.com/posit-dev/py-shiny-site/edit/main/.*',
   '^file:.*',
   "^https://support.posit.co",
-  "^ https://shiny.posit.co/py/api/",
 ]

From 46c70c68041cf5111d76fd53e38943cf73e78b41 Mon Sep 17 00:00:00 2001
From: Daniel Chen 
Date: Tue, 29 Apr 2025 07:49:01 -0700
Subject: [PATCH 9/9] fix link from ui.nav to ui.nav_panel

---
 layouts/navbars/index.qmd | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/layouts/navbars/index.qmd b/layouts/navbars/index.qmd
index d10cd9c3..2bb630b3 100644
--- a/layouts/navbars/index.qmd
+++ b/layouts/navbars/index.qmd
@@ -11,8 +11,8 @@ listing:
   - title: ui.page_navbar
     href: https://shiny.posit.co/py/api/core/ui.page_navbar.html
     signature: ui.page_navbar(*args, title=None, id=None, selected=None, sidebar=None, fillable=True, fillable_mobile=False, gap=None, padding=None, position='static-top', header=None, footer=None, bg=None, inverse=False, underline=True, collapsible=True, fluid=True, window_title=MISSING, lang=None)
-  - title: ui.nav
-    href: https://shiny.posit.co/py/api/ui.nav.html
+  - title: ui.nav_panel
+    href: https://shiny.posit.co/py/api/core/ui.nav_panel.html
     signature: ui.nav_panel(title, *args, value=None, icon=None)
 ---