5

I’m trying to implement different hyperlink styles within a rich-text field by adding formatting options via a Redactor config file.

"formattingAdd": [
  {
    "title": "Button",
    "tag": "a",
    "class": "button"
  }
]

This isn’t working as expected though. The above, for example, adds a <span> around or within the <a> tag, occasionally removing the <a> tag altogether.

Is there a way to add classes to hyperlinks within a rich-text field?

Note: This rich-text field is already within a containing Matrix field, so that’s not an option.

6

If you only want to style how the link looks visually, and need a work-around, you could use my Redactor Styles for Craft plugin. If you add an inline style to the plugins Styles JSON object like this:

[
  {
    "btnName":"Action button", 
    "className":"btn-action", 
    "spanClass":"btn-action"
  }
] 

Depending on which order the user creates the link and marks the text/link and select style, you now can get the following markup from your rich text field:

<span class="btn-action"><a href="http://loremipsum.net">A link</a></span>
<a href="http://loremipsum.net"><span class="btn-action">A link</span></a>

If this works for you or not depends on your design. Unless there are some styles on the that can't be removed, you could style it so that it looks the same by using:

.btn-action > a,
a > .btn-action { ... }  

You could also instruct your users to always create the link, then select the style, or the other way around. But, it's of course a very fragile solution.

Thinking of making a new plugin just for creating more advanced links, the built in one doesn't really cut it.

| improve this answer | |
3

I tried a few different solutions but didn’t find anything user friendly enough, and ended up writing a Redactor plugin that adds a button to toggle a class on any selected links.

var RedactorPlugins = window.RedactorPlugins || {};

RedactorPlugins.toggleButton = function()
{
    return {
        init: function()
        {
            var button = this.button.add('toggle-button', 'Toggle Button');

            this.button.setAwesome('toggle-button', 'fa-minus-square-o');

            this.button.addCallback(button, function()
            {
                this.link.toggleClass('button');
                this.code.sync();
            });
        }
    };
};

There’s some extra styles to keep things tidy but the actual functionality is covered in the above-pasted snippet.

| improve this answer | |
  • 1
    How do you implement this plug in within Craft? – Alan Miller Aug 11 '15 at 1:53
  • 2
    I'll gladly send my warmest personal regard if you can describe how that's actually implemented. – Nick Benson Aug 20 '15 at 1:16
  • @AlanMiller/@NickBenson: Hi both. I’ll add this to my list to share. It’s quite a simple plugin. – Joshua Baker Aug 24 '15 at 15:35
2

I don't think this is possible using formattingAdd. From Redactor's docs:

formattingAdd can only be applied to p, pre, blockquote and header tags.

| improve this answer | |
  • Thanks for the response, Brad. I’m not sure what your relationship is like with the Redactor ream but it’d be great to have access to this functionality in future. – Joshua Baker Jul 30 '15 at 18:31
  • You've probably got as much influence with them as we do. :) – Brad Bell Jul 30 '15 at 21:39
2

For Craft 3 using Redactor 3, I have managed to create a small redactor plugin that toggles a class on all the links selected in redactor.

Here is how I did it.

  1. Create your folders. Create a folder called plugins inside the config/redactor/ folder. Inside the plugin folder create a folder for your plugin. Example I created a a folder called toggleButton. So the folder structure is config/redactor/plugins/toggleButton.

  2. Create your files. Create a your js file and your css file. It is important that the files are named the same as the folder. So in my example my files would be named toggleButton.js and toggleButton.css.

  3. Add you plugin to your redactor field. In your config/redactor folder you can add different redactor configs. For example I have Simple.json and Standard.json. This can then be selected in the craft admin, when you are adding your redactor field. In your selected config file add the following "plugins": ["toggleButton"],.

Example of my Simple.json file:

{
  "buttons": ["html", "link", "file"],
  "plugins": ["toggleButton"],
  "toolbarFixed": true
}
  1. Code your plugin. In you js file you want to create your redactor plugin code. In my example I add a button that toggles all selected links to have the class button.

Here is my js code:

(function($R) {
  $R.add('plugin', 'toggleButton', {
    translations: {
      en: {
        toggleButton: 'Button',
      },
    },
    init: function(app) {
      this.app = app;
      this.lang = app.lang;
      this.toolbar = app.toolbar;
      this.selection = app.selection;
    },
    // public
    start: function() {
      //Define the button object
      var btnObj = {
        title: this.lang.get('toggleButton'),
        api: 'plugin.toggleButton.toggle',
      };

      //Add the button to the toolbar
      this.$button = this.toolbar.addButton('toggleButton', btnObj);
    },
    toggle: function() {
      //This is what happens on when the button is clicked

      //Class that we will toggle
      var classToToggle = 'button';
      //Get all the links that are selected
      var selectedLinks = this.selection.getInlines({ all: true, tags: ['a'] });

      //Loop through all the links and toggle the class
      selectedLinks.forEach(function(element) {
        //Crossbrowser toggle class
        if (element.classList) {
          element.classList.toggle(classToToggle);
        } else {
          // For IE9
          var classes = element.className.split(' ');
          var i = classes.indexOf(classToToggle);

          if (i >= 0) classes.splice(i, 1);
          else classes.push(classToToggle);
          element.className = classes.join(' ');
        }
      });
    },
  });
})(Redactor);
  1. Style your Button. In your css file you want to style the links with the class button to look like buttons. So that the author sees that they have become buttons.

Here is my css code:

a.button {
  display: inline-block;
  box-sizing: border-box;
  font-size: 14px;
  text-align: center;
  padding: 10px 20px 9px 20px;
  cursor: pointer;
  outline: none;
  border: none;
  vertical-align: middle;
  text-decoration: none;
  zoom: 1;
  position: relative;
  color: #29323d !important;
  border-radius: 2px;
  background: #eaf0f4;
  background-image: linear-gradient(#f3f6f9, #eaf0f4);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.22);
  margin-right: 5px;
  margin-bottom: 4px;
  text-decoration: none !important;
}

a.button:hover {
  outline: none;
  color: #fff !important;
  background: #449aef !important;
}

Now you and your authors can easily make links in to buttons in your redactor field. Then it is up to you how you use that in the frontend.

References:

| improve this answer | |
  • This works perfectly, thank you! If you're using HTML Purifier, you may also need to update it to allow classes on links. My purifier config looks like this: "HTML.Allowed": "a[href|class], br, p, b, strong, em, i, ul, ol, li, h2, h3, h4" – Dalton Sep 23 '19 at 18:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.