Download the PHP package markup-carve/shopware-carve without Composer
On this page you can find all versions of the php package markup-carve/shopware-carve. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download markup-carve/shopware-carve
More information about markup-carve/shopware-carve
Files in markup-carve/shopware-carve
Package shopware-carve
Short Description Render Carve markup to safe HTML in Shopware: Twig filters, CMS element, product/category fields, live preview, mail, inline product references.
License MIT
Homepage https://github.com/markup-carve/shopware-carve
Informations about the package shopware-carve
shopware-carve
Render Carve markup to safe, semantic HTML in Shopware 6. One source - ten surfaces: Twig filters, CMS elements, product/category/manufacturer fields, admin live preview, transactional mail, inline product references, product reviews, and a CLI renderer.
Safe by default. Raw HTML passthrough is off. javascript:, data:, vbscript:, file: URL
schemes are neutralized. on*, srcdoc, and formaction attributes are stripped. These protections
are always-on baselines independent of any plugin setting. No separate sanitizer needed. The |carve
filter is is_safe => html because carve-php's URL/attribute hardening is unconditional. For the full
threat model, a Carve-vs-Markdown comparison with examples, and the honest limits, see
docs/security.md.
- Composer:
markup-carve/shopware-carve - License: MIT
- Shopware: 6.6 and 6.7
- PHP: ^8.2
- Namespace:
MarkupCarve\Shopware\
Pre-1.0 caveat. Syntax and output format can still change before 1.0. Pin versions explicitly and review the carve-php changelog before upgrades.
Gallery
One plain-text source, rendered safely across the shop. The product description (left) and the admin authoring view with live preview (right) come from the same Carve source:
| Storefront product description | Admin live preview |
|---|---|
Untrusted review text is hardened automatically - bold/italic/links survive, while headings, images,
and raw <script> degrade to inert text:
See GALLERY.md for all surfaces (CMS element, category and manufacturer copy,
transactional mail, inline product references, and the CLI renderer) with the Carve source behind
each screenshot.
Enabled extensions
The following carve-php extensions are registered unconditionally on every HTML converter (both
CarveRenderer and CarveContextRenderer). They are pure-PHP and require no extra JavaScript.
| Extension | What it does |
|---|---|
AdmonitionExtension |
Converts ::: note, ::: tip, ::: warning, ::: danger, ::: info, ::: success divs to <div class="admonition {type}"> with a <p class="admonition-title"> header and an appropriate ARIA role. |
DetailsExtension |
Converts ::: details "Title" to a native <details><summary>Title</summary>...</details> disclosure widget. |
ListTableExtension |
Converts ::: list-table blocks (nested lists) to real <table> markup with <thead>/<tbody>/<th>/<td> and rowspan/colspan support. |
InlineFootnotesExtension |
Allows inline footnote syntax [content]{.fn} to generate numbered footnote references and an end-of-document footnotes section, sharing the numbering sequence with regular footnotes. |
AutolinkExtension |
Detects bare https://, http://, and mailto: URLs in text and turns them into clickable <a> links. |
ExternalLinksExtension |
Adds rel="nofollow noopener" and target="_blank" to all external HTTP/HTTPS links, including those produced by AutolinkExtension. |
TableOfContentsExtension |
Collects headings and makes a <ul class="toc"> available via getTocHtml() (or auto-inserts at position: 'top'/'bottom' when configured). Not auto-inserted by default - use position option or call getTocHtml() manually. |
SpoilerExtension |
Block ::: spoiler "Title" becomes a native <details class="spoiler"><summary>Title</summary>...</details> (collapsed by default - no JS). Inline :spoiler[text] becomes <span class="spoiler">text</span> (CSS blur-until-hover, no JS). |
CodeGroupExtension |
Converts ::: code-group with labeled fenced blocks (e.g. ` twig |
{# HTML output (safe, is_safe => html) #} {{ product.translated.description | carve }}
{# Plain text (e.g. for meta descriptions) #} {{ product.translated.description | carve_text }}
{# Markdown (e.g. for export) #} {{ product.translated.description | carve_md }} twig {# storefront/page/product-detail/description.html.twig - rendered automatically #} {{ product.customFields.carve_body | carve }} twig {# In any storefront template that has the manufacturer in scope #} {% if product.manufacturer.translated.customFields.carve_manufacturer_body %}
{% endif %} twig {# HTML part of a mail template #} {% set body %}
Order {{ order.orderNumber }}
Dear {{ order.orderCustomer.firstName }},
your order is on its way. {% endset %} {{ body | carve }}
{# Plain-text part of the same mail template #} {{ body | carve_text }} twig {{ product.customFields.carve_body | carve_ctx(context) }} twig {# Rendered automatically when renderReviews is on - no manual change needed #} {{ review.content|carve_ugc }} bash
Render to HTML
bin/console carve:render path/to/content.crv --html
Render to plain text
bin/console carve:render path/to/content.crv --plain
Render to Markdown
bin/console carve:render path/to/content.crv --md
Render with ANSI color (terminal output)
(--term, not --ansi: the latter is reserved by Symfony's console to force color globally)
bin/console carve:render path/to/content.crv --term twig {# Any storefront .html.twig with a Carve source in scope #} {{ myEntity.translated.someCarveField|carve }}
{# With :product[SKU] inline references resolved against the current sales channel #} {{ myEntity.translated.someCarveField|carve_ctx(context) }} twig {# HTML part of an email template #} {% set body = order.customFields.carve_message_body ?? '' %} {{ body|carve }}
{# Plain-text part of the same email template #} {{ body|carve_text }} twig {# In a custom document Twig override #} {% set manufacturerCopy = order.lineItems.first.product.manufacturer.translated.customFields.carve_manufacturer_body ?? '' %} {% if manufacturerCopy %} {{ manufacturerCopy|carve }} {% endif %} bash composer require markup-carve/shopware-carve bash cd custom/plugins/ShopwareCarve/src/Resources/app/administration npm ci bash
Activate the plugin
bin/console plugin:install --activate ShopwareCarve
Run migrations (adds carve_body to products, carve_category_body to categories)
bin/console database:migrate --all ShopwareCarve
Build the admin (required for CMS element and live preview)
bin/console bundle:dump bin/build-administration.sh bin/console assets:install
Compile storefront theme (picks up carve-content styles)
bin/console theme:compile
Clear cache
bin/console cache:clear
mermaid blocks as diagrams. CDN must be in CSP. | |ShopwareCarve.config.enableCharts|false| Lazy-load Chart.js from CDN and render plantuml (and =html blocks and inline ``...{=html} `` spans) is passed through to the output or escaped. Default:false` (raw HTML is escaped).
Note that the following protections are always on regardless of this setting - they are a
baseline provided by carve-php and are not governed by allowRawHtml:
javascript:,data:,vbscript:, andfile:URL schemes are neutralized.on*event attributes,srcdoc, andformactionare stripped.
Enable allowRawHtml only if every content author is fully trusted. Enabling it while the
|carve filter is registered as is_safe => html creates a stored XSS vector - any author can
inject arbitrary HTML (including <script> tags) into the storefront.
livePreview
When true (the default), the CMS element config panel renders an instant storefront-identical
preview powered by carve-js. Set to false to disable the preview (e.g. for performance or
when carve-js is not installed).
Symbol shortcodes
ShopwareCarve.config.symbols maps shortcodes such as :rocket: to replacements. Enter one
name=value mapping per line, for example:
Whitespace around the name and value is trimmed. Blank lines and lines without = are ignored.
Names use carve-php's shortcode grammar: they must start with an ASCII letter or _, followed by
ASCII letters, digits, _, or -. Invalid names are ignored, and unmapped shortcodes remain
literal.
Security warning: symbol values are trusted raw HTML. carve-php inserts them verbatim and
unescaped, even through |carve_ugc / toHtmlUgc(); safe mode does not sanitize these configured
values. Only administrators who understand that the values become executable storefront markup
should edit this setting. Never populate it from user-authored content.
smartQuotes
When true, carve-php's smart-quotes extension is applied to HTML output, converting straight
ASCII quotes ("..." and '...') to locale-correct typographic equivalents. Only affects HTML
output (|carve, |carve_ctx) - plain-text and Markdown targets are not affected.
Default: false.
smartQuotesLocale
Sets the locale used to choose typographic quote characters. Only takes effect when smartQuotes
is true.
Default: en (English curly quotes: "..." / '...').
Supported locales:
| Locale | Description |
|---|---|
en |
English |
de |
German (de) |
de-CH |
German (Switzerland) |
fr |
French |
es |
Spanish |
it |
Italian |
pt |
Portuguese |
nl |
Dutch |
pl |
Polish |
ru |
Russian |
uk |
Ukrainian |
cs |
Czech |
hu |
Hungarian |
sv |
Swedish |
da |
Danish |
fi |
Finnish |
nb |
Norwegian Bokmal |
nn |
Norwegian Nynorsk |
ja |
Japanese |
zh |
Chinese |
Note: future versions may auto-derive the locale from the Shopware sales channel language.
enableMermaid
When true, chart fenced code blocks (containing a Chart.js config as JSON) are rendered
as charts. The Chart.js library is lazy-loaded from jsDelivr CDN (https://cdn.jsdelivr.net/npm/chart.js@4/+esm)
only when at least one <div class="chart"> element is present on the page.
Default: false.
enablePlantuml
When true, puml) fenced code blocks are rendered as diagrams.
carve-php emits <pre class="plantuml">SOURCE</pre>; PlantUML has no in-browser renderer, so the
storefront JS sends each block's source to the external Kroki service
(https://kroki.io/plantuml/svg, HTTP POST as text/plain) only when at least one
<pre class="plantuml"> element is present on the page. The returned SVG replaces the <pre>
with an inline <img src="data:image/svg+xml;base64,...">. No client library is loaded (Kroki
needs none). On a network/service error the original code block stays visible.
[!IMPORTANT] The diagram source is transmitted to the public
kroki.ioservice. If your content is confidential, self-host Kroki and changeKROKI_PLANTUML_URLinsrc/Resources/app/storefront/src/carve-diagrams.jsto your instance.
Default: false.
profile (Content profile)
Restricts which Carve node types are rendered in HTML output. Use comment or minimal for
untrusted user content such as product reviews, Q&A answers, or any other UGC surface. Disallowed
elements degrade to plain text by default (carve-php's ACTION_TO_TEXT). Applies to HTML output
only (|carve, |carve_ctx) - text and Markdown converters are never profiled.
Default: none (no restriction).
| Value | Name | What it restricts |
|---|---|---|
none |
None | No restrictions. All Carve elements render normally. |
article |
Article | Denies raw HTML blocks and inline raw HTML only. All other formatting (headings, images, tables, footnotes, etc.) is allowed. Suitable for blog posts and articles from trusted authors who must not embed scripts. |
comment |
Comment (UGC) | Allows only basic inline formatting (bold, italic, strikethrough, code, links, insert/delete/highlight/superscript/subscript) and block-level paragraphs, lists, blockquotes, and code blocks. Denies headings, images, tables, footnotes, raw HTML, divs, sections, definition lists, thematic breaks, and math. Links get rel="nofollow ugc". Max nesting depth: 4. |
minimal |
Minimal (inline only) | Allows basic inline formatting (bold, italic, strikethrough, code, insert/delete/superscript/subscript, soft/hard breaks) and block-level paragraphs and lists only. Denies links, images, headings, tables, blockquotes, footnotes, raw HTML, and all advanced elements. Max nesting depth: 2. Suitable for chat messages and micro-posts. |
full |
Full | Explicitly marks all features as allowed. Functionally equivalent to none but records intent. Use for trusted admin content. |
Custom profile (PHP escape hatch)
There is no UI for a fully custom profile. To apply bespoke restrictions, build a Profile
directly in PHP and set it on the converter before rendering. The simplest approach is to decorate
or replace CarveRenderer in your own plugin:
For the full list of node type constants, see
Carve\NodeType in the
carve-php library and the node-type vocabulary in docs/profiles.md in the Carve spec.
CDN, Kroki and CSP
When either enableMermaid or enableCharts is turned on, the storefront loads the
corresponding library from https://cdn.jsdelivr.net. If your shop enforces a Content Security
Policy, add https://cdn.jsdelivr.net to both script-src and connect-src.
When enablePlantuml is turned on, the storefront instead POSTs the diagram source to the
external Kroki service at https://kroki.io and inlines the returned SVG as an <img> data URI
(no library is loaded). For a CSP, add:
https://kroki.iotoconnect-src(thefetchPOST), anddata:toimg-src(the inlined SVG data URI).
If you self-host Kroki, substitute your own origin for https://kroki.io in both the CSP and
KROKI_PLANTUML_URL in carve-diagrams.js.
Security note
The |carve and |carve_ctx filters are marked is_safe => html - meaning Twig will not
double-escape their output. This is safe because carve-php provides always-on hardening that
cannot be disabled by any plugin setting:
javascript:,data:,vbscript:, andfile:URL schemes are neutralized.on*event attributes,srcdoc, andformactionare stripped.- Parse depth and input size are bounded against DoS.
The only thing the ShopwareCarve.config.allowRawHtml setting controls is whether authored raw
HTML (fenced ```=html blocks and inline `...`{=html} spans) is passed through or
escaped. By default (allowRawHtml = false) raw HTML is escaped and cannot reach the output.
Enable allowRawHtml only if all content authors are fully trusted. Enabling it while
is_safe => html is in the Twig filter registration creates a stored XSS vector - authors can
inject arbitrary HTML including <script> tags into the storefront.
Shopware version support
| Shopware | Supported |
|---|---|
| 6.6.x | Yes |
| 6.7.x | Yes |
| < 6.6 | No |
Each supported line has its own CI leg that installs that line by name and reads the installed version back, so a row here is a measured claim rather than a declared one. A red leg therefore means support for that line is currently unverified - including when the cause is upstream, such as Composer refusing a release over a security advisory.
The 6.6 legs run in ci.yml, the badge at the top of this
file. The 6.7 legs run in
shopware-67.yml on every pull request, and are
expected to be red today: no Shopware 6.7 release currently installs, because
Composer refuses the whole line over open advisories on shopware/core and on the
dompdf/dompdf and mcp/sdk it reaches. The badge therefore tracks the line a merchant
can install; the workflow tracks the line this plugin declares.
All versions of shopware-carve with dependencies
shopware/core Version ~6.6.0 || ~6.7.0
markup-carve/carve-php Version ^0.1.5