From ab0475cdc1961d2a4d996d59205fd698e3a66c0f Mon Sep 17 00:00:00 2001 From: Zack Spear Date: Wed, 2 Jul 2025 13:50:23 -0700 Subject: [PATCH] docs: enhance migration guide with new sections and clarifications - Added a Table of Contents for easier navigation. - Updated the introduction to clarify the shift to responsive CSS. - Improved explanations for common bugs and fixes, including detailed examples and formatting adjustments. - Emphasized the importance of whitespace and structure in Markdown parsing. - Included a warning about opting out of responsive layout, with clear options for developers. This update aims to provide comprehensive guidance for developers transitioning to the responsive design system. No further changes are pending for this task. --- ...esponsive-webgui-plugin-migration-guide.md | 218 ++++++++++++++---- 1 file changed, 169 insertions(+), 49 deletions(-) diff --git a/docs/responsive-webgui-plugin-migration-guide.md b/docs/responsive-webgui-plugin-migration-guide.md index c4097e5ef..30176382f 100644 --- a/docs/responsive-webgui-plugin-migration-guide.md +++ b/docs/responsive-webgui-plugin-migration-guide.md @@ -1,16 +1,21 @@ # Responsive WebGUI Plugin Migration Guide +## Table of Contents + +- [Why Responsive? The Benefits for Unraid Users & Developers](#why-responsive-the-benefits-for-unraid-users--developers) +- [Prerequisite: How .page Files Are Parsed](#prerequisite-how-page-files-are-parsed-markdown-whitespace-and-structure) +- [Common Bugs in .page Files](#common-bugs-in-page-files-and-how-to-fix-them) +- [Making Wide Tables Responsive](#making-wide-tables-responsive-using-the-tablecontainer-class) +- [Summary](#summary) +- [Quick Fix: Opting Out of Responsive Layout](#quick-fix-opting-out-of-responsive-layout-if-youre-short-on-time) + ## Why Responsive? The Benefits for Unraid Users & Developers -Unraid's webGUI has moved to a fully responsive design system. This isn't just a facelift—it's a fundamental shift in how plugins and core pages are built and rendered. Here's why this matters: +Unraid's webGUI has been refactored to support responsive CSS. Here's why this matters: -- **Mobile & Tablet Friendly:** Manage your server from any device, any screen size, no more pinching/zooming. +- **Mobile & Tablet Friendly:** Manage your server from any device, any screen size, no more pinching/zooming required. - **Consistent Layouts:** No more broken forms or tables on small screens. Everything adapts. - **Modern Look & Feel:** Cleaner, more professional UI that matches user expectations. -- **Future-Proof:** New features and plugins can be built once, work everywhere. -- **Accessibility:** Improved support for screen readers and keyboard navigation. - -**Bottom line:** Users get a better experience, and plugin devs spend less time fighting CSS and more time building features. --- @@ -19,23 +24,29 @@ Unraid's webGUI has moved to a fully responsive design system. This isn't just a Unraid's plugin system uses `.page` files, which are parsed using a custom Markdown engine. Understanding this is key to writing responsive plugins. ### The Parsing Pipeline + 1. **Header Parsing:** The top of the file (before `---`) is parsed as INI for metadata (Title, Menu, etc). 2. **Content Parsing:** The rest is parsed as Markdown, with special handling for translation (`_(text)_`) and definition lists. 3. **PHP Evaluation:** Any PHP code is executed after Markdown is processed. ### Whitespace & Markdown Structure + - **Definition List Syntax:** + ```markdown _(Label)_: : ``` + This is parsed into: + ```html
Label
``` + - **Whitespace is Critical:** - The colon (`:`) must be at the start of the line, followed by a space. - Indentation or extra spaces can break parsing, causing elements to fall outside the `
` structure. @@ -57,51 +68,83 @@ By default, if you use a `
` (or any block-level HTML tag) in your `.page` f ``` **With `markdown="1"`:** + ```html
_(This WILL be parsed as markdown inside the div)_ :
``` -Example 2 -**With `markdown="1"`:** + +Example 2 **With `markdown="1"`:** + ```html _(This WILL be parsed as markdown)_ :
_(This WILL be parsed as markdown inside the div)_ +
+

This will not be parsed as markdown.

+

+

+
``` This applies to all block-level tags (div, section, article, etc). Use `markdown="1"` if you need markdown parsing inside a custom container. ### Why This Matters + If your markup doesn't follow the expected pattern, the CSS can't do its job. That's when you get broken layouts, giant buttons, or misaligned fields. --- -## Common Bugs in Non-Responsive .page Files (and How to Fix Them) +## Common Bugs in .page Files (and How to Fix Them) ### 1. Large Buttons + **Bug:** Buttons stretch full width, look massive, or break the layout. ![Example: Pool Device Status page with large, stretched Reset button](assets/pool-device-status-bug.png) *Pool Device Status page before fix: The Reset button is stretched and not visually grouped.* **Why:** + - On desktop screens, `
` uses `display: flex; flex-direction: column;` (see the responsive CSS). This means every direct child of `
`—including buttons, inputs, spans, etc.—is stacked vertically and stretched to the available width by default. - If you put a button directly inside `
`, it becomes a flex item and will stretch to fill the column (unless it's inside a `` or similar inline container). -- Old markup: `_(Action)_: -: ` +- Old markup: -**Fix:** -- Wrap buttons in a `` (or `` for groups): ```markdown _(Action)_: - : + : + : ``` + +**Fix:** + +- Wrap buttons in a `` (or `` for groups): + + ```markdown + _(Action)_: + : + +   + : + + + ``` + - For button groups: + - Before: + + ```markdown +   + : + ``` + + - After: + ```markdown   : @@ -110,28 +153,41 @@ If your markup doesn't follow the expected pattern, the CSS can't do its job. Th ``` -### 2. [Settings Label + Inputs Are Offset (Whitespace/Parsing Issue)] +### 2. Settings Label + Inputs Are Offset (Whitespace/Parsing Issue) + **Bug:** Labels and inputs don't line up, or inputs appear on a new line, not next to their label. ![Example: Scrub Status page with offset labels and controls](assets/scrub-status-bug.png) *Scrub Status page before fix: Labels and controls are misaligned due to whitespace/structure issues.* **Why:** + - Extra spaces, tabs, or missing colons in the Markdown definition list syntax. -- Elements placed outside the `label: content` pattern aren't wrapped in `
`, `
`, `
`. +- Elements placed outside the `label: content` pattern aren't wrapped in `
`, `
`, `
`. Or potentially two `
` elements adjacent to each other. **Fix:** -- Make sure every input is inside a definition list: + +- Make sure every input is inside a definition list and with a line break between each label + content pair: + ```markdown - _(Setting Name)_: + _(Setting One)_: + : + + _(Setting Two)_: + : + + _(Setting Three)_: : ``` + - For elements with no label, use ` ` as the label: + ```markdown   : ... ``` -- Remove rogue elements outside the definition structure. + +- Inspect the page source and clean up whitespace in an attempt to remove rogue elements outside the definition structure. --- @@ -140,14 +196,18 @@ If your markup doesn't follow the expected pattern, the CSS can't do its job. Th When you have tables with **a lot of columns** (wide tables) in your plugin, you should wrap them in a special container to ensure they remain usable on all screen sizes. The `TableContainer` class sets a **minimum width** on the table, so it doesn't shrink too small on mobile or narrow windows. This allows users to scroll horizontally to view the entire table, especially when there are many columns. ### How to Use + - For tables with many columns (wide tables), wrap them in a `
`. - For simple/narrow tables, this wrapper is usually not needed. +- **Test extensively at various screen sizes** and make your decision based on your own content display needs. ### Why? + - Without this wrapper, wide tables may become too small to read or interact with at smaller screen sizes. - The TableContainer class sets a `min-width` on the table and enables horizontal scrolling, so users can always access all columns, even on mobile. ### Example: Before + ```html @@ -160,6 +220,7 @@ When you have tables with **a lot of columns** (wide tables) in your plugin, you ``` ### Example: After + ```html
@@ -177,32 +238,8 @@ When you have tables with **a lot of columns** (wide tables) in your plugin, you --- -## Real-World Example: DeviceInfo.page - -**Before:** -```markdown - - -``` -- Buttons are outside the definition list, so they break the layout and look wrong on mobile. - -**After:** -```markdown -  -: - - - -``` -- Now the buttons are inside the `
`, `
`, `
` structure, and the CSS can lay them out responsively. - -**Screenshot Reference:** -- See attached images for examples of large buttons and offset fields before/after fixing the markup. - ---- - ## Summary -- Always use the definition list pattern for settings and controls. + - Wrap button groups in ``. - Watch your whitespace and colons—Markdown parsing is strict. - Test on mobile and desktop to catch layout issues early. @@ -211,9 +248,14 @@ When you have tables with **a lot of columns** (wide tables) in your plugin, you ## Quick Fix: Opting Out of Responsive Layout (If You're Short on Time) -If you can't dedicate time right now to fully update your plugin for the new responsive system, you can temporarily opt out of the responsive CSS for your page. This will preserve the legacy layout and prevent your page from breaking, but **it is not a long-term solution**. +**⚠️ WARNING: This is a temporary stopgap solution. You should plan to migrate to the responsive system for the best user experience and future compatibility.** + +If you can't dedicate time right now to update your plugin for the new responsive system, you can temporarily opt out of the responsive CSS for your page. This will preserve the legacy layout and prevent your page from breaking, but **it is not a long-term solution** and you should plan to migrate to the responsive system for the best user experience and future compatibility. + +There are two options + +### Option 1: Custom pages that don't utilize markdown parsing -### How to Opt Out Add the following to the top (YAML header) of your `.page` file: ```yaml @@ -221,6 +263,7 @@ ResponsiveLayout="false" ``` **Example:** + ```yaml Title="Add VM" Tag="clipboard" @@ -232,7 +275,84 @@ ResponsiveLayout="false" See `AddVM.page` and `UpdateVM.page` for real-world examples of this approach. -### What This Does -- Wraps your page content in a `
` that forces a **minimum width of 1200px** via CSS. This keeps your layout looking like the old (non-responsive) UI, even on smaller screens. -- Your page will not adapt to mobile or small window sizes—it will always be at least 1200px wide, and users may need to scroll horizontally on small devices. +Instead of using the `dl > dt + dd` structure, these pages use a different layout system that doesn't utilize markdown parsing. + +#### What This Does + +- Wraps your page content in a `
` that forces a **minimum width of 1200px** via CSS. This keeps your layout looking like the old (non-responsive) UI, even on smaller screens. +- Your page content will not adapt to mobile or small window sizes—it will always be at least 1200px wide, and users may need to scroll horizontally on small devices. - **This is a stopgap.** You should still plan to migrate to the responsive system for the best user experience and future compatibility. + +### Option 2: Wrap your custom elements in a `
` to force a min width of 1200px + +Let's say you have a `*.page` for your plugin. It has some settings that follow the standard `label: content` pattern that are get parsed into a `
`, `
`, `
` structure. + +But also on this page you have custom element(s) that are not parsed by the markdown parser and wrapped in the `dl > dt + dd` structure. Instead you maybe have a `
` that contains your plugin specific content. And instead that plugin specific content you have a complex layout. + +Before example: + +```html +_(Setting One)_: +: + +
+
+

Plugin Element

+
+
+

This is a plugin element

+
+
+ +_(Setting Two)_: +: + +
+
+

Plugin Element

+
+
+

This is a plugin element

+
+
+``` + +After example: + +```html +_(Setting One)_: +: + + +
+
+ ... +
+
+ + +
+ ... +
+ +_(Setting Two)_: +: + + +
+
+ ... +
+
+ + +
+ ... +
+``` + +The route you choose will depend on your specific use case. Explore the available options. + +If these specific examples don't apply to your plugin, you can still opt out of the responsive layout by adding `ResponsiveLayout="false"` to the top (YAML header) of your `.page` file. Or come up with your own solution for your specific use case. + +However, we highly recommend you migrate to the responsive system for the best user experience and future compatibility.