Page MenuHomePhabricator

Support Discourse's specific dialect of OpenGraph metadata tags to enrich Discourse "OneBox" previews
Open, WishlistPublic

Assigned To
Authored By
Nov 20 2017, 1:53 PM
Referenced Files
"Orange Medal" token, awarded by Krinkle."Love" token, awarded by friesenschrauber."Mountain of Wealth" token, awarded by johnny-bit."Love" token, awarded by qgil.


I haven't found a similar suggestion, so here it goes:

Have you considered adding Open Graph metadata in Phabricator pages? The use case is to render Phabricator URLs into informative and beautiful boxes in the services supporting that feature.

For an example, here is a comparison between Phabricator and GitHub URLs, as rendered by Discourse:

(Sorry, I could not find an appropriate tag.)

Event Timeline

epriestley triaged this task as Wishlist priority.Nov 22 2017, 9:05 PM
epriestley added a subscriber: epriestley.

After spending a couple hours on this, I more or less understand what we have to do, but it isn't entirely straightforward.

Discourse requires an og:description tag, and we don't currently have a convenient way to build a sensible description for all pages in a generic way. We can add support, but this requires going through each application and updating it. There are also some Remarkup vs text concerns (see also, e.g., T3278), although we could deal with that later.

Additionally, as far as I can tell your examples (of GitHub integrations) are all hard-coded by Discourse/OneBox, and not achievable with OpenGraph, despite what the replies on that thread imply. We can achieve something a bit similar, but we can not implement the "Opened by <user> on <date>" element or anything else fancy in the body of the UI. These work with GitHub because Discourse/OneBox have explicit code for handling GitHub -- for example:

I added some notes to the Discourse thread.

We may be able to get Discourse to accept a Phabricator OneBox implementation for our various content types, but this is a large amount of work (and I'm not familiar with Ruby).

Short of that, we can go add description metadata object-by-object, but this is probably a day of work to go through everything and test it, particularly because testing OneBox against a local development environment is a pain.

@epriestley thank you very much for looking into this so quickly and in such detail. I fully understand that it is not worth investing a lot on this task. I thought this would be almost an easyfix, and I have learned something understanding the complexities (and the fact that OneBox hardcodes quite a bit of the fancy boxes).

I backed out the earlier changes since I'm not sure when this will move forward, but:

  • D18780 is mostly fine, but the image in D18781 is a better choice (not white-on-transparent) so the logo changes are unnecessary.
  • D18781 is unnecessary (OneBox does not care about the <html /> tag), but the image change is good.

To move forward, we'd probably need to add methods like setOpenGraphTextDescription(), setOpenGraphRemarkupDescription(), and setOpenGraphEmptyDescription() to StandardPageView. Page rendering changes to:

  return $this->newPage()
+   ->setOpenGraphRemarkupDescription($object->getSummaryOrWhatever())
+   ->setOpenGraphEmptyDescription(pht('This <whatever it is> has no description.'))

When rendering OG tags:

  • If there's a text or remarkup description but no empty description, throw an exception ("Empty description is required for OG pages."). This prevents issues where someone forgets to add an empty description and we get inconsistent behavior for the rare task with no description, commit with no description, blank wiki page, etc.
  • If there's no empty description, don't render any OG tags (unless we later add support for some other consumer which isn't as strict).
  • If there's a nonempty text description, truncate it appropriately and use it as og:description.
  • If there's a nonempty remarkup description, mangle it with PhabricatorMarkupEngine::summarize() for now (which also truncates it) and use it as og:description. Distinguishing between setText... and setRemarkup... lets us upgrade this when T3278 improves.
  • If both are empty, use the "empty" description.

Maybe "Default" is a better term than "Empty", since then we could set a "Default" description on other pages like, say /config/ ("This page is for configuring Phabricator.").

For what is worth, I believe the main use case for this are Maniphest tasks: someone complaining about X in social media or tools like Discourse, then someone replies pointing to a related Phabricator task.

After the title, the most important value is the pair status, priority, a simple text string already available in Maniphest that provides a lot of context before visiting the page.

Maybe the tags (projects) are even more relevant and easier to handle than the actual description of the task.

If by placing the URL of a Phabricator task somewhere a box generates with the title, status, priority, projects and an avatar of the author just for the looks, I think the excerpt of the task description is completely secondary and could even be skipped.

epriestley renamed this task from Open Graph metadata for beautiful rendering of Phabricator URLs to Support Discourse's specific dialect of OpenGraph metadata tags to enrich Discourse "OneBox" previews.Dec 18 2017, 5:20 PM
Krinkle added a subscriber: Krinkle.

This would also be great for Phame, so that sharing a link to a Phame post results in a title card when shared on Twitter.

Looks like Twitter's dialect of og tags is slightly special, but nothing too crazy:

There are a lot of options here, and it possibly makes sense to let users customize some of this stuff (like the post summary text, the Twitter handle attribution, and card images). I don't want to overwhelm users with options in the common case, but this stuff can probably live in a subscreen and we can pick reasonable defaults for most of it (e.g., let the blog itself have a default image and content handle attribution).

I was sort of unpersuaded by the original Discourse thread, but the Twitter integration looks less magical, and blog posts are a more clear-cut integration point.