问题
I created a widget inside my custom module. Everything is working and the widget can be embedded onto CMS pages. However, instead of a textarea parameter type I want to add a WYSIWYG editor.
This is the significant part in my widget.xml:
<parameters>
<description translate="label">
<required>0</required>
<visible>1</visible>
<label>Description</label>
<type>textarea</type>
</description>
</parameters>
I wonder if there's a way to extend Magento's functionality to allow a WYSIWYG editor similar to this:
<parameters>
<description translate="label">
<required>0</required>
<visible>1</visible>
<label>Description</label>
<type>WYSIWYG</type>
</description>
</parameters>
Has anybody encountered a similar problem? .. or does anyone know how this could be achieved? Maybe through a custom renderer, which calls the WYSIWYG editor, but how..?
Thanx in advance.
回答1:
I finally managed to do it myself. For all those who have the same problem, this is how I did it:
In the widget.xml I have the parameter set as follows:
<parameters>
<text translate="label">
<required>1</required>
<visible>1</visible>
<label>Specify text</label>
<description>No double quotes allowed, use single quotes instead!</description>
<type>cmswidget/widget_wysiwyg</type>
</text>
</parameters>
To enable the WYSIWYG editor on the widget's textarea, I created a new block class in my custom module, extended the class Mage_Adminhtml_Block_Widget_Form_Renderer_Fieldset_Element and overwrote the render() function:
class MyCompany_MyModule_Block_Widget_Wysiwyg extends Mage_Adminhtml_Block_Widget_Form_Renderer_Fieldset_Element
{
public function render(Varien_Data_Form_Element_Abstract $element)
{
$editor = new Varien_Data_Form_Element_Editor($element->getData());
$editor->setId($element->getId());
$editor->setForm($element->getForm());
$editor->setWysiwyg(true);
$editor->setForceLoad(true);
return parent::render($editor);
}
}
Now, I was happy to see the editor inside the widget. Unfortunately there was still a problem. Since the editor creates inline styles and attributes with double quotes and places it to the CMS page as an widget attribut - which itself is also in double quotes, the widget cannot be rendered correctly. To solve this issue I extended the class Mage_Widget_Model_Widget and replaced the editors double quotes with single quotes as follows:
class MyCompany_MyModule_Model_Widget extends Mage_Widget_Model_Widget
{
public function getWidgetDeclaration($type, $params = array(), $asIs = true)
{
if( preg_match('~(^mymodule/myblockclass)~', $type) )
{
$params['text'] = str_replace('"', "'", $params['text']);
}
return parent::getWidgetDeclaration($type, $params, $asIs);
}
}
Inside getWidgetDeclaration() function I check if the widget type is the one I want to handle. The widget type is specified in the widget.xml for each widget like here:
<MyCompany_MyModule_MyWidgetName type="mymodule/myblockclass" translate="name description" module="mymodule">
<!-- ... -->
</MyCompany_MyModule_MyWidgetName>
And now I got everything working like I wanted it to be. The editor's generated HTML will have its double quotes replaced by single quotes and the output will work perfectly. Before I escaped the double quotes like this - \"some text \". That seemed to work at first, but when editing the widget by clicking on the icon (Editor view) the html was cut off. Magento's javascript seemed to escape the strings in its own way. However, the method described above will work as I just replace double quotes by single quotes when the widget is being inserted and Magento turns the single quotes into double quotes when opening the widget in CMS Editor view.
Hope this is useful for somebody.
回答2:
I don't think this is compatible with Magento 1.9 anymore. I've tried this method and I keep getting a javascript error when saving the cms block / page where the widget is added
error: error in [unknown object].fireEvent(): event name: formSubmit error message: Cannot set property 'value' of null
回答3:
Based on Rouzbeh I added small jQuery code that validate if double quotes are used:
<description>
<![CDATA[
<script>
jQuery("#widget_options textarea").keyup(function(){
if(jQuery(this).val().indexOf('"') > -1){
jQuery(this).val(jQuery(this).val().replace('"',"'"));
alert('No double quotes allowed, use single quotes instead.')
}
});
</script>
]]>
</description>
回答4:
So,the known solutions no longer seem to work on 1.9+, so I produced an alternative, which adds WYSIWYG, but using an alternative editor.
I used this editor:
https://alex-d.github.io/Trumbowyg/
with the end result looking as such:
STEP 1: Download the editor files and pace in adminhtml skin area:
In my example I had placed them in skin/adminhtml/default/js/wysiwyg
STEP 2: In your module, you need to define an admin layout update, and in your adminhtml layout file, add the directives to load the library files (and jquery)
Since I wanted this to appear only n CMS Page edits, I added via the appropriate handle:
<adminhtml_cms_page_edit>
<reference name="head">
<action method="addJs">
<script>lib/jquery/jquery-1.12.0.js</script>
</action>
<action method="addJs">
<script>lib/jquery/noconflict.js</script>
</action>
<action method="addItem"><type>skin_js</type><name>js/wysiwyg/trumbowyg.min.js</name></action>
<action method="addItem"><type>skin_css</type><name>js/wysiwyg/ui/trumbowyg.min.css</name></action>
</reference>
</adminhtml_cms_page_edit>
STEP 3: Create a new widget class to render the element:
In my example, I placed this is a module under the BLOCKS
Basically, this takes the widget xml defined element, and transposes it over to a textarea
element, and then attaches the needed javascript (jquery) to initialise the wysiwyg editor.
You will see thw options being passed to the editor, defined in $options
<?php
class ProxiBlue_Landingpage_Block_Widgets_Wysiwyg extends Mage_Adminhtml_Block_Widget_Form_Renderer_Fieldset_Element
{
public function render(Varien_Data_Form_Element_Abstract $element)
{
$textarea = new Varien_Data_Form_Element_Textarea();
$textarea->setForm($element->getForm())
->setId($element->getHtmlId())
->setName($element->getName())
->setLabel($element->getLabel())
->setClass('widget-option input-area input-text');
if ($element->getRequired()) {
$textarea->addClass('required-entry');
}
if ($element->getValue()) {
$textarea->setValue($element->getValue());
}
$options = "btns: ['viewHTML', 'strong', 'em', 'del', 'undo', 'redo', 'formatting', 'superscript', 'subscript', 'justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull', 'unorderedList', 'orderedList', 'horizontalRule', 'fullscreen'],
semantic: true,
removeformatPasted: true,
autogrow: false";
$textarea->setData('after_element_html',
"<script>jQuery(document).ready(
function() {
jQuery(" . $element->getHtmlId() .").trumbowyg({ " . $options . " })
.on('tbwblur', function(){
var html = jQuery(this).trumbowyg('html');
html = html.replace(/\"/g, '"');
jQuery(this).trumbowyg('html', html);
});
});</script>");
$html = parent::render($textarea);
return $html;
}
}
In there you may also note this snippet:
.on('tbwblur', function(){
var html = jQuery(this).trumbowyg('html');
html = html.replace(/\"/g, '"');
jQuery(this).trumbowyg('html', html);
});
The purpose here is to changed any double quotes (") to the proper html entity of "
This is to prevent the storing of the textual data, in the widget params, which is encased with double quotes.
Step 4: Define the widget element:
<text_blurb translate="label">
<sort_order>50</sort_order>
<label>Textual Content</label>
<visible>1</visible>
<required>1</required>
<type>landingpage/widgets_wysiwyg</type>
</text_blurb>
Done.
Hope this is of use to someone.
来源:https://stackoverflow.com/questions/15767894/magento-add-wysiwyg-editor-to-custom-widget