mirror of
https://github.com/flarum/framework.git
synced 2025-04-24 21:54:04 +08:00
feature: adds advanced link handling in core (#3455)
* feature: adds advanced link handling in core This PR adds rel and target to textformatter so that these can be easily extended and rendered into the source. Without using the Extender the default values `ngc nofollow` are provided as a backward compatible way. The new extender allows conditional overrides, a proof of concept extension is available at https://github.com/luceos/flarum-ext-dofollow; I will probably migrate this into the Blomstra namespace soon. * Apply fixes from StyleCI * fix typehints * fix: mixed typehint is php 8+ Co-authored-by: StyleCI Bot <bot@styleci.io>
This commit is contained in:
parent
62be3e01be
commit
0859bb13a5
62
framework/core/src/Extend/Link.php
Normal file
62
framework/core/src/Extend/Link.php
Normal file
@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Extend;
|
||||
|
||||
use Flarum\Extension\Extension;
|
||||
use Flarum\Foundation\Config;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Laminas\Diactoros\Uri;
|
||||
use s9e\TextFormatter\Renderer;
|
||||
use s9e\TextFormatter\Utils;
|
||||
|
||||
class Link implements ExtenderInterface
|
||||
{
|
||||
protected $setRel = null;
|
||||
protected $setTarget = null;
|
||||
|
||||
public function setRel(callable $callable): static
|
||||
{
|
||||
$this->setRel = $callable;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setTarget(callable $callable): static
|
||||
{
|
||||
$this->setTarget = $callable;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function extend(Container $container, Extension $extension = null)
|
||||
{
|
||||
$siteUrl = $container->make(Config::class)->url();
|
||||
|
||||
(new Formatter)->render(function (Renderer $renderer, $context, string $xml) use ($siteUrl) {
|
||||
return Utils::replaceAttributes($xml, 'URL', function ($attributes) use ($siteUrl) {
|
||||
$uri = isset($attributes['url'])
|
||||
? new Uri($attributes['url'])
|
||||
: null;
|
||||
|
||||
$setRel = $this->setRel;
|
||||
if ($setRel && $rel = $setRel($uri, $siteUrl, $attributes)) {
|
||||
$attributes['rel'] = $rel;
|
||||
}
|
||||
|
||||
$setTarget = $this->setTarget;
|
||||
if ($setTarget && $target = $setTarget($uri, $siteUrl, $attributes)) {
|
||||
$attributes['target'] = $target;
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
});
|
||||
})->extend($container);
|
||||
}
|
||||
}
|
@ -9,10 +9,14 @@
|
||||
|
||||
namespace Flarum\Formatter;
|
||||
|
||||
use DOMDocument;
|
||||
use DOMElement;
|
||||
use Illuminate\Contracts\Cache\Repository;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use s9e\TextFormatter\Configurator;
|
||||
use s9e\TextFormatter\Renderer;
|
||||
use s9e\TextFormatter\Unparser;
|
||||
use s9e\TextFormatter\Utils;
|
||||
|
||||
class Formatter
|
||||
{
|
||||
@ -98,7 +102,7 @@ class Formatter
|
||||
* Render parsed XML.
|
||||
*
|
||||
* @param string $xml
|
||||
* @param mixed $context
|
||||
* @param mixed|null $context
|
||||
* @param ServerRequestInterface|null $request
|
||||
* @return string
|
||||
*/
|
||||
@ -110,6 +114,8 @@ class Formatter
|
||||
$xml = $callback($renderer, $context, $xml, $request);
|
||||
}
|
||||
|
||||
$xml = $this->configureDefaultsOnLinks($renderer, $xml, $context, $request);
|
||||
|
||||
return $renderer->render($xml);
|
||||
}
|
||||
|
||||
@ -174,11 +180,13 @@ class Formatter
|
||||
*/
|
||||
protected function configureExternalLinks(Configurator $configurator)
|
||||
{
|
||||
/** @var DOMDocument $dom */
|
||||
$dom = $configurator->tags['URL']->template->asDOM();
|
||||
|
||||
/** @var DOMElement $a */
|
||||
foreach ($dom->getElementsByTagName('a') as $a) {
|
||||
$rel = $a->getAttribute('rel');
|
||||
$a->setAttribute('rel', "$rel nofollow ugc");
|
||||
$a->prependXslCopyOf('@target');
|
||||
$a->prependXslCopyOf('@rel');
|
||||
}
|
||||
|
||||
$dom->saveChanges();
|
||||
@ -217,7 +225,7 @@ class Formatter
|
||||
/**
|
||||
* Get the renderer.
|
||||
*
|
||||
* @return \s9e\TextFormatter\Renderer
|
||||
* @return Renderer
|
||||
*/
|
||||
protected function getRenderer()
|
||||
{
|
||||
@ -239,4 +247,17 @@ class Formatter
|
||||
{
|
||||
return $this->getComponent('js');
|
||||
}
|
||||
|
||||
protected function configureDefaultsOnLinks(
|
||||
Renderer $renderer,
|
||||
string $xml,
|
||||
$context = null,
|
||||
ServerRequestInterface $request = null
|
||||
): string {
|
||||
return Utils::replaceAttributes($xml, 'URL', function ($attributes) {
|
||||
$attributes['rel'] = $attributes['rel'] ?? 'ugc nofollow';
|
||||
|
||||
return $attributes;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user