Enable mapping of entity bundles and fields to ActivityStreams object types
Each Drupal content entity bundle (node type, media type, etc.) can be mapped to a specific Activity Streams object type.
Notes:
- Important that we assign sensible defaults. A site admin shouldn't require deep ActivityPub knowledge for basic setup.
- On module install, programmatically enable and configure ActivityPub for applicable content entity bundles. Ideas:
- Consult RDF schema where available. For example,
types: ''schema:Article'on a content type would map to theArticleActivityPub object type; possibly,a field withproperties:'schema:text'would map to thecontentproperty in ActivityStreams. - Consider a commonsense default where the bundle label equals an ActivityPub object name. For example, the content type "Event" would map to
Event. - Examine fields and make a determination. Example: Media type (
mediaentity bundle) using theVideoFilesource plugin maps to theVideoobject type.
- Consult RDF schema where available. For example,
- On module install, programmatically enable and configure ActivityPub for applicable content entity bundles. Ideas:
- For field mapping, options should be limited to applicable properties by field type. For example, a date field could be mapped to
startTime. But note that the same field might map also toendTimeand evenduration. - Entity property mappings should be automatically assigned where feasible. For example,
$node->updatedshould map to theupdatedproperty. - Need to respect properties and fields marked as internal,
\Drupal\Core\TypedData\DataDefinitionInterface::isInternal().
Possible models
There are many ways this could work.
Relevant models include:
Core RDF module plus contrib RDF UI.
- Mappings stored as config entities.
- UI module enables editing of the config entities.
Configuring a content type:

Configuring a content type's fields:

Core JSON:API module plus contrib JSON:API Extras
- Resources programmatically generated.
- Resources can be overridden/customized using a UI from JSON:API Extras
Selecting which resources to override:

Configuring properties and fields:

Group module
- A plugin for each applicable bundle
- Plugins can be enabled and configured
A plugin for each entity bundle that can be enabled for a group:

Configuration for a plugin:

Spent some time looking over the options here. The model that stands out is JSON:API. The authors of that module have already tackled many of the hard questions we'll face here. While we won't need nearly all of what's there, we can draw a lot.
A key design feature of JSON:API - and a difference from our use case - is it "just works". While there's a lot of tweaking you could do, there aren't any necessary choices in exposing data for the JSON:API spec, so it's possible to have a default implementation that you just turn on. Only if you need changes do you then need to alter the defaults, which you can do either programmatically - like by writing custom normalizers - or via the config entity and accompanying UI provided by JSON:API Extras.
In our case, we're not just exposing our data; we have to also map it to the specific object types and properties expected in the AP spec. So "it just works" isn't a realistic goal. We need a configuration entity and UI. However, with some tweaks, the basic architecture of JSON:API is still applicable. Because our task is fundamentally similar. Like JSON:API, we:
- Potentially want to handle any bundle of any content entity type.
- Want to have available all entity properties and fields.
So like JSON:API we need a solution that's automatically aware of all such.
Following ResourceTypeRepository, we compile a repository of all content entity types and their bundles and fields. This repository does not include mappings, either to AP object types or their properties. That's done via a configuration entity type, parallel to that defined by JSON:API Extras, with the difference that it's defined by our base module. Then the admin UI for working with these config entities is in a dedicated UI module. (This part of the solution is closely parallel to core's RDF module and the contrib RDF UI.)
The admin UI looks a lot like that for JSON:API Extras, with the following differences:
- Provide more user-friendly names for the resources. Yes, for DX we'll use the same keys, such as
comment--comment, but provide the entity type label ("Comment"). - Path is not applicable.
- For Operations, rather than "Overwrite", we'll have (like the Group module) "Install" or, if already enabled, "Configure" and "Uninstall".
- For State, either Installed or Uninstalled.
- Once installed, a resource can be temporarily disabled by setting the disabled flag or deleted to uninstall.
- On install of our module, we programmatically create and configure a basic set of these config entities so that, in this limited sense, it does indeed "just work".
Ah I guess I mixed a bit of this with #6 (sorry). But as I was verbosely talking about there the RDF helps here because it is namespaced linked data, and can even include the schema.org NS properties.