File: external-links.md

package info (click to toggle)
php-league-commonmark 2.7.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 8,260 kB
  • sloc: php: 20,378; xml: 1,988; ruby: 45; makefile: 21; javascript: 15
file content (157 lines) | stat: -rw-r--r-- 5,170 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
---
layout: default
title: External Links Extension
description: The ExternalLinksExtension detects external links and adjusts their HTML markup
---

# External Links Extension

This extension can detect links to external sites and adjust the markup accordingly:

- Make the links open in new tabs/windows
- Adds a `rel` attribute to the resulting `<a>` tag with values like `"nofollow noopener noreferrer"`
- Optionally adds any custom HTML classes

## Installation

This extension is bundled with `league/commonmark`. This library can be installed via Composer:

```bash
composer require league/commonmark
```

See the [installation](/2.1/installation/) section for more details.

## Usage

Configure your `Environment` as usual and simply add the `ExternalLinkExtension` provided by this package:

```php
use League\CommonMark\Environment\Environment;
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
use League\CommonMark\Extension\ExternalLink\ExternalLinkExtension;
use League\CommonMark\MarkdownConverter;

// Define your configuration, if needed
$config = [
    'external_link' => [
        'internal_hosts' => 'www.example.com', // TODO: Don't forget to set this!
        'open_in_new_window' => true,
        'html_class' => 'external-link',
        'nofollow' => '',
        'noopener' => 'external',
        'noreferrer' => 'external',
    ],
];

// Configure the Environment with all the CommonMark parsers/renderers
$environment = new Environment($config);
$environment->addExtension(new CommonMarkCoreExtension());

// Add this extension
$environment->addExtension(new ExternalLinkExtension());

// Instantiate the converter engine and start converting some Markdown!
$converter = new MarkdownConverter($environment);
echo $converter->convertToHtml('I successfully installed the <https://github.com/thephpleague/commonmark> project!');
```

## Configuration

This extension supports three configuration options under the `external_link` configuration:

### `internal_hosts`

This option defines a list of hosts which are considered non-external and should not receive the external link treatment.

This can be a single host name, like `'example.com'`, which must match **exactly**.

Wildcard matching is also supported using regular expression like `'/(^|\.)example\.com$/'`.  Note that you must use `/` characters to delimit your regex.

This configuration option also accepts an array of multiple strings and/or regexes:

```php
$config = [
    'external_link' => [
        'internal_hosts' => ['foo.example.com', 'bar.example.com', '/(^|\.)google\.com$/],
    ],
];
```

By default, if this option is not provided, all links will be considered external.

### `open_in_new_window`

This option (which defaults to `false`) determines whether any external links should open in a new tab/window.

### `html_class`

This option allows you to provide a `string` containing one or more HTML classes that should be added to the external link `<a>` tags:  No classes are added by default.

### `nofollow`, `noopener`, and `noreferrer`

These options allow you to configure whether a `rel` attribute should be applied to links.  Each of these options can be set to one of the following `string` values:

- `'external'` - Apply to external links only
- `'internal'` - Apply to internal links only
- `'all'` - Apply to all links (both internal and external)
- `''` (empty string) - Don't apply to any links

Unless you override these options, `nofollow` defaults to `''` and the others default to `'external'`.

## Advanced Rendering

When an external link is detected, the `ExternalLinkProcessor` will set the `external` data option on the `Link` node to either `true` or `false`.  You can therefore create a [custom link renderer](/2.1/customization/rendering/) which checks this value and behaves accordingly:

```php
use League\CommonMark\Extension\CommonMark\Node\Inline\Link;
use League\CommonMark\Renderer\ChildNodeRendererInterface;
use League\CommonMark\Renderer\NodeRendererInterface;
use League\CommonMark\Util\HtmlElement;

class MyCustomLinkRenderer implements NodeRendererInterface
{
    /**
     * @param Node                       $node
     * @param ChildNodeRendererInterface $childRenderer
     *
     * @return HtmlElement
     */
    public function render(Node $node, ChildNodeRendererInterface $childRenderer)
    {
        if (!($node instanceof Link)) {
            throw new \InvalidArgumentException('Incompatible node type: ' . \get_class($node));
        }

        if ($node->data->get('external')) {
            // This is an external link - render it accordingly
        } else {
            // This is an internal link
        }

        // ...
    }
}
```

## Adding Icons

You can also use CSS to automagically add an external link icon by targeting the `html_class` given in the configuration:

```css
// Font Awesome example:
a[target="_blank"]::after,
a.external::after {
   content: "\f08e";
   font: normal normal normal 14px/1 FontAwesome;
}

// Glyphicon example:
a[target="_blank"]::after,
a.external::after {
  @extend .glyphicon;
  content: "\e164";
  margin-left: .5em;
  margin-right: .25em;
}
```