Symbol before a link in Redactor

Permalink
Dear all,

I want to specify a link in a WYSIWYG text with a symbol infront of it.

E.g. World-Symbol for an external link, PDF-Symbol for PDF, Mail-Symbol for a mail address.

Mail:
<a href="mailto:info@flummi@flummi.impro.theater" class="link linkEmail"><i class="fa fa-envelope"></i> info@flummi@flummi.impro.theater</a>


Internal link
<a href="https://flummi.impro.theater/presse-und-kontakt/impressum"><i class="fa fa-sitemap"></i> Impressum</a>


How can I do this in Redactor?

I tried to manipulate the links when I view it (with a javascript) but I can not see whitch file I have (I have only the file number and not the type).

GunterSchmitt
 
PineCreativeLabs replied on at Permalink Reply
PineCreativeLabs
GunterSchmitt replied on at Permalink Reply
GunterSchmitt
Thank you for your reply.

This can be a workarround for the moment but I need a solution for automatic adding the ansome sign (in dependence of the link type)..

Best Regards

Gunter
MrKDilkington replied on at Permalink Reply
MrKDilkington
Hi GunterSchmitt,

This can be done using attribute selectors, pseudo-elements, and a custom template.

Examples:
- these would select anchor tags with href attribute values starting with different protocols
[href^="ftp"]
[href^="https"]
[href^="http"]
[href^="tel"]
[href^="mailto"]

- these would select anchor tags with href attributes ending in .pdf, .docx, .zip
a[href$=".pdf"]
a[href$=".docx"]
a[href$=".zip"]

- this would be your Content block custom template (requiring Font Awesome and adding a class to scope/namespace your CSS)
<?php defined('C5_EXECUTE') or die("Access Denied.");
View::getInstance()->requireAsset('css', 'font-awesome');
$c = Page::getCurrentPage();
if (!$content && is_object($c) && $c->isEditMode()) { ?>
   <div class="ccm-edit-mode-disabled-item"><?php echo t('Empty Content Block.')?></div>
<?php } else { ?>
    <div class="content-block"><?php echo $content; ?></div>
<?php }

- this would add the Font Awesome font icon symbol
.content-block [href^="mailto"]:before {
    content: "\f0e0";
    margin-right: 5px;
    font: normal normal normal 14px/1 FontAwesome;
}
.content-block [href^="http"]:before {
    content: "\f0ac";
    margin-right: 5px;
    font: normal normal normal 14px/1 FontAwesome;
}
.content-block [href^="https"]:before {
    content: "\f0ac";
    margin-right: 5px;
    font: normal normal normal 14px/1 FontAwesome;
}
GunterSchmitt replied on at Permalink Reply
GunterSchmitt
Thank you MrKDilkington,

this was also an idear by me but I have 2 problems:

1. All URLs (external and internal) starts with http, https, ftp...
In this case I have no change to select internal and external pages.

2. All URLs to files (files from contrete5) ends with the file number and nit with the file name. So I have no suffix like pdf, docx, xlsx ...
<a href="https://test.impro.theater/index.php?cID=1">test file</a>


Is there a possibility to change the links during creation, like giving the link a class (link-pdf, link-doc, link-external, link-mail, link-internal...)?

Thanks in advance

Gunter
MrKDilkington replied on at Permalink Best Answer Reply
MrKDilkington
@GunterSchmitt

For internal versus external links, you can target all links first, and then internal links second.

Here is an example of giving http/https links a purple world icon and internal links get a red icon:
.content-block [href^="http"]:before {
    content: "\f0ac";
    margin-right: 5px;
    font: normal normal normal 14px/1 FontAwesome;
    color: purple;
}
.content-block [href^="http://test.impro.theater"]:before,
.content-block [href^="https://test.impro.theater"]:before {
    content: "\f0ac";
    margin-right: 5px;
    font: normal normal normal 14px/1 FontAwesome;
    color: red;
}

There is likely a way to assign links during creation, but it would involve a lot of file overriding. Instead, you can manually add classes for files using this add-on:
https://www.concrete5.org/marketplace/addons/mrkdilkington-add-and-r...

