Structured Data in Json-LD for Neos - beyond SEO and

I’m looking for a as simple as possible solution to handle structured data.

  • Primarily to generate Json-LD for search-engines in
  • But would be great to use the created Json-LD as datasource like described in @sebobo’s talk
  • Could be an easy to maintain and editor-editable/-changeable/extendable project-wide datasource.

Does anyone know a specific plugin or part of one to use as code-base boilerplate for

1. store data in Json-LD as datasource?

2. generate output for search-engine?

3. use the data for further output on other place in website?

Thanks to @christianm I could find @dfeyer’s But seems to be outdated and if I recognize correctly with focus to provide a CLI-tool to generate Yaml file as a starting point.

In General:

Maybe I’m looking in wrong corners: Would be nice to get tipps about best way to store project-wide data central placed, editor-friendly and flexible.

So far I found only the less-practical solutions with «hard-coded» content-collection tree as datasource structure, Yaml-File or Plugin with own db-store. All three less editor-friendly and inflexible.

Would be great to get hints, links or informations about!

This package is more an experiment than anything really production ready and my package only handle the creation of the Node structure configuration (YAML), nothing about rendering.

Converting a Node to JSONLD is pretty easy, but a generic solution is not easy because of the flexibility of the schema / structure. You can have so many cases, like when the JSON-LD is not strictly related to the node structure, or based on some relation but not all, …

I agree! And thank you for information of plugin’s aim.

On the other hand, it would be very tempting to have a less strictly related datasource sometimes. Would increase flexibility.

Maybe I interpreted the talk wrong. But it would be tempting to use «Json-LD as datasource». Sounds too seductive in my ears.

Perhaps I am on the totally wrong track, but from time to time it would help to have site-tree/node-structure-independency. Or in a way detached data from the default-structure, packed in own structure like Json-LD or possibly vice versa: Json-LD build from a separated node-tree.

Notes and thoughts are very welcome!

@mad After many discussions with content strategists most of them use to build content hub that stay “software agnostic” so the contents (and the strategy) can survive hype and software changes. I think my package is wrong because it use too much inheritance. This package can be more useful if the produced node type are abstract. So when you build a website you can get some schema “module” and compose the node type that you need, it can be really powerful, but need more spare time than I have currently. [quote=“mad, post:3, topic:2328”]
Maybe I interpreted the talk wrong. But it would be tempting to use «Json-LD as datasource». Sounds too seductive in my ears.

This is also a great idea, if content stored in the CR, but based on, can be easly converted to JSON-LD or RDF, the CR will be usable as a hub of content for other tools.

There is other intersting specification about content share / reusability, like DITA. Many nice articles about DITA can be found here

@dfeyer: thanks for:

Have done research about at weekend. All in all sound very interesting, but also all I’ve read about and found is difficult to record for me – very «dry»-stuff. Have problem to integrate in Neos-system-thinking with an separated approach. Found only few practical examples (all not for websites, nor CMS) of DITA and very theoretical.

  • Does anyone have hints for more practically example/reads?
  • Does someone have create some Neos-stuff with DITA – or for?

Currently DITA is just in my radar, no real research done.

About the JSON-LD, I work on a prototype to generate JSON-LD based on node type configuration, let’s see what happens, currently I try something with this configuration:

          ISO8601: "Y-m-d\TH:i:sO"
          where: "${q(node).property('where').get(0)}"
          @type: Event
          name: "${q(node).property('title')}"
          startDate: "${Date.format(q(node).property('begin'), ISO8601)}"
          endDate: "${Date.format(q(node).property('end'), ISO8601)}"
            @type: Place
            name: "${q(where).property('title')}"
              streetAddress: "${q(where).property('streetAddress')}"
              postalCode: "${q(where).property('postalCode')}"
              addressLocality: "${q(where).property('addressLocality')}"
              addressRegion: "${q(where).property('addressRegion')}"

It start to work for simple case, now need more test with more complex data structure, like a workshop that can be offered with multiple sessions:

          @type: Event
          name: "${q(node).property('title')}"
          subEvent: "${LinkedData.List(q(node).children('sessions').get())}"

Currently I’m not completly sure if the coupling NodeType to 1 JSON-LD representation is OK or not. But the syntax can be extended to support presets:

            @type: Event
            name: "${q(node).property('title')}"
            subEvent: "${LinkedData.List(q(node).children('sessions').get())}"

A small package that implement the give configuration:

After some test on a current projet, it’s really nice to use if your are confortable with EEL query and it’s really flexible.

If google provide some API for JSON-LD validation that can be a nice Inspector integration to help the editor respect the Google requirement . This tools ( is nice, but not sure if a proper API exists.

1 Like

@dfeyer Yeah!
I did not know even in the “beginning” what is possible with Yaml-Configuration-Files: The dynamic-part has been perfectly hidden – until now. Thanks a lot.
Also for sharing your LikedData-code. Will have a look today. The approach sounds really staggering!
Inspiring to define basic-data’s as particular NodeTypes for “detached” storing on root-level and re-use them over yaml and EEL for clean structure delivering to search engines and Fusion-EEL for all other direct-website-stuff.

We release version 0.2.0 of the LinkedData package, a bit more flexible with the LinkedData.renderRaw() helper and the README is more complete.

@dfeyer: Static Example works (with typo-fix) – Thanks!

In the static example there is the «potentialAction»: I guess, per default it will not work, if search engines would output this in SERP as search-field …

Because, tried the example adapted to the real-world-working-terms typed by hand:
only response with root-website as output without redirect to search-site or result from search…

I use simpleSearch:
Does anyone know, if there have to be/is possible to define a particular uri-rule for redirection to simpleSearch?

Maybe there is a docu about to use getParams instead of the default Post-Form-Param. But I can’t find.

Found solution:[word]={search_term_string}

Just stumbled upon the thread.
@dfeyer: I am currently building a nodetype package with reflects the Dita specification including a Dita editing mode. So ping me if you wanna talk Dita :stuck_out_tongue:

@daniellienert When you have something to test ping me. Not enough time on my side to go deeper on Dita