Last activity on 6 June 2021
  • 1457
composer require codeq/link

Link helper for Neos - with Atomic.Fusion & Monocle in mind


Link helper for Neos - with Atomic.Fusion & Monocle in mind

Release Date
28.06.2021 12:43:32
Requires (dev)
GPL-3.0-or-later c74991c5a9411ba794f4d637813c80a3ec3ea1fd

Latest Stable Version License


The Neos link helper with Atomic.Fusion & Monocle in mind

Here's the most basic usage, which separates your Monocle presentational components from your integration. By providing a transfer object, you can keep your presentational components clean without cluttering your props.

prototype(YOUR.Site:Presentation.Atom.Link) < prototype(Neos.Fusion:Component) {
    @styleguide {
        title = 'My Link'
        props {
            link = CodeQ.Link:Link {
                link = ''
                label = 'CodeQ.Link is awesome'

    link = CodeQ.Link:Link

    renderer = afx`
        <CodeQ.Link:Tag link={} class="link" />

prototype(YOUR.Site:Presentation.Molecule.BlogPostTeaser) < prototype(Neos.Fusion:Component) {
    @styleguide {
        title = 'Blog Post Teaser'
        props {
            link = CodeQ.Link:Link {
                label = 'My first blog post'
                link = ''
            description = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam'

    renderer = afx`
        <CodeQ.Link:Tag link={} class="blog-post-teaser">

prototype(YOUR.Site:Content.BlogPostTeaser) < prototype(Neos.Fusion:Component) {
  link = CodeQ.Link:NodeLink {
      node = {node}
      backendLink = false
  description = Neos.Neos:Editable {
      property = 'description'
  renderer = YOUR.Site:Presentation.Molecule.BlogPostTeaser {
      @apply.props = ${props}

By separating the aspects of link types and rendering we enable the separation of those aspects into different fusion-components.

What's important to notice:

  • If a link should be a link in the backend can be controlled in your integration with backendLink = false
  • If a component should be rendered, if no link is given can be configured on presentation with <CodeQ.Link:Tag renderDefaultTagIfNoLink={true}...
  • The code is easy to read, no hidden magic

So the package offers way more. Interested? Read ahead!


CodeQ.Link is available via packagist run composer require codeq/link. We use semantic versioning so every breaking change will increase the major-version number.


Rendering one link

As you have seen, the presentational part of rendering one link is simple:

<CodeQ.Link:Tag link={} />
<CodeQ.Link:Tag link={} class="my-class">Read more</CodeQ.Link:Tag>
<CodeQ.Link:Tag link={} renderDefaultTagIfNoLink={true} defaultTagName="span">Link or Span</CodeQ.Link:Tag>

For the integration we offer a lot of helpers to implement common use cases:

  • For Monocle: CodeQ.Link:DummyLink
  • Defining everything yourself:
    CodeQ.Link:Link {
      link = ''
      label = 'Sponsor'
      rel = 'noopener'
      target = '_blank'
  • Handling Neos nodes:
    CodeQ.Link:NodeLink {
      node = ${node}
      backendLink = false
  • Handling Neos assets:
    CodeQ.Link:AssetLink {
      asset = ${asset}
      backendLink = true
  • Handling Neos strings with references, like 'node://XXX' or 'asset://XXX'
    CodeQ.Link:StringLink {
      link = ${q(node).property('link')}

Rendering one link lists and menus

Our menu items are inspired by the Neos core and have the following API:

CodeQ.Link:MenuItem {
  link = '#'
  label = 'Page 1'
  state = 'active'
  subItems = Neos.Fusion:DataStructure

We provide the following helpers:

  • CodeQ.Link:DummyMenuItems
  • CodeQ.Link:NeosMenuItems {
      startingPoint = ${site}
      maximumLevels = 2
  • CodeQ.Link:DummyReferences
  • CodeQ.Link:NodeReferences { nodes = ${q(site).property('nodes')} }

You need to provide your own code to render it, this will typically look something like:

menuItems = CodeQ.Link:DummyMenuItems

renderer = afx`
    <ul class="menu">
        <Neos.Fusion:Loop items={props.menuItems} itemName="menuItem" @children="itemRenderer">
            <li class={'navigation-item ' + (menuItem.state ? 'navigation-item--state-' + menuItem.state : '') }>
                <CodeQ.Link:Tag linkSource={menuItem} />


When would I use CodeQ.Link and when Carbon.Link?

Carbon.Link is great for rendering links with just <Carbon.Link:Link node={props.node}>Read more</Carbon.Link:Link> if you don't use Sitegeist.Monocle.

If you want to use Monocle Carbon.Link does not work, because it uses content and node data inside the prototype. Also it does not offer a way to give link configuration to the Fusion rendering.

By providing a transfer object instead, we implement Carbon.Link functionality with Monocle in mind. What does such a transfer object consist of:

Neos.Fusion:DataStructure {
    link = '/'
    label = 'Home'
    rel = false
    target = '_blank'

Background information

Carbon.Link does a really great job at offering an appealing simple API, but at the cost of some very complex and slow requests, generally massively slowing down rendering if you use it 50+ times - which you easily archieve using it inside a menu. So we chose to reimplement these features in a more explizit API.


Licensed under MIT, see LICENSE

Sponsors & Contribution

The development of this plugin was kindly sponsored by Code Q.

We will gladly accept contributions. Please send us pull requests.

The content of the readme is provided by Github
The same vendor provides 19 package(s).