Broadly speaking, there are a lot of different, maybe mutually exclusive or incompatible ideas of what a “quote” is, or what it should do, or what it should look like, and so on. Many people, when asking for such a “quote” feature, are drawing inspiration from past features, perhaps more commonly the Twitter “quote tweet” or perhaps alternatively the forum-style “quote” as can be seen on this very Discourse forum. This pre-FEP aims to describe all possible approaches, as well as describing the pros and cons of each approach from both semantic and practical perspectives.

Implementation approaches

The quote reply

The semantic purpose of the inReplyTo is to denote that the current resource is “in reply to” or considered a response to the linked resource. Very often, a “quote” is semantically a response to the “quoted” resource. What actually makes it a “quote” is purely presentational or display-based; the “quoted” resource is embedded next to the “quote”. This embed can be placed below or above the current resource; because reading often happens top-to-bottom, a placement below the current resource allows the “quote” to act as framing for the “quoted”, while a placement above the current resource allows the “quoted” to provide a contextual preview for the “quote”.

Some implementations differentiate between “replies” and “normal posts”, while other implementations treat all posts the same regardless of whether they are in reply to anything or not. For example, at the time of writing this, Mastodon filters out “replies” from your timeline unless you follow the author of the post being replied to. Pleroma does no such filtering. Akkoma and Misskey make it a user choice. These are once again presentational choices, stemming from implementation-specific UX choices. For an AS2 producer which makes such distinctions, it may be helpful to signal a further distinction between “replies” and “quote replies”; a “quote reply” could be shown in timelines always, or considered the same as a “normal post”. If, for example, Mastodon wanted to adopt this strategy, it could define an extension property like http://joinmastodon.org/ns#quoteReply which, if set to true, would treat the resource linked in inReplyTo as a “Mastodon quote post”, opting into the rendering and timeline-filtering behavior associated with such a concept. An AS2 consumer sharing Mastodon’s UX choices and aware of this property would interpret objects with toot:quoteReply = true as “Mastodon-style quote posts”. An AS2 consumer not sharing Mastodon’s UX choices can render the reply metadata as it wishes; it is possible to render all replies as “quote replies” by simply embedding a preview of the replied-to resource above the current resource.

The quote tag

The purpose of tag is to markup the natural-language properties of name, summary, and content. In particular, substrings of content are often associated with richer metadata. Most commonly, tags of type Mention are used to associate a specific substring following a microsyntax, @mention, with a specialized Link that is intended to denote a “mention”.1 Following this logic, Mastodon’s implementation of ActivityPub defined extensions for https://www.w3.org/ns/activitystreams#Hashtag2 and http://joinmastodon.org/ns#Emoji. The Hashtag type is used to associate the #hashtag microsyntax with a “hashtag”, which is a reference to some string. The Emoji type is used to associate an :emoji: microsyntax with a “custom emoji”, which is an inline image with a square aspect ratio and the same height as a single line of text. In each of these cases, the name of the tag denotes the microsyntax, and this substring of the (sometimes plain-textified and HTML-stripped)3 content can be replaced with a richer entity. FEP-e232 follows this logic as well; “object links” are tagged as a Link (or subtype) with appropriate mediaType, and the name is used to denote any applicable microsyntax such as RE: <url>, especially coupled with the use of rel to specify the link relation.

It is possible to build on FEP-e232 by using “object links” with a link relation specifically denoting a “quote” relationship. Some software such as Foundkey uses the rel-value https://misskey-hub.net/ns#_misskey_quote to denote a “Misskey quote”, while also accepting http://fedibird.com/ns#quoteUri and https://www.w3.org/ns/activitystreams#quoteUrl as equivalent. All three of these IRIs have historically been used as properties to express the same or nearly-identical concept – a single “post” that will be embedded as a preview below yours, separately from what you are replying to, intended to send a notification to the author of the quoted post that they’ve been quoted. It is possible to define standardized semantics using an IRI as a property or as a type, e.g. a Quote type.

The quote boost

The purpose of a share (Announce) is to draw attention to, boost, or republish the referenced object. Functionally, when sent to the author of that object, the author can add the Announce activity to the shares collection on that object. This gets interpreted as a “boost” or “reblog” within most current implementations.4

It is possible to add content to your Announce activity; a generic presentation of activities can use the natural-language properties name, summary, and content along with actor type object in order to generate a representation of the activity.

Comparison and analysis

Quote replies (reply with adjacent contextual preview)

  • (+) The quote reply maintains the best semantics in cases where the author is responding to the quoted object. It also falls back to a regular reply where not understood.
  • (+) The quote reply can easily inherit from “reply controls”, which allow authors of objects to grant stamps of approval that offer proof for a given object’s presence in the replies collection.
  • (-) The quote reply is practically (but not theoretically) limited to one “quoted” resource per post. It is possible to reply to multiple objects, although it is not immediately clear how this should be rendered or presented; adding a “quote reply” boolean property would limit the “quote” presentation to an all-or-nothing case, and selecting only some linked resources to be rendered as “quotes” would best be served by one of the other approaches.

Quote tags (rich quotes embedded in content)

  • (+) Multiple quote tags would be supported.
  • (~) Semantics can be signaled with rel or with extension types, but it is important to avoid proliferation of similar or identical semantic IRIs.

Quote boosts (reshare with comment)

  • (~) Might be semantically appropriate, if the “sharing” aspect of the “quote post” is what you intended.
  • (-) Falls back to a normal boost, without displaying the added content at all.

Footnotes

  1. (The exact meaning of a “mention” is not entirely clear. AS2-Vocab ties the definition to the @mention microsyntax, but provides no additional guidance on its intended functionality or meaning. At minimum, there is the implication that the Mention might denote an actor or a user, and might generate some notification that the mentioned entity has been mentioned. Software such as Mastodon follows this interpretation and uses mentions to generate notifications, but also goes further and requires tags of type Mention in order to determine delivery and addressing. Addressing someone in to/cc without mentioning them will create a “silent mention”.) Return to text

  2. (Mastodon defining as:Hashtag within the activitystreams namespace is technically lacking authority, as only the W3C SocialCG can adopt new terms into the activitystreams namespace or make modifications to the normative activitystreams context. In particular, as:Hashtag is an inline extension, and it is not defined in the normative context.) Return to text

  3. It is unclear when, how, or if such sanitiziation or stripping of content will take place. Current implementations are not entirely consistent with what they put into name (or href) compared to what they put into contentReturn to text

  4. Some software implementations do not use Announce as a reshare activity, and instead use it for other purposes outside of a publishing context, such as wrapping and forwarding someone else’s activity. The intended specified mechanism for doing this is inbox forwarding. Return to text