Using FCKeditor and Image Assist from Drupal

Published
2009-05-13 14:47
Written by
Firstly, congratulations all the book sprinters. You did well. I'll be having a good read of it this weekend. Before I delve into some code I'd like to give you my motivation for doing what I'm about to describe. I need image uploading, ease of use and consistency. I also don't want to bother with maintaining 2 versions of fckeditor. I knew it shouldn't be too hard to get it working across to 2 systems and to be honest it wasn't. It took a little more to find out what the Image assist module needed though. A nice feature of fckeditor is that we get a nice button in the editor toolbar instead of the link below the textarea as it would normally be. To get fckeditor and image assist working in drupal together you will need to copy img_assist_fckeditor.js from fckeditor module folder into img_assist folder. If you get a white empty popup screen then you have missed this step out. On to some actual coding. Please make sure your drupal modules are all working before trying this for your own sanity's sake. Rather than giving you chunks to piece together, here are the highlights and you can see the rest in the patch below. I check for the Drupal userFramework and that it has fckeditor installed. We then alter the location of the fckeditor javascript files. Later on I add the location to the drupal fckeditor's config file: fckeditor.config.js I altered this config file a bit to have some control over the buttons when used in a CiviCRM context. Apart from setting a few more paths, that's all you need for fckeditor alone. To add the Image Assist capability I had to trick it a bit. The standard thing to do for civicrm and fckeditor is to have a hidden input in the form but I needed a hidden (display:none) textarea as part of the javascript checking makes sure the element exists and is hidden by the sylesheet. The only other thing is that cunningly hidden <a> tag. I had to do this because the href is read by the javscript of fckeditor's toolbar button and it also points the image assist's output to the correct editor window. Although I only did this today, I'm not sure why I added: $this->Config['TextareaID'] = $name; If someone finds out if it does anything in this situation then feel free to comment and I'll update if needed. Now all you need is the patch and my additions to the drupal config file.
Patch for civicrm/packages/HTML/QuickForm/fckeditor.php
Index: fckeditor.php
===================================================================
--- fckeditor.php	(revision 990)
+++ fckeditor.php	(revision 1494)
@@ -187,33 +188,75 @@
             if (!defined('HTML_QUICKFORM_FCKEDITOR_LOADED')) {                
                 // load FCKeditor
                 $config = CRM_Core_Config::singleton( );
-                $html  = sprintf(
-                    '<script type="text/javascript" src="%s"></script>',
-                    $config->resourceBase . $this->BasePath . 'fckeditor.js'
-                );                
+                if($config->userFramework == 'Drupal' && module_exists('fckeditor')) {
+                   	$html  = sprintf(
+	                    '<script type="text/javascript" src="%s"></script>',
+	                    drupal_get_path('module', 'fckeditor') . '/fckeditor/fckeditor.js');
+                } else {
+	                $html  = sprintf(
+	                    '<script type="text/javascript" src="%s"></script>',
+	                    $config->resourceBase . $this->BasePath . 'fckeditor.js'
+	                );      
+                }          
                 define('HTML_QUICKFORM_FCKEDITOR_LOADED', true);
             }