Example classes and CSS for links to give them a PDF, Word, or Excel icon:
.content-block .link-word:before {
    content: "\f1c2";
    margin-right: 5px;
    font: normal normal normal 14px/1 FontAwesome;
    color: blue;
}
.content-block .link-pdf:before {
    content: "\f1c1 ";
    margin-right: 5px;
    font: normal normal normal 14px/1 FontAwesome;
    color: red;
}
.content-block .link-xlsx:before {
    content: "\f1c3";
    margin-right: 5px;
GunterSchmitt replied on at Permalink Reply
GunterSchmitt
Thank you MrKDilkington,

for the internal and external link I can use this but for the file links I have the problem that the site have more than one editors and is an non comercial project.
I can use this workarround but I can not animate the other authors to use this also. In this case its easier to use the addon ansome-fonts (see the secound post).

I search a methode to add the class during creation (automatic) and the best case was to add the filesize (for a file) also, so a file link will displayed like:

<a href="https://impro.theater/download_file/4/161 " class="link fileLink" target="_blank">PresseInfo - die Flummis.pdf (78,29 KB)</a>


Best Regards
Gunter
MrKDilkington replied on at Permalink Reply 1 Attachment
MrKDilkington
@GunterSchmitt

For files, you could explore using a custom template for the File block. In the custom template you could create custom classes based on the file extension and include the file size. The custom template could be set as the default in page_theme.php using the getThemeDefaultBlockTemplates() method.

Example CSS:
.ccm-block-file .link-docx:before {
    content: "\f1c2";
    margin-right: 5px;
    font: normal normal normal 14px/1 FontAwesome;
    color: blue;
}
.ccm-block-file .link-pdf:before {
    content: "\f1c1 ";
    margin-right: 5px;
    font: normal normal normal 14px/1 FontAwesome;
    color: red;
}
.ccm-block-file .link-xlsx:before {
    content: "\f1c3";
    margin-right: 5px;

See attached custom template.
GunterSchmitt replied on at Permalink Reply
GunterSchmitt
Hello MrKDilkington,

I tried to make a function to pharse the html from the Editor.

function extentLinks($text) {
   $attribute = "";
   if (isset($text) && trim($text) != ""){ 
      $doc = new DOMDocument();
      $doc->loadHTML($text);
      $links = $doc->getElementsByTagName('a');
      $domain = View::url('/');
      foreach ($links as $item) {
         $pos = strpos ($item->getAttribute('href'), "mailto:" );   
         if ($pos !== FALSE){
            $attribute = "link mail";
         } else {
            $pos = strpos ($item->getAttribute('href'), $domain );
            if ($pos !== FALSE){
               $pos= strpos ($item->getAttribute('href'), "/download_file/" );


But this dosen't work because I have 2 problems:

1. When I use this function it pharse signs like ü,ö,ä... in a wrong way (I get "öfters" instead of "öfters").

2. When I had more then one blocks in a page i get the message that the function "extentLinks" can not decleared a secound time.

Any idears?

Thanks in Advanced

Gunter
MrKDilkington replied on at Permalink Reply 1 Attachment
MrKDilkington
@GunterSchmitt

I am not sure what is causing the issue with umlauts. If you define your function in your controller as a method, you avoid the "redeclare" error. This can be done by overriding your Content block controller.

- controller method
use Sunra\PhpSimple\HtmlDomParser;
use File;

public function autoFormat($content)
{
    $dom = new HtmlDomParser();
    $html = $dom->str_get_html($content, true, true, DEFAULT_TARGET_CHARSET, false);
    if (is_object($html)) {
        foreach ($html->find('a') as $link) {
            // file links
            $downloadLink = strpos($link->href, 'download_file');
            // mail links
            $mailLink = strpos($link->href, 'mailto:');
            // internal links
            $internalLink = strpos($link->href, BASE_URL);
            if ($downloadLink !== false) {
                // download_file/view/47/304
                $pattern = '/download_file\/view\/(\d+)\//i';

- custom template
<?php defined('C5_EXECUTE') or die("Access Denied.");
View::getInstance()->requireAsset('css', 'font-awesome');
$c = Page::getCurrentPage();
if (!$content && is_object($c) && $c->isEditMode()) { ?>
   <div class="ccm-edit-mode-disabled-item"><?php echo t('Empty Content Block.'); ?></div>
<?php } else {
    echo '<div class="ccm-content-block">' . $controller->autoFormat($content) . '</div>';
}

- CSS
.ccm-content-block .icon:before {
  margin-right: 5px;
  font: normal normal normal 14px/1 FontAwesome;
}
.ccm-content-block .link-docx:before {
    content: "\f1c2";
    color: blue;
}
.ccm-content-block .link-pdf:before {
    content: "\f1c1 ";
    color: red;
}
.ccm-content-block .link-xlsx:before {
    content: "\f1c3";
    color: green;

I am attaching a custom template and overridden Content block controller. I tested it using umlauts without an issue - "die grünen Vögel fressen das Mädchen".
MrKDilkington replied on at Permalink Reply 1 Attachment
MrKDilkington
Here is another option that does not require the content output to be wrapped in a div or overriding the Content block controller. This approach works in both Redactor and CKEditor.

Please find attached a custom Content block template.
- the file will be unzipped into:
application\blocks\content\templates\file_info_icon

view.css
.file-info-icon:before {
  font: normal normal normal 14px/1 FontAwesome;
  margin-right: 5px;
}
.file-info-icon.link-docx:before {
    color: blue;
    content: "\f1c2";
}
.file-info-icon.link-pdf:before {
    color: red;
    content: "\f1c1 ";
}
.file-info-icon.link-xlsx:before {
    color: green;
    content: "\f1c3";

view.php
<?php
defined('C5_EXECUTE') or die("Access Denied.");
// HtmlDomParser and File are required for the fileInfoIcon anonymous function to work
// - HtmlDomParser lets you manipulate HTML
//https://github.com/sunra/php-simple-html-dom-parser...
use Sunra\PhpSimple\HtmlDomParser;
// - File lets you get information about and work with file objects
use Concrete\Core\File\File;
// if your theme does not use Font Awesome, you can require it
View::getInstance()->requireAsset('css', 'font-awesome');
$c = Page::getCurrentPage();
// $fileInfoIcon is the anonymous function that goes through the content looking for links
// - it assigns a class for displaying an icon and adds the file size to the display text
$fileInfoIcon = function ($content) {
    $dom = new HtmlDomParser();