Skip to content

Commit

Permalink
Properties plugin
Browse files Browse the repository at this point in the history
Added properties plugin from Redactor site. Also tided up the Readme.
Sort of address this issue:
#1
  • Loading branch information
Elliot Lewis committed Mar 8, 2016
1 parent 710c072 commit 0eadb26
Show file tree
Hide file tree
Showing 5 changed files with 306 additions and 7 deletions.
38 changes: 31 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ Useful Redactor plugins for Craft's richtext field

### Version History

1.1 : 16 February 2016
1.0 : 10 February 2016
* 1.2 : 8 March 2016
* 1.1 : 16 February 2016
* 1.0 : 10 February 2016

### Requirements

Expand All @@ -26,7 +27,7 @@ Once installed, in Craft go to `Settings > Plugins` and click the small cog or g

To use a plugin edit an existing config or create a new config json file as per Craft's [documentation](https://craftcms.com/docs/rich-text-fields#redactor-configs).

If you turn on all available plugins, an example config could be:
Turn on required plugins then an example config could be:

{
"plugins": ["scriptbuttons", "counter", "alignment"]
Expand All @@ -39,7 +40,8 @@ Available plugin are:
+ Superscript and Subscript
+ Word count
+ Alignment
+ Character Lmiter
+ Properties
+ Character Limiter
+ Custom plugin

#### Superscript and Subscript
Expand All @@ -48,17 +50,39 @@ Adds superscript and subscript buttons to the toolbar. In source, the text is su

![Image of Redactor with superscript](readme-images/superscript.png "Super!")

{
"plugins": ["scriptbuttons"]
}

#### Word / Character count

Adds a 'Word count' button to the toolbar. Overlay modal appears with word and character count.

![Image of Redactor with superscript](readme-images/count.png "Super!")
![Image of Redactor with superscript](readme-images/count.png "Word count")

{
"plugins": ["counter"]
}

#### Alignment

Adds an 'Alignment' button to the toolbar. Aligns text block by adding a class, `text-center` or `text-right`.

![Image of Redactor with superscript](readme-images/align.png "Super!")
![Image of Redactor with superscript](readme-images/align.png "Alignment")

{
"plugins": ["alignment"]
}

#### Properties

Assign an id or class to any block level tag. From the cursor position outwrds, finds the first block level item, eg. p, ul. and adds `id="xx" or class="xx"`. Use the HTML source plugin to view code to see this in action.

![Image of Redactor with properties modal](readme-images/properties.png "Properties")

{
"plugins": ["properties"]
}

#### Character Lmiter

Expand All @@ -71,4 +95,4 @@ Limits the number of character in the rich text field to the value definied in <

### Your own custom plugin

There's also the option to create your own Redactor plugin and link to the JS and CSS files. Just fill-in the paths in settings under, 'Custom plugin'.
There's also the option to create your own Redactor plugin and link to the JS and CSS files. Just fill-in the paths in settings under, 'Custom plugin'. The plugin code needs to follow the Craft way of wrapping/loading the JS. Check the included Redactor plugins as an example.
Binary file added readme-images/properties.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions redactorextras/redactorExtrasPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ protected function defineSettings()
'alignment' => array(
AttributeType::Bool, 'default' => false
),
'properties' => array(
AttributeType::Bool, 'default' => false
),
'limiter' => array(
AttributeType::Bool, 'default' => false
),
Expand Down Expand Up @@ -89,6 +92,11 @@ public function init()
craft()->templates->includeJsResource('redactorextras/plugins/limiter.js');
}

if($settings->properties === "1")
{
craft()->templates->includeJsResource('redactorextras/plugins/properties.js');
}

