codeq/link

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

Installs: 2 036

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 2

Forks: 0

Open Issues: 0

Type:neos-package

v2.1.0 2021-06-28 12:43 UTC

This package is auto-updated.

Last update: 2021-11-24 17:25:33 UTC


README

Latest Stable Version License

CodeQ.Link

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 = 'https://github.com/code-q-web-factory/neos-link'
                label = 'CodeQ.Link is awesome'
            }
        }
    }

    link = CodeQ.Link:Link

    renderer = afx`
        <CodeQ.Link:Tag link={props.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 = 'https://example.org/my-first-blog-post'
            }
            description = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam'
        }
    }

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


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!

Installation

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.

Usage

Rendering one link

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

<CodeQ.Link:Tag link={props.link} />
<CodeQ.Link:Tag link={props.link} class="my-class">Read more</CodeQ.Link:Tag>
<CodeQ.Link:Tag link={props.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 = 'https://codeq.at'
      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} />
            </li>
        </Neos.Fusion:Loop>
    </ul>
`

FAQ

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.

License

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.