{"id":249575,"date":"2026-01-09T08:59:30","date_gmt":"2026-01-09T08:59:30","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/blockglow-per-block-custom-css\/"},"modified":"2026-01-11T07:50:00","modified_gmt":"2026-01-11T07:50:00","slug":"blockglow","status":"publish","type":"plugin","link":"https:\/\/oci.wordpress.org\/plugins\/blockglow\/","author":23123447,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_crdt_document":"","version":"1.1.7","stable_tag":"1.1.7","tested":"6.9.4","requires":"5.8","requires_php":"8.2","requires_plugins":null,"header_name":"BlockGlow \u2014 Per-block Custom CSS","header_author":"Mary Rose Elbambo","header_description":"Extend every block with a \"Custom CSS\" inspector field. CSS is scoped to the block instance and printed on the front-end.","assets_banners_color":"3f4e65","last_updated":"2026-01-11 07:50:00","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/wordpress.org\/plugins\/blockglow\/","header_author_uri":"https:\/\/profiles.wordpress.org\/eltresse93\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":168,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.1.6":{"tag":"1.1.6","author":"eltresse93","date":"2026-01-09 11:11:35"},"1.1.7":{"tag":"1.1.7","author":"eltresse93","date":"2026-01-11 07:50:00"}},"upgrade_notice":{"1.0.0":"<p>First release.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3435790,"resolution":"128x128","location":"assets","locale":""},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3435790,"resolution":"256x256","location":"assets","locale":""}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3435790,"resolution":"1544x500","location":"assets","locale":""},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3435790,"resolution":"772x250","location":"assets","locale":""}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.1.6","1.1.7"],"block_files":[],"assets_screenshots":[],"screenshots":{"1":"Inspector panel showing the CodeEditor or fallback textarea.","2":"Live editor preview demonstrating scoped styles.","3":"Example front-end output with linked per-block stylesheet.","4":"BlockGlow CSS manager page with pagination and multiple file selection (admin view)."},"jetpack_post_was_ever_published":false},"plugin_section":[],"plugin_tags":[4121,356,2001,1332,148076],"plugin_category":[46,59],"plugin_contributors":[253640],"plugin_business_model":[],"class_list":["post-249575","plugin","type-plugin","status-publish","hentry","plugin_tags-blocks","plugin_tags-css","plugin_tags-custom-css","plugin_tags-editor","plugin_tags-gutenberg","plugin_category-editor-and-writing","plugin_category-utilities-and-tools","plugin_contributors-eltresse93","plugin_committers-eltresse93"],"banners":{"banner":"https:\/\/ps.w.org\/blockglow\/assets\/banner-772x250.png?rev=3435790","banner_2x":"https:\/\/ps.w.org\/blockglow\/assets\/banner-1544x500.png?rev=3435790","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/blockglow\/assets\/icon-128x128.png?rev=3435790","icon_2x":"https:\/\/ps.w.org\/blockglow\/assets\/icon-256x256.png?rev=3435790","generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>BlockGlow adds a \"BlockGlow \u2014 Custom CSS\" panel to the inspector of every block. Use it to scope custom CSS to a single block instance. The plugin stores CSS in the uploads folder (under uploads\/blockglow\/) and enqueues the generated CSS file when rendering on the front end. If the uploads directory isn't writable or file write fails, BlockGlow will fall back to outputting inline styles.<\/p>\n\n<p>Key features:<\/p>\n\n<ul>\n<li>Adds two block attributes to every block: <code>blockglowCustomCSS<\/code> and <code>blockglowId<\/code>.<\/li>\n<li>Inspector panel with a CodeMirror-backed code editor (if WordPress provides it) or a fallback textarea supporting Tab and Shift+Tab outdent.<\/li>\n<li>Live preview inside the block editor: custom CSS is scoped to the block in the editor so you can see the effect while editing.<\/li>\n<li>CSS files are saved to <code>wp-content\/uploads\/blockglow\/blockglow-&lt;id&gt;.css<\/code> and enqueued on the front end as a linked stylesheet; files are removed automatically when you clear the Custom CSS field.<\/li>\n<li>Graceful fallback to inline styles when file writing isn't possible.<\/li>\n<\/ul>\n\n<p>How scoping works:<\/p>\n\n<p>BlockGlow creates a unique <code>blockglowId<\/code> for each block instance and scopes your CSS with a wrapper selector like:<\/p>\n\n<pre><code>[data-blockglow-id=\"bg-xxxxxxx\"] { \/* your declarations *\/ }\n<\/code><\/pre>\n\n<p>For convenience you can use <code>&amp;<\/code> as the wrapper shorthand in the editor. Example:<\/p>\n\n<pre><code>&amp; .my-class { color: red; }\n<\/code><\/pre>\n\n<p>The plugin will replace <code>&amp;<\/code> with the wrapper selector for both editor preview and front-end output.<\/p>\n\n<h3>Support<\/h3>\n\n<p>If you find issues or want improvements (for example: limiting who can edit per-block CSS, collecting styles into a single head include, or adding an admin UI to manage generated CSS files), open an issue in the repository or reply here and I will assist.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Install BlockGlow via the WordPress Plugin Directory or upload the <code>blockglow<\/code> folder to the <code>\/wp-content\/plugins\/<\/code> directory.<\/li>\n<li>Activate the plugin through the 'Plugins' menu in WordPress.<\/li>\n<li>Make sure the <code>wp-content\/uploads\/<\/code> directory is writable so BlockGlow can create <code>wp-content\/uploads\/blockglow\/<\/code> and store generated CSS files.<\/li>\n<li>If the uploads directory is not writable, BlockGlow will automatically fall back to using inline styles instead of linked CSS files.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id='where%20are%20the%20css%20files%20stored%3F'><h3>Where are the CSS files stored?<\/h3><\/dt>\n<dd><p>Files are stored in <code>wp-content\/uploads\/blockglow\/<\/code> and are named like <code>blockglow-&lt;id&gt;.css<\/code>.<\/p><\/dd>\n<dt id='will%20the%20css%20affect%20other%20blocks%20or%20pages%3F'><h3>Will the CSS affect other blocks or pages?<\/h3><\/dt>\n<dd><p>No \u2014 BlockGlow scopes the CSS to the block instance using a data attribute. If you write global selectors inside the editor (for example <code>body { ... }<\/code>), those will still be global \u2014 be careful.<\/p><\/dd>\n<dt id='how%20do%20i%20delete%20generated%20css%20files%3F'><h3>How do I delete generated CSS files?<\/h3><\/dt>\n<dd><p>If you clear the Custom CSS field in the block inspector and update the post\/page, the plugin will attempt to delete the corresponding CSS file automatically.<\/p><\/dd>\n<dt id='is%20there%20any%20capability%20check%3F'><h3>Is there any capability check?<\/h3><\/dt>\n<dd><p>At present BlockGlow does not add extra capability checks beyond the normal block editing capabilities. If you need a role-based restriction, consider adding custom checks or ask for an enhancement.<\/p><\/dd>\n<dt id='is%20this%20safe%20for%20production%3F'><h3>Is this safe for production?<\/h3><\/dt>\n<dd><p>BlockGlow only writes CSS files and outputs styles. It's recommended to review custom CSS and limit who can edit posts\/pages. This plugin does not sanitize arbitrary CSS; it persists whatever CSS you enter. Restrict editor access as needed.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.1.7 (2026-01-11)<\/h4>\n\n<ul>\n<li>Fixed: Fixed the redirect URL after deleting a CSS file in WP Admin Blockglow page.<\/li>\n<\/ul>\n\n<h4>1.1.6<\/h4>\n\n<ul>\n<li>Update: Create new blockglowId when a block is duplicated or copied.<\/li>\n<li>Update: Added pagination and multiple select to delete CSS files in Block Glow page in backend.  <\/li>\n<\/ul>\n\n<h4>1.1.5<\/h4>\n\n<ul>\n<li>Admin: Fixed the nonce issue.<\/li>\n<\/ul>\n\n<h4>1.1.4<\/h4>\n\n<ul>\n<li>Admin: Removed the CSS filename when creating the delete nonce.<\/li>\n<\/ul>\n\n<h4>1.1.3<\/h4>\n\n<ul>\n<li>Fixed: Reordered logic in <code>BlockGlow_Admin::handle_delete_file()<\/code> so nonce validation runs before processing user input.<\/li>\n<li>Fixed: Addressed security scanner warning for missing nonce checks on <code>$_POST['file']<\/code> and <code>$_GET['file']<\/code>.<\/li>\n<li>Improved: Raw file input is now only read after successful nonce verification and capability checks.<\/li>\n<\/ul>\n\n<h4>1.1.2<\/h4>\n\n<ul>\n<li>Security: Added stricter nonce validation and capability checks for file deletion handlers; accept both generic and per-file nonces for compatibility.<\/li>\n<li>Security: Improved inline CSS handling for untrusted users \u2014 HTML tags are stripped before inlining to reduce the risk of injecting HTML into a style context.<\/li>\n<li>Admin: Removed PHPCS suppression and standardized sanitization of request inputs; cleaned up admin enqueue logic to prefer built assets when available.<\/li>\n<\/ul>\n\n<h4>1.1.1<\/h4>\n\n<ul>\n<li>Security: Tightened admin navigation and delete handlers \u2014 added nonce verification and input validation for admin page\/tab navigation and file deletion.<\/li>\n<li>Admin: Removed Import\/Export submenu and tab from the admin UI in this build to simplify the UI surface.<\/li>\n<li>Code Quality: Fixed PHPCS i18n warnings and added translator context where needed.<\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>Minor: Improved editor reliability and added an option to toggle in-editor rendering of custom CSS. This release is backwards-compatible; no data migration is required.<\/li>\n<\/ul>\n\n<h4>1.0.5<\/h4>\n\n<ul>\n<li>Editor: improved attribute attachment in the block editor so <code>data-blockglow-id<\/code> is applied to the actual editor block element when possible (closest-node, clientId selector and MutationObserver fallback).<\/li>\n<li>Editor: added a clientId-based selector fallback so editor-scoped CSS applies even when a DOM attribute cannot be attached.<\/li>\n<li>Editor: added a ToggleControl to optionally enable\/disable rendering custom CSS inside the editor preview (default: off).<\/li>\n<li>Editor: displays the \"Generated CSS file\" path under the CodeEditor\/textarea in the inspector so you can quickly open or verify the created CSS file.<\/li>\n<\/ul>\n\n<h4>1.0.4<\/h4>\n\n<ul>\n<li>Security: Sanitized input handling for $_POST['file'] and $_GET['file'] using sanitize_file_name() and wp_unslash().<\/li>\n<li>Security: Added nonce sanitization and validation for $_POST['_wpnonce'] and $_GET['_wpnonce'] using sanitize_text_field() and wp_verify_nonce().<\/li>\n<li>Code Quality: Resolved PHPCS warnings related to WordPress.Security.ValidatedSanitizedInput.InputNotSanitized.<\/li>\n<\/ul>\n\n<h4>1.0.3<\/h4>\n\n<ul>\n<li>Security: replace use of <code>$_REQUEST<\/code> with explicit <code>$_POST<\/code>\/<code>$_GET<\/code> handling and <code>wp_unslash()<\/code> for admin delete actions; improve input normalization and handling.<\/li>\n<\/ul>\n\n<h4>1.0.2<\/h4>\n\n<ul>\n<li>Security: perform nonce verification (<code>check_admin_referer()<\/code>) and capability checks early for admin delete actions; normalize and sanitize request inputs.<\/li>\n<li>Output safety: apply \"escape late\" handling for inline CSS \u2014 raw CSS is allowed only for users with <code>unfiltered_html<\/code>; other users will have CSS escaped at output time to avoid XSS.<\/li>\n<li>Editor: improved dark fallback textarea styling (border-radius:0; background:#000; color:#fff; font-size:13px; padding:10px) and token color rules for editor where available.<\/li>\n<li>Misc: several bugfixes and code hygiene improvements addressing WordPress.org review feedback.<\/li>\n<\/ul>\n\n<h4>1.0.1<\/h4>\n\n<ul>\n<li>Improved front-end output: removed automatic wrapper DIVs and now inject a <code>data-blockglow-id<\/code> attribute into the block's root element so global and theme styles are easier to author.<\/li>\n<li>Switched all inline stylesheet output to use <code>wp_register_style()<\/code> + <code>wp_add_inline_style()<\/code> and <code>wp_enqueue_style()<\/code> instead of echoing <code>&lt;style&gt;<\/code> tags directly.<\/li>\n<li>Added stronger admin-side security: nonce verification for delete actions via <code>check_admin_referer()<\/code> and capability checks for file management.<\/li>\n<li>Misc: improved input sanitization and removed unsafe direct superglobal usage in admin handlers.<\/li>\n<\/ul>","raw_excerpt":"Adds a &quot;Custom CSS&quot; inspector panel to every Gutenberg block and saves per-block CSS files to uploads for front-end enqueuing.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/oci.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/249575","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/oci.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/oci.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/oci.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=249575"}],"author":[{"embeddable":true,"href":"https:\/\/oci.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/eltresse93"}],"wp:attachment":[{"href":"https:\/\/oci.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=249575"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/oci.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=249575"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/oci.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=249575"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/oci.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=249575"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/oci.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=249575"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/oci.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=249575"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}