├── README.md └── src └── linkclass.js /README.md: -------------------------------------------------------------------------------- 1 | # redactor-link-styles 2 | 3 | This redactor plugin modifies the link modal to include a configurable drop down of class names that you can use to style links differently. 4 | 5 | ![redactor link plugin screenshot](https://simplicate.nyc3.digitaloceanspaces.com/simplicate/assets/site/images/redactor-link-styles.png) 6 | 7 | This is an early draft of the plugin and any bug reports would be appreciated. 8 | 9 | ## Installation 10 | 11 | If you're using Craft CMS, copy the file `src/linkclass.js` from this repository into your `cms/config/redactor/plugins` directory. 12 | 13 | 14 | ## Configuration 15 | 16 | You can configure the available link styles within your redactor JSON config file: 17 | 18 | *Sample Redactor-Config.json* 19 | 20 | ``` 21 | ... 22 | "plugins": ["linkclass"], 23 | "linkClasses" : [ 24 | { "label": "Button (regular)", "class": "button" }, 25 | { "label": "Button (large)", "class": "button button--large" }, 26 | { "label": "Button (small)", "class": "button button--small" } 27 | ] 28 | ... 29 | ``` 30 | 31 | ## Styling links inside Redactor 32 | 33 | If you want your links class names to appear differently within the redactor editor, you'll need to inject some css into your admin panel. 34 | 35 | *Sample control-panel.css* 36 | 37 | ``` 38 | .input .redactor-styles a.button { 39 | display : inline-block; 40 | padding: 0.25em 0.5em; 41 | border: 2px solid #3397ff; 42 | } 43 | 44 | .input .redactor-styles a.button:hover { 45 | background: #3397ff; 46 | text-decoration: none; 47 | color: #fff; 48 | } 49 | ``` 50 | 51 | If you're using Craft CMS you could either use a plugin to inject this code into your admin panel, or you can create a module and load your own CSS file. 52 | 53 | Here are some resources that might be of assistance: 54 | 55 | - https://plugins.craftcms.com/cp-css 56 | - https://craftquest.io/livestreams/building-a-craft-module 57 | - https://craftcms.com/docs/3.x/extend/module-guide.html 58 | - https://pluginfactory.io/ 59 | 60 | If you're using Redactor in some other tool, you'll have to do your own digging to figure out how to add CSS in your editor. -------------------------------------------------------------------------------- /src/linkclass.js: -------------------------------------------------------------------------------- 1 | (function(t) { 2 | t.add('plugin', 'linkclass', { 3 | 4 | translations: { 5 | en: { 6 | linkStyle: 'Link Style', 7 | }, 8 | }, 9 | 10 | init: function(app) { 11 | this.app = app; 12 | this.lang = app.lang; 13 | this.toolbar = app.toolbar; 14 | this.selection = app.selection; 15 | this.opts = app.opts; 16 | this.selectedClass = ''; 17 | }, 18 | 19 | 20 | /** 21 | * listen for when the link module changes or inserts new links 22 | */ 23 | onlink: { 24 | 25 | // on 'changed' passes a regular browser DOM object 26 | changed: function(e) { 27 | if( this.opts.linkClasses ) { 28 | e[0].className = this.selectedClass 29 | } 30 | }, 31 | 32 | // but on 'inserted' passes a Redactor DOM object 33 | // https://imperavi.com/redactor/docs/api-services/dom/#s-dom 34 | inserted: function(e) { 35 | if( this.opts.linkClasses ) { 36 | var element = e.first() 37 | this.selectedClass.split(" ").forEach( function(className) { 38 | element.addClass(className); 39 | }); 40 | } 41 | } 42 | }, 43 | 44 | 45 | /** 46 | * listen for when the link modal opens 47 | */ 48 | onmodal: { 49 | link: { 50 | open: function (modal, form) { 51 | if( this.opts.linkClasses ) { 52 | this.$modal = modal; 53 | this.$form = form; 54 | this._setup(); 55 | this._startingClass() 56 | } 57 | } 58 | } 59 | }, 60 | 61 | 62 | /** 63 | * setup the class name '); 72 | var opt = t.dom(""); 73 | se.append(opt); 74 | 75 | this.opts.linkClasses.forEach(function(element) { 76 | opt = t.dom(``); 77 | se.append(opt); 78 | }); 79 | 80 | se.on("change", this._select.bind(this)); 81 | 82 | fi.append(lb).append(se); 83 | 84 | // try to place the field before the new tab target checkbox 85 | var $target = this.$form.find('div.form-item-target') 86 | if( $target ) { 87 | $target.before(fi) 88 | } else { 89 | this.$modal.getBody().children().first().append(fi); 90 | } 91 | } 92 | }, 93 | 94 | 95 | /** 96 | * set the class that the changes 111 | */ 112 | _select: function(i) { 113 | var data = this.$form.getData(); 114 | this.selectedClass = data.class ?? ''; 115 | }, 116 | 117 | 118 | /** 119 | * find the first currently selected link in the editor (if one exists). 120 | * useful for setting thje class name