Editable rich text fields

A standard thing in ActivityPub is that there’s content containing rendered rich text such as HTML, and source contains the source material and can be used for editing the content. The AS2 vocabulary spec describes the content property like this:

The content or textual representation of the Object encoded as a JSON string

What if an object has some rich text field but that field is not the “content” or “textual representation” of the object? And what if there are multiple rich text fields? For these cases, I want to ask:

  • Which property to use for the HTML?
  • Which property to use for the Markdown source?
  • Which properties to use for media types?

I want to give specific examples and be very precise about what I’m asking.

Question 1: Placing the source field

Imagine there’s a property description and we want it to contain HTML, and we also want to provide Markdown source. One hypothetical very scary way to do this is to define a dedicated properties for the source and media type:

{ "@context": "...",
  "id": "https://...",
  "content": "This is the content of this object",
  "description": "<p>Here's some <b>bold</b> text</p>",
  "descriptionMediaType": "text/html",
  "descriptionSource": {
    "content": "Here's some **bold** text",
    "mediaType": "text/markdown"

Another way, perhaps a nicer way is to do something like this:

{ "@context": "...",
  "id": "https://...",
  "content": "This is the content of this object",
  "description": {
    "content": "<p>Here's some <b>bold</b> text</p>",
    "mediaType": "text/html",
    "source": {
      "content": "Here's some **bold** text",
      "mediaType": "text/markdown"

Does the 2nd way look reasonable? Shall we do it like this? The downside is that description doesn’t have an obvious type as its range. AP doesn’t define a range type for the source property. Are we ok with that? Or do we want do define/propose a type for this? We could call it Content or something. Idk.

Question 2: How much to use content

For a Note, the content is the true actual essence of the note. When you talk about writing a note, the stuff you write is what’s in the content. But imagine something like Banana, and we want to specify a description of this banana, e.g. “A sweet delicious yellow ripe organic banana”. Do we put this text under the content property? I’m asking because this text is clearly not the content of the banana. The content is a physical object you’re about to eat, in the physical world.

Another example, imagine a Merge Request submitted against one of your Git repos. The Merge Request probably has a title, and a longer description, and then there’s the actual commits that the submitter made. Do we put the Merge Request’s description in content? I’m asking because the actual content, essence, of the merge request is the commits, not the description.

So, I’m wondering: Should we use content when there’s a single description field for an object, even if it’s not the actual content and just a textual description/representation, or should we use other properties, and reserve content for use with the actual essence of the object (when the essence is textual; since the range of content is xsd:string so it can’t be e.g. a list of commits)?

What is the description meant to be used for? Normally you would have the content as text/html and additionally the source with an encoding of your choice. Friendica for example transports their BBCode with it. Socialhome does the same for markdown.

I think wrapping the content and the source into an own object is the best way, but we should clearly define it. Maybe for AP that’s to specific and we can just define it, for example, specifically for ForgeFed.

A MR then would have an AP content that textually represents it, for example IID, title and a small extract from the description, so implementations knowing nothing about MRs can still somehow represent them. And then we would have ForgeFed title and description; title being plain text and description of type “Content”, having (html) content, mediaType and (markdown) source.

I think what goes into content depends on what you want implementations that do not understand the type to display. I think that in that case what I described above is more useful than just a list of commits.

Again, I encourage to avoid extra properties unless really really needed. I feel that there is a lot of trying to add an extra property for a lot of things that just work with the existing properties AS2 ships with. Making everything custom will lose all the benefits of using AS2/AP in the first place.

What kind of cases would these be?

I actually try to reuse standard properties as much as possible and reasonable, but there’s also a point where reuse is just abuse and confusion.

The big question is whether to always use content for objects that have a single rich text field, or to use content only when it’s the actual essence of the object. Examples:

  • Banana: Which property to use for a rich text description of the banana? content? Or some other, possibly custom property? (because the actual content/essence of a banana is a physical object in the physical world)
  • MergeRequest: Which property to use for the rich text description? content? Or something else? (Because the actual content/essence of the merge request is technically a list of commits)

Either choice is fine with me, I just want to make a decision and follow it consistently.

Another example: a Commit object representing a git commit that exists in a repo. Does it make sense for content to be used for the commit message / description? Example:

    "@context": [
    "id": "https://dev.angeley.es/s/fr33domlover/r/vervis/p/5630042027e1bc11bcb401391eea409356413008",
    "type": "Commit",
    "context": "https://dev.angeley.es/s/fr33domlover/r/vervis",
    "hash": "5630042027e1bc11bcb401391eea409356413008",
    "created": "2019-11-13T13:26:26Z",
    "attributedTo": "https://dev.angeley.es/s/fr33domlover",
    "name": "docs: mention binary build in INSTALL.md",
    "mediaType": "text/plain",
    "content": "I uploaded a binary build to a Nextcloud folder, detailed usage instructions are missing but will be added soon. Ping me on IRC if you get any errors with it."

(The commit message is split between name and content; why that is, is discussed in another thread, either way not the point of the example)

I think banana is a very tricky example. content would be the textual representation of that specific instance of banana. An example could be:

  "@context": {
       "fruits": "https://superfruits.net/ns/",
  "type": "fruit:Banana",
  "fruits:Banana#blackspots": [ [1,2,3], [3,4,2], [6,1,5] ],
  "fruits:age": "1d",
  "content": "A banana with three black spots, 1 day old."

Now, most implementations don’t know anything about superfruits, so the only property the understand is content so they will just display that.

I took alook at Article, and it has it’s title in name and the body in content, for a MR the plain-text title would go to name and the rendered rich text then could go to content as html and the markdown to source.

Regarding this:

That was in context of multiple editable rich text fields. But, Jason might be right with “who needs that?” for the moment.

Regarding the commit example I think that looks okay that way. :slight_smile:
Name is the plain-text “title”/display name and the content is the longer description of the commit. (what is what and why is/was, as you said, a different discussion.)

1 Like