-
-            $config =& CRM_Core_Config::singleton();
-
-            // make link for iframe src
-            $link = $config->resourceBase . $this->BasePath . 'editor/fckeditor.html?InstanceName=' . $name;
-
-            if (strlen($this->ToolbarSet)) {
-                $link .= '&amp;Toolbar=' . $this->ToolbarSet;
+			$config =& CRM_Core_Config::singleton();
+			
+			if($config->userFramework == 'Drupal' && module_exists('fckeditor')) {
+				global $base_url;
+				$fckPath = drupal_get_path('module', 'fckeditor');
+				// make link for iframe src
+	            $link = '/' . $fckPath . '/fckeditor/editor/fckeditor.html?InstanceName=' . $name;
+	            
+	            if(module_exists('img_assist')) {
+	            	drupal_add_js(drupal_get_path('module', 'img_assist') .'/img_assist.js');
+	            	
+	            	drupal_add_js($fckPath .'/fckeditor/fckeditor.js');
+	            	drupal_add_js($fckPath .'/fckeditor.utils.js');
+	            	$html .= sprintf('<a href="%s" id="%s" style="display: none;"
+	            	/>Add Image</a>',
+	                             htmlspecialchars($base_url . '/img_assist/load/fckeditor?textarea=' . $name),
+	                             'img_assist-link-' . $name, $name);
+	                 $this->Config['TextareaID'] = $name;
+	            }
+	            
+	            $link .= '&amp;Toolbar=' . 'DrupalCiviCRM';
+	            
+	            // render the linked hidden field
+	            $html .= sprintf('<input type="textarea" id="%s" name="%s" value="%s" style="display: none;"/>',
+	                             $name, $name, htmlspecialchars($this->getValue()));
+	            
+	            $this->Config['CustomConfigurationsPath'] = '/' . $fckPath . '/fckeditor.config.js';
+	            // render the config hidden field
+	            $html .= sprintf('<input type="hidden" id="%s" name="%s" value="%s" />',
+	                             $cname, $cname, $this->_getConfigFieldString());
+	             // render the editor iframe
+	            $html .= sprintf(
+	                '<iframe id="%s" src="%s" width="%s" height="%s" framborder="no" scrolling="no"></iframe>',
+	                $name . '___Frame', $link, $this->Width, $this->Height
+	            );
+			
+			} else {
+	
+	            // make link for iframe src
+	            $link = $config->resourceBase . $this->BasePath . 'editor/fckeditor.html?InstanceName=' . $name;
+	
+	            if (strlen($this->ToolbarSet)) {
+	                $link .= '&amp;Toolbar=' . $this->ToolbarSet;
+	            }
+	
+	            // render the linked hidden field
+	            $html .= sprintf('<input type="hidden" id="%s" name="%s" value="%s" />',
+	                             $name, $name, htmlspecialchars($this->getValue()));
+	            // render the config hidden field
+	            $html .= sprintf('<input type="hidden" id="%s" name="%s" value="%s" />',
+	                             $cname, $cname, $this->_getConfigFieldString());
+	             // render the editor iframe
+	            $html .= sprintf(
+	                '<iframe id="%s" src="%s" width="%s" height="%s" framborder="no" scrolling="no"></iframe>',
+	                $name . '___Frame', $link, $this->Width, $this->Height
+	            );
             }
-
-            // render the linked hidden field
-            $html .= sprintf('<input type="hidden" id="%s" name="%s" value="%s" />',
-                             $name, $name, htmlspecialchars($this->getValue()));
-            // render the config hidden field
-            $html .= sprintf('<input type="hidden" id="%s" name="%s" value="%s" />',
-                             $cname, $cname, $this->_getConfigFieldString());
-             // render the editor iframe
-            $html .= sprintf(
-                '<iframe id="%s" src="%s" width="%s" height="%s" framborder="no" scrolling="no"></iframe>',
-                $name . '___Frame', $link, $this->Width, $this->Height
-            );
             return $html;
         }
     }
Additions to drupal's modules/fckeditor/fckeditor.config.js
//This toolbar should work fine with "Filtered HTML" filter
FCKConfig.ToolbarSets["DrupalCiviCRM"] = [
['Source'],
['Cut','Copy','Paste','PasteText','PasteWord'],
['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],
/*
 * EXPERIMENTAL
 * Uncomment the line below to enable linktonode and linktomenu buttons
 * ATTENTION: Link to Content module must be installed first!
 * Remember to load appropriate plugins with FCKConfig.Plugins.Add command a couple of lines above
 */
//['Link','Unlink','LinkToNode','LinkToMenu','Anchor'],
['Link','Unlink','Anchor'],
['Image','Flash','Table','Rule','Smiley','SpecialChar'],
'/',
['FontFormat'],
['Bold','Italic','Underline','StrikeThrough','-','Subscript','Superscript'],
['OrderedList','UnorderedList','-','Outdent','Indent'],
//as of FCKeditor 2.5 you can use also 'Blockquote' button
//['OrderedList','UnorderedList','-','Outdent','Indent','Blockquote'],
['JustifyLeft','JustifyCenter','JustifyRight'],
//uncomment this line to enable the page break button
//remember to load appropriate plugin with FCKConfig.Plugins.Add command a couple of lines above
//['JustifyLeft','JustifyCenter','JustifyRight','DrupalBreak','DrupalPageBreak'],
] ;
And that's it. Please let me know what you think. The diff was run directly against the file in question and not from the civicrm installation root.
Filed under

Comments

http://drupal.org/node/35728
I'm still waiting for some support, but you might find some luck there.
Also, look at the Advanced Profile Kit drupal module. It does work, after some configuration. It's based on Content export and panels.

brandcannon (not verified)
2009-06-22 - 23:12

Replace the block from above:

+ if(module_exists('img_assist')) {
+ drupal_add_js(drupal_get_path('module', 'img_assist') .'/img_assist.js');
+
+ drupal_add_js($fckPath .'/fckeditor/fckeditor.js');
+ drupal_add_js($fckPath .'/fckeditor.utils.js');
+ $html .= sprintf('Add Image',
+ htmlspecialchars($base_url . '/img_assist/load/fckeditor?textarea=' . $name),
+ 'img_assist-link-' . $name, $name);
+ $this->Config['TextareaID'] = $name;
+ }

With:

if(module_exists('imce')) {
$this->Config['LinkBrowserURL'] = urlencode($base_url . "/?q=imce&app=FCKEditor|url@txtUrl");
$this->Config['ImageBrowserURL'] = urlencode($base_url .
"?q=imce&app=FCKEditor|url@txtUrl|width@txtWidth|height@txtHeight");
$this->Config['FlashBrowserURL'] = urlencode($base_url . "/?q=imce&app=FCKEditor|url@txtUrl");
}