MarkupInterface interoperability with other PHP frameworks Situation in Drupal 8

Drupal 8 introduces a few classes and interfaces for safe markup:


Drupal\Component\Render\MarkupInterface
Drupal\Component\Render\FormattableMarkup
Drupal\Core\StringTranslation\TranslatableMarkup


The purpose is


to mark a string as being safe for use in html, without further sanitization.
to have the string be lazy-evaluated.


The problem seems to be that all of these are specific to Drupal.

Use case

I am designing an API I want to publish as a composer package, that should be used and implemented within Drupal 8 but also work outside of it. It should not depend on anything within Drupal.

There are interfaces that can return string labels, or arrays of such labels (e.g. to act as option labels in a select element).

Implementations within Drupal will want to use the t() function, which returns TranslatableMarkup objects. But the interface or the calling code know nothing about Drupal's TranslatableMarkup or MarkupInterface.

Solutions considered so far

One option would be to require all implementations to return plain strings, which they can do via (string) cast, or by calling the __toString() method. This would work but it feels unnatural.

Another option would be to introduce a custom TranslatableString object which my own API can understand. This would replace a Drupalism with a my-own-ism, and also feel clumsy for implementations within D8.

Another option would be to allow the interface to return arbitrary values and later attempt to convert them to strings using either a flexible adapter layer, or attempting to call the __toString() function. This would make it harder to require a specific return type, and detect if an implementation returns "illegal" values.

Question

Have there been any attempts to make a "bridge" between Drupal's MarkupInterface (EDIT: And TranslatableMarkup) and the larger PHP ecosystem?



Ongoing discussion

There are some comments below which point to interesting directions.

I'd say the main question is still open: How can we bridge the Drupal-specific classes and interfaces to the outside world? Are there Drupal-agnostic versions of these classes and interfaces?
TLDR

(this summarizes conclusions from the comments below)

The MarkupInterface is available on packagist as part of the drupal/core-render package, which provides all the classes from Drupal\Component\Render\* without any heavy dependencies (only drupal/core-util). It does not give you TranslatableMarkup, though.

If you let your package depend on drupal/core-render, you can use MarkupInterface as a return type.

Implementations within Drupal modules, which call t() and return a TranslatableMarkup object, would satisfy the return type from the interface.

Implementations outside of Drupal would instead return FormattableMarkup, or HtmlEscapedText, or a custom implementation of MarkupInterface. Or something else, if the interface allows alternative return types (e.g. native string).

You need to decide if you accept this dependency, or do something else instead.

Original (longer) answer

The ultimate goal of having the two names spaces in Drupal is


Drupal\Component is for classes that do not need a bootstrapped kernel.  In other words, these do not need a running Drupal system. These classes may depend on other classes outside Drupal\Component (eg, Symfony) or other classes in Drupal\Component, but not Drupal\Core
Drupal\Core is for classes that require a bootstrapped kernel.  These full from Drupal\Core, Drupal\Component, and elsewhere.


Take date/time objects.


DrupalDateTime is in Drupal\Core because leverages the translation service.
DateTimePlus is inDrupal\Componentbecause it adds some enhancements to the native\DateTime` class.


So, in theory, Drupal\Component can be used in anything. That said, the composer.json files for each component may not be accurate for dependencies and minimum PHP version.

In your case, MarkupInterface and FormattableMarkup should be able to be used outside of Drupal. TranslatableMarkup relies on the Drupal translation system, which needs a booted kernel to operate.

TranslatableMarkup essentially just extends FormattableMarkup, and acts a bridge to the string translation service. So, that on its own doesn't buy you much unless you need everything that surrounds translation (language management, the UI, etc).

All of that said, I am not sure how much you will really gain from this. Ignoring the translation parts, FormattableMarkup is a component, but they are really best used as part of the rendering service, which is part of core.  For the purposes of making your own API, I would start with seeing if you can just leverage FormattableMarkup on its own.