if($settings->extraPluginJs != "")
{
craft()->templates->includeJsFile($settings->extraPluginJs);
Expand Down
258 changes: 258 additions & 0 deletions redactorextras/resources/plugins/properties.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
// Assign an id or class to any block level tag
// Adapted from offical Redactor site
// https://imperavi.com/redactor/plugins/properties/

if (!RedactorPlugins) var RedactorPlugins = {};

RedactorPlugins.properties = function()
{
return {
langs: {
en: {
"properties": "Properties"
}
},
block: false,
labelStyle: {
'position': 'absolute',
'padding': '2px 5px',
'line-height': 1,
'border-radius': '5px',
'font-size': '10px',
'color': 'rgba(255, 255, 255, .9)',
'z-index': 99
},
getTemplate: function()
{
return String()
+ '<div class="modal-section" id="redactor-modal-properties">'
+ '<section>'
+ '<label id="modal-properties-id-label">Id</label>'
+ '<input type="text" id="modal-properties-id" />'
+ '</section>'
+ '<section>'
+ '<label id="modal-properties-class-label">Class</label>'
+ '<input type="text" id="modal-properties-class" />'
+ '</section>'
+ '<section>'
+ '<button id="redactor-modal-button-action">Save</button>'
+ '<button id="redactor-modal-button-cancel">Cancel</button>'
+ '</section>'
+ '</div>';
},
setup: function()
{
this.opts.properties = (typeof this.opts.properties === 'undefined') ? {} : this.opts.properties;
this.opts.properties.id = (typeof this.opts.properties.id === 'undefined') ? true : this.opts.properties.id;
this.opts.properties.classname = (typeof this.opts.properties.classname === 'undefined') ? true : this.opts.properties.classname;
this.opts.properties.show = (typeof this.opts.properties.show === 'undefined') ? false : this.opts.properties.show;

},
init: function()
{
if (this.opts.type === 'pre' || this.opts.type === 'inline')
{
return;
}

this.properties.setup();

this.properties.createLabelId(this.properties.labelStyle);
this.properties.createLabelClass(this.properties.labelStyle);

this.properties.setEvents();

var button = this.button.add('properties', this.lang.get('properties'));
this.button.addCallback(button, this.properties.show);

},
show: function()
{
this.modal.addTemplate('properties', this.properties.getTemplate());
this.modal.load('properties', 'Properties', 600);

var button = this.modal.getActionButton().text('Save');
button.on('click', this.properties.save);

this.properties.showId();
this.properties.showClass();

this.modal.show();

},
createLabelId: function(css)
{
if (!this.opts.properties.show && !this.opts.properties.id)
{
return;
}

this.properties.labelId = $('<span />').attr('id', 'redactor-properties-label-id-' + this.uuid).attr('title', 'ID').hide();
this.properties.labelId.css(css).css('background', 'rgba(229, 57, 143, .7)');
$('body').append(this.properties.labelId);

},
createLabelClass: function(css)
{
if (!this.opts.properties.show && !this.opts.properties.classname)
{
return;
}

this.properties.labelClass = $('<span />').attr('id', 'redactor-properties-label-class-' + this.uuid).attr('title', 'class').hide();
this.properties.labelClass.css(css).css('background', 'rgba(61, 121, 242, .7)');
$('body').append(this.properties.labelClass);

},
setEvents: function()
{
this.core.element().on('click.callback.redactor', this.properties.showOnClick);
$(document).on('mousedown.redactor-properties', $.proxy(this.properties.hideOnBlur, this));

this.core.element().on('destroy.callback.redactor', $.proxy(function()
{
$(document).off('.redactor-properties');

}, this));
},
showId: function()
{
if (this.opts.properties.id)
{
$('#modal-properties-id-label').show();
$('#modal-properties-id').show().val($(this.properties.block).attr('id'));
}
else
{
$('#modal-properties-id, #modal-properties-id-label').hide();
}
},
showClass: function()
{
if (this.opts.properties.classname)
{
$('#modal-properties-class-label').show();
$('#modal-properties-class').show().val($(this.properties.block).attr('class'));
}
else
{
$('#modal-properties-class, #modal-properties-class-label').hide();
}
},
save: function()
{
// id
if (this.opts.properties.id)
{
var id = $('#modal-properties-id').val();
if (typeof id === 'undefined' || id === '')
{
this.block.removeAttr('id', this.properties.block);
}
else
{
this.block.replaceAttr('id', id, this.properties.block);
}
}

// class
if (this.opts.properties.classname)
{
var classname = $('#modal-properties-class').val();
if (typeof classname === 'undefined' || classname === '')
{
this.block.removeAttr('class', this.properties.block);
}
else
{
this.block.replaceClass(classname, this.properties.block);
}
}

this.modal.close();
this.properties.showOnClick(false);

},
showOnClick: function(e)
{
if (e !== false)
{
e.preventDefault();
}

var zindex = (typeof this.fullscreen !== 'undefined' && this.fullscreen.isOpen) ? 1052 : 99;

this.properties.block = this.selection.block();
if (!this.properties.block || !this.utils.isRedactorParent(this.properties.block) || this.utils.isCurrentOrParent(['figure', 'li']))
{
return;
}

var pos = $(this.properties.block).offset();

var classname = this.properties.showOnClickClass(pos, zindex);
this.properties.showOnClickId(pos, zindex, classname);

},
showOnClickId: function(pos, zindex, classname)
{
var id = $(this.properties.block).attr('id');
if (this.opts.properties.show && this.opts.properties.id && typeof id !== 'undefined' && id !== '')
{
setTimeout($.proxy(function()
{
var width = (this.opts.properties.classname && typeof classname !== 'undefined' && classname !== '') ? this.properties.labelClass.innerWidth() : -3;
this.properties.labelId.css({

zIndex: zindex,
top: pos.top - 13,
left: pos.left + width

}).show().text('#' + id);

}, this), 10);
}
},
showOnClickClass: function(pos, zindex)
{
var classname = $(this.properties.block).attr('class');
if (this.opts.properties.show && this.opts.properties.classname && typeof classname !== 'undefined' && classname !== '')
{
this.properties.labelClass.css({

zIndex: zindex,
top: pos.top - 13,
left: pos.left - 3

}).show().text(classname);
}

return classname;
},
hideOnBlur: function(e)
{
if (e.target === this.properties.block)
{
return;
}

this.properties.hideOnBlurId();
this.properties.hideOnBlurClass();

},
hideOnBlurId: function()
{
if (this.opts.properties.show && this.opts.properties.id)
{
this.properties.labelId.css('z-index', 99).hide();
}
},
hideOnBlurClass: function()
{
if (this.opts.properties.show && this.opts.properties.classname)
{
this.properties.labelClass.css('z-index', 99).hide();
}
}
};
};
9 changes: 9 additions & 0 deletions redactorextras/templates/_settings.html
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,15 @@ <h2>Extra plugins</h2>
errors: settings.getErrors('alignment')
}) }}

{{ forms.lightswitchField({
label: "Properties"|t,
id: "properties",
name: "properties",
instructions: "Assign an id or class to any block level tag. <code class=\"inlinecode\">'properties'</code>"|t,
on: settings.properties,
errors: settings.getErrors('properties')
}) }}

{{ forms.lightswitchField({
label: "Character limit"|t,
id: "limiter",
Expand Down

0 comments on commit 0eadb26

Please sign in to comment.