PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.9
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.9
1.1.9 1.1.8 1.1.7 1.1.6 1.1.5 1.1.4 1.1.3 1.1.2 1.1.1 1.1.0 1.0.1 1.0.0 0.9.8 0.9.7 0.9.6 0.9.4 0.9.5 0.9.3 0.9.2 0.9.1 0.9.0 0.8.9 0.8.8 0.8.7 0.8.6 All 33 releases
desktop-mode / includes / widgets / widget-starter.php

widget-starter.php in OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin 1.1.9, at includes/widgets/widget-starter.php

188 lines 9.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * =============================================================================
4 * OpenStation — Starter Widget PHP registration
5 * =============================================================================
6 *
7 * WHAT THIS FILE DOES
8 * -------------------
9 * This is the PHP side of a OpenStation widget. It has three jobs:
10 *
11 * 1. Register the JS bundle and CSS with WordPress so they can be loaded.
12 * 2. Enqueue the CSS eagerly on shell pages (prevents flash of unstyled content).
13 * 3. Announce the widget to OpenStation via openstation_register_widget()
14 * so it appears in the widget picker.
15 *
16 * The PHP side does NOT contain any widget logic. All the rendering, data
17 * fetching, and interactivity lives in the JS file (index.ts). PHP just
18 * tells the system "this widget exists, here is its metadata, here is its
19 * script handle."
20 *
21 * HOW TO USE THIS AS A TEMPLATE
22 * ------------------------------
23 * 1. Copy this file to includes/widgets/widget-my.php
24 * 2. Replace every "starter" in function names with your widget name
25 * e.g. openstation_register_starter_* → openstation_register_my_*
26 * 3. Replace "widget-starter" in asset filenames with "widget-my"
27 * 4. Replace 'desktop-mode/starter' with your widget id — must match
28 * the WIDGET_ID constant in your JS file exactly
29 * 5. Update label, description, icon, and size constraints
30 * 6. Add a require_once line for this file in desktop-mode.php
31 *
32 * Requires: OpenStation 0.18.0+ (openstation_register_widget).
33 *
34 * @package OpenStation
35 */
36
37 defined( 'ABSPATH' ) || exit;
38
39 /**
40 * Register the JS bundle and CSS stylesheet handles.
41 *
42 * WHY wp_register_script AND NOT wp_enqueue_script?
43 * The shell's server-sync loads widget scripts lazily — only when the
44 * picker opens or a widget that needs this script is about to mount.
45 * wp_register_script() makes the handle known to WordPress without
46 * actually outputting a <script> tag. The shell requests the script
47 * via its own enqueue path at the right moment. Using wp_enqueue_script()
48 * here would output the tag unconditionally on every admin page, wasting
49 * bandwidth for users who never open the widget picker.
50 *
51 * WHY IS THE CSS REGISTERED HERE BUT ENQUEUED SEPARATELY?
52 * Styles do not have a lazy-load mechanism equivalent to scripts. If we
53 * registered the CSS but never enqueued it, the widget would flash as
54 * unstyled on first mount while the stylesheet is fetched. So we register
55 * both the JS and the CSS here, then eagerly enqueue just the CSS in a
56 * separate function below that only runs on shell pages.
57 *
58 * SCRIPT_DEBUG CONVENTION
59 * When SCRIPT_DEBUG is true WordPress loads the unminified development
60 * build (widget-starter.js). In production it loads the minified build
61 * (widget-starter.min.js). Both are produced by `npm run build:widget-starter`.
62 *
63 * VERSION STRINGS
64 * Using filemtime() as the version means the browser cache is busted
65 * automatically whenever the file changes on disk — no manual version bumping.
66 * Falls back to OPENSTATION_VERSION if the file does not exist yet (e.g.
67 * during development before the first build).
68 */
69 function openstation_register_starter_widget_assets() {
70 $suffix = openstation_asset_suffix();
71 $version = defined( 'OPENSTATION_VERSION' ) ? OPENSTATION_VERSION : '0';
72
73 $js_path = OPENSTATION_DIR . 'assets/js/widget-starter' . $suffix . '.js';
74 $css_path = OPENSTATION_DIR . 'assets/js/widget-starter' . $suffix . '.css';
75
76 wp_register_style(
77 'os-starter-widget', // Handle name — referenced in wp_enqueue_style() below.
78 OPENSTATION_URL . 'assets/js/widget-starter' . $suffix . '.css',
79 array(), // No CSS dependencies.
80 file_exists( $css_path ) ? (string) filemtime( $css_path ) : $version
81 );
82
83 wp_register_script(
84 'os-starter-widget', // Handle name — passed as 'script' to openstation_register_widget().
85 OPENSTATION_URL . 'assets/js/widget-starter' . $suffix . '.js',
86 array( 'wp-api-fetch' ), // List WordPress script handles your widget depends on.
87 // Declare every WordPress package you use, and do not assume any
88 // of them are already on the page. They used to be: Core's ⌘K
89 // palette pulled the whole Gutenberg runtime onto every admin
90 // screen, so `wp.apiFetch`, `wp.element` and friends happened to
91 // be globals by the time any widget mounted. Deferring that
92 // runtime to the first ⌘K took the accident away — on a fresh
93 // boot they are undefined until the palette is opened, and a
94 // widget that reached for one at mount threw. A declared
95 // dependency is resolved by WordPress when the script is
96 // enqueued, which is why this line is the fix and not a
97 // workaround. See docs/migration-wp-package-globals.md.
98 file_exists( $js_path ) ? (string) filemtime( $js_path ) : $version,
99 true // Load in the footer — always true for widget scripts.
100 );
101 }
102 add_action( 'init', 'openstation_register_starter_widget_assets', 5 );
103 // Priority 5 — must run before openstation_register_starter_widget() at priority 6
104 // so the script handle exists when register_widget() looks it up.
105
106 /**
107 * Eagerly enqueue the CSS on OpenStation shell pages.
108 *
109 * The JS loads lazily (server-sync handles it). The CSS must load early
110 * so it is in the DOM before the widget's first render — otherwise there
111 * is a visible flash of unstyled content while the browser fetches the
112 * stylesheet after mount.
113 *
114 * The two guards below prevent the stylesheet loading on pages where
115 * OpenStation is not active:
116 * openstation_is_enabled() — user has OpenStation turned on
117 * openstation_is_chromeless_request() — not an iframe content request
118 */
119 function openstation_enqueue_starter_widget_styles() {
120 if ( function_exists( 'openstation_is_enabled' ) && ! openstation_is_enabled() ) {
121 return;
122 }
123 if ( function_exists( 'openstation_is_chromeless_request' ) && openstation_is_chromeless_request() ) {
124 return;
125 }
126 wp_enqueue_style( 'os-starter-widget' );
127 }
128 add_action( 'admin_enqueue_scripts', 'openstation_enqueue_starter_widget_styles', 20 );
129
130 /**
131 * Announce the widget to OpenStation.
132 *
133 * This call stores the widget's metadata in OpenStation's registry so
134 * it appears in the widget picker. The shell reads this registry at boot
135 * and on every session refresh — adding or removing a widget definition
136 * takes effect without a browser reload.
137 *
138 * AVAILABLE ARGUMENTS
139 * -------------------
140 * label string Human-readable name shown in the picker. Required.
141 * description string One-line subtitle shown beneath the label.
142 * icon string Any dashicons class, e.g. 'dashicons-chart-bar'.
143 * Full list: https://developer.wordpress.org/resource/dashicons/
144 * script string The wp_register_script() handle from above.
145 * movable bool true = user can drag the widget off the right column
146 * and float it anywhere on the desktop.
147 * false = widget stays in the column (default).
148 * resizable bool true = user can resize the widget card.
149 * Requires movable: true for all 8 handles.
150 * Column-docked widgets only get a bottom handle.
151 * min_width int Smallest width the user can drag the card to (px).
152 * min_height int Smallest height the user can drag the card to (px).
153 * max_width int Optional ceiling on user-driven width resize (px).
154 * max_height int Optional ceiling on user-driven height resize (px).
155 * default_width int Starting width when first added as a floating widget.
156 * default_height int Starting height when first added as a floating widget.
157 * capabilities array Optional. ALL listed capabilities must be held by the
158 * current user or the widget will not register for them.
159 * e.g. array( 'edit_posts', 'publish_posts' )
160 */
161 function openstation_register_starter_widget() {
162 if ( ! function_exists( 'openstation_register_widget' ) ) {
163 // OpenStation is not active — bail gracefully.
164 return;
165 }
166
167 openstation_register_widget(
168 // First argument: widget id.
169 // Must exactly match the WIDGET_ID constant in your JS file and the
170 // key used in window.openStationWidgets[ id ] at the bottom of index.ts.
171 'desktop-mode/starter',
172 array(
173 'label' => __( 'Starter Widget', 'desktop-mode' ),
174 'description' => __( 'A skeleton widget — copy this to build your own.', 'desktop-mode' ),
175 'icon' => 'dashicons-welcome-widgets-menus',
176 'script' => 'os-starter-widget',
177 'movable' => true,
178 'resizable' => true,
179 'min_width' => 200,
180 'min_height' => 140,
181 'default_width' => 280,
182 'default_height' => 200,
183 )
184 );
185 }
186 add_action( 'init', 'openstation_register_starter_widget', 6 );
187 // Priority 6 — runs after the asset registration at priority 5.
188