Skip to main content
Version: 2026.3

Link Editable

General​

The link editable is used for dynamic link creation in documents.

Configuration​

You can pass every valid attribute an <a>-tag can have (w3.org - Link), such as: class, target, id, style, accesskey, name, title, data-*, aria-* and additionally the following:

NameTypeDescription
reloadbooleanSet to true to reload the page in editmode after changing the state.
textPrefixstringAdd an icon or something else before Text.
textSuffixstringAdd an icon or something else after Text.
noTextbooleanIf you need only the <a> tag without text (or only with an textSuffix/textPrefix).
requiredboolean/string(default: false) set to true to make link and text required for publish, set to linkonly to make only the link required for publish.
allowedTypesarrayYou can limit the available types for this editable by passing the allowed types explicitly. If this option is not used, all types are available. Valid types are: asset, document, object
allowedSubtypesarrayYou can limit the available subtypes for this editable by passing the allowed subtypes (grouped by type) explicitly. If this option is not used, all subtypes are available.
allowedClassesarrayYou can limit the available classes for this editable by passing the allowed object class names explicitly. If this option is not used, all classes are available.
allowedTargetsarrayYou can limit the available targets for this editable by passing the allowed targets explicitly. If this option is not used, all targets are available. Valid targets are: (empty string), _blank, _self, _top, _parent
disabledFieldsarrayYou can limit the available fields for this editable by passing the allowed fields explicitly. If this option is not used, all fields are available. Valid Fields are: text, target, parameters, anchor, title, accesskey, rel, tabindex, class, attributes

Security policy (URL schemes and attribute keys)​

By default, the Link editable renders whatever the document editor enters: any URL scheme (including javascript:/vbscript:/data:) and any custom attribute key (including event handlers like onclick). This preserves this editable's historical behavior, but means a document editor (document-edit permission, not necessarily an administrator) can use it to store a persistent (stored) XSS payload that runs for every visitor who views or clicks the rendered link (GHSA-9g27-c28m-8xg5).

To close this, enable it via config:

# config/packages/pimcore.yaml
pimcore:
documents:
editables:
link_sanitizer:
strict: true

PimcoreCoreBundle::boot() reads this and installs the strict policy for you. If you need a fully custom policy instead of the boolean toggle, call AttributeSanitizer::setInstance(...) directly from your own bundle's boot() method - application bundles register at Symfony's default priority and boot before PimcoreCoreBundle (registered at a lower priority), so an explicit call there always takes precedence over the config-driven default, regardless of the config value:

use Pimcore\Model\Document\Editable\Link\AttributeSanitizer;
use Symfony\Component\HttpKernel\Bundle\Bundle;

class YourBundle extends Bundle
{
public function boot(): void
{
AttributeSanitizer::setInstance(AttributeSanitizer::strict());
}
}

The strict policy rejects javascript:/vbscript: paths and most data: URIs (data:image/* other than data:image/svg+xml is still allowed, e.g. for a downloadable data-uri image), and rejects editor-supplied attribute keys that look like an event handler (on*) or aren't shaped like a conventional HTML attribute name. It also stops emitting the editable's own bookkeeping data (path, linktype, text, parameters, anchor, internal*) as attributes on the <a> tag, which the permissive default still does for backward compatibility (e.g. linktype="direct"). A target/title/class/data-*/aria-*/... attribute, or an event handler passed only via the template call (e.g. pimcore_link("x", {"onclick": "track()"})), is unaffected either way.

The permissive default is deprecated since 2026.3 and will be removed in 2027.1, where the strict policy becomes the default. While running with the permissive default, a deprecation is triggered whenever a Link renders a URL or attribute the strict policy would reject. Enabling it today is recommended for any site where document editors are not fully trusted.

Methods​

NameReturnDescription
getHref()stringGet the path of this link. The path is not HTML-escaped (print it in an escaping context, e.g. Twig auto-escaping); query parameters and anchor are.
getText()stringGet the text of the link
getTarget()stringGet the target of the link
getParameters()stringGet the query params of the link
getAnchor()stringGet the anchor text of the link
getTitle()stringGet the title of the link
getRel()stringGet the rel text of the link
getTabindex()stringGet the tabindex of the link
getClass()stringGet the class of the link
getAccessKey()stringGet the access key of the link
isEmpty()stringWhether the editable is empty or not

Examples​

Basic Usage​

<p>
{{ "Visit our" | trans }}
{{ pimcore_link("blogLink") }}
</p>

You could see the edit mode preview in the picture, below.

Link editable - edit mode previewLink editable - edit mode previewLink editable - edit mode preview

And the frontend:

Link editable - frontendLink editable - frontendLink editable - frontend

Let's see how to make a list of links with Block.

<h3>{{ "Useful links" | trans }}</h3>
<ul>
{% for i in pimcore_block("linkblock").iterator %}
<li>{{ pimcore_link("myLink", {"class": "special-link-class"}) }}</li>
{% endfor %}
</ul>

The above example renders a list of links:

The links list in the backendThe links list in the backendThe links list in the backend

Please also see the section about Link Generators

getHtml() / __toString() of the DataObject Link data type (Pimcore\Model\DataObject\Data\Link) are hardened by an independent policy with its own config (GHSA-h78x-47qg-qjmq); it does not depend on the Document setting above:

# config/packages/pimcore.yaml
pimcore:
objects:
link_sanitizer:
strict: true
# optional, only used while strict is true:
blocked_url_schemes: ['javascript:', 'vbscript:'] # default
block_unsafe_data_urls: true # default

With the permissive default (strict: false) the output is unchanged apart from " in href and in the named attributes (title, class, rel, target, tabindex, accesskey) being escaped as &quot;; a deprecation is triggered whenever the strict policy would have rejected the href or a free-form attribute. With strict: true, javascript:/vbscript: and script-capable data: URLs render an empty href, and the free-form attributes string is parsed and re-serialized (event handlers and malformed tokens are dropped; remaining values are HTML-escaped).

For a fully custom policy, call Pimcore\Model\DataObject\Data\Link\SanitizerPolicy::setInstance(...) from your own bundle's boot() method; it takes precedence over the config value.