alengo/sulu-preview-block-focus-bundle
Install the bundle:
composer require alengo/sulu-preview-block-focus-bundle
Register in config/bundles.php:
Alengo\SuluPreviewBlockFocusBundle\PreviewBlockFocusBundle::class => ['all' => true],
Admin-side integration:
assets/admin/package.json:
"sulu-preview-block-focus-bundle": "file:../../vendor/alengo/sulu-preview-block-focus-bundle/assets/admin"
cd assets/admin && npm install
// assets/admin/app.js
import 'sulu-preview-block-focus-bundle';
cd assets/admin && npm run build
Website-side integration (for preview iframe):
webpack.config.js:
.addEntry('suluPreviewBlockFocus', './vendor/alengo/sulu-preview-block-focus-bundle/assets/website/index.js')
{% if sulu_user_loggedin_and_preview(app.request) %}
{{ encore_entry_script_tags('suluPreviewBlockFocus') }}
{% endif %}
Enable block focus in Twig templates:
<div{{ (sulu_user_loggedin_and_preview(app.request) ? ' data-block-id="' ~ content._id ~ '"')|raw }}>
{# Your block content #}
</div>
Scenario: A content editor hovers over a block in the Sulu preview iframe, clicks the focus button, and expects the corresponding block in the admin panel to scroll into view and expand. Steps:
Preview Context Detection:
Use sulu_user_loggedin_and_preview(app.request) to conditionally render data-block-id and load the script only in preview mode. Avoid exposing block IDs in production.
Nested Block Support:
The bundle handles nested blocks by sending parent-to-child IDs in sequence (e.g., parentId|childId). Ensure your Twig templates pass the correct _id for nested structures:
<div data-block-id="{{ (sulu_user_loggedin_and_preview(app.request) ? content._id ~ (content.children|length ? '|' ~ content.children[0]._id : '') : '') }}">
Admin Panel React Integration:
The admin-side script uses React fiber introspection to locate blocks. If your admin panel uses custom React components for blocks, ensure they are properly mounted in the React tree and accessible via ReactDOM.findDOMNode().
Custom Block Types: For custom block types, extend the bundle’s JavaScript logic:
sulu-preview-block-focus-bundle admin script by publishing its assets:
php bin/console assets:install public
SuluPreviewBlockFocusBundle class to add custom block selectors or logic.Performance Considerations:
| Pattern | Implementation |
|---|---|
| Basic Block Focus | Add data-block-id to all blocks in preview mode. |
| Nested Blocks | Chain IDs with ` |
| Custom Styling | Override the focus button CSS via assets/admin/styles/sulu-preview-block-focus.scss. |
| Debugging | Use browser dev tools to check for sulu-preview-block-click messages. |
Block ID Exposure:
data-block-id in production.data-block-id in sulu_user_loggedin_and_preview() checks. Use Twig’s raw filter to avoid XSS risks.React Tree Accessibility:
ReactDOM.findDOMNode() can locate your block components. Use console.log in the bundle’s JS to inspect the React tree.Nested Block ID Format:
|).| (e.g., parent|child). Test with nested structures in preview mode.Admin Script Conflicts:
useEffect or ensure the bundle’s event listeners (sulu-preview-block-click) are not overridden.Webpack Encore Cache:
suluPreviewBlockFocus entry not reflecting after rebuilds.rm -rf var/cache/dev/*
npm run dev
Check Messages:
Console tab) and listen for sulu-preview-block-click messages from the iframe to the admin window.React DevTools:
Network Tab:
suluPreviewBlockFocus) loads only in preview mode. Check for 404 errors if the path is incorrect.CSS Overrides:
// assets/admin/styles/sulu-preview-block-focus.scss
.sulu-preview-block-focus-button {
opacity: 1 !important;
}
Custom Block Selectors:
Extend the admin script to support custom block types by overriding the getBlockElement logic in the bundle’s JS. Example:
// Override in a custom admin script
window.SuluPreviewBlockFocus = {
...window.SuluPreviewBlockFocus,
getBlockElement: (blockId) => {
// Custom logic for your block types
return document.querySelector(`[data-custom-block-id="${blockId}"]`);
}
};
Animation Control:
Disable or customize scroll/expand animations by modifying the admin script’s handleBlockClick method:
window.SuluPreviewBlockFocus.handleBlockClick = (blockId) => {
// Custom animation logic
document.querySelector(`[data-block-id="${blockId}"]`).scrollIntoView({ behavior: 'auto' });
};
Multi-Tab Support: If using multiple admin tabs (e.g., Sulu’s tabbed interfaces), ensure the bundle’s event listeners are scoped to the correct tab context. This may require extending the admin script to target specific tabs.
Server-Side Logic:
For complex block structures, pre-process block IDs server-side (e.g., in a Twig extension) to generate the correct data-block-id format before rendering.
How can I help you explore Laravel packages today?