I am trying to use the Code Filter to highlight PHP code with rich text is enabled in CKEditor.

I toggle off rich text, put in the PHP code

<?php
print "Hello, world!";
?>

and wrap it in between the < code > tags.
It works - after submit the code is nicely highlighted.

However, when I then edit the page, with rich text enabled in CKEditor, the code is not visible at all.
When I toggle off rich text, I see that the code has changed as follows:

<!--?php
print "Hello, world!";
?-->

FYI:

  • Code Filter is the first filter that runs.
  • I've battled with this in 6.x-2.4, now tried also in latest 6.x-2.x-dev, but the issue has not gone away.

Ideas?

Comments

Version:7.x-2.x-dev» 6.x-2.x-dev
Status:Closed (duplicate)» Active

This happens because CKEditor does not escape PHP code or the code tags by default. There's currently no easy way for Wysiwyg to pass the required setting to CKEditor because it needs to be in the form of a regular expression, which is a datatype not supported by JSON.

There is a way around it though, by making Wysiwyg tell CKEditor to also load a custom configuration file, in which this regular expression can be defined.

You'll need to create a small Drupal module, like so:

sites/all/modules/cke_php/cke_php.info

name = CKEditor settings override
description = Makes CKEditor load a custom  config file via Wysiwyg module
dependencies[] = wysiwyg
core = 6.x

Change core = 6.x to core = 7.x if you are using D7.

sites/all/modules/cke_php/cke_php.module

<?php
/**
* Implements hook_wysiwyg_editor_settings_alter().
*/
function cke_php_wysiwyg_editor_settings_alter(&$settings, $context) {
  if (
$context['profile']->editor == 'ckeditor') {
   
$settings['customConfig'] = base_path() . drupal_get_path('module', 'cke_php') . '/ckeditor.config.js';
  }
}
?>

sites/all/modules/cke_php/ckeditor.config.js
CKEDITOR.editorConfig = function(config) {
  config.protectedSource.push(/<\?[\s\S]*?\?>/g); // PHP Code
  config.protectedSource.push(/<code>[\s\S]*?<\/code>/gi); // Code tags
}

More details about these settings can be found in the CKEditor config docs.

Enable the module and CKEditor should now pick up the new config file, along with the protectedSource settings.
I wrote this out of memory, so there might be typos etc.

UPDATE: Disable the Teaser Break plugin. It will turn the PHP tag into an HTML comment. Follow #510552: Invalid XHTML: missing trailing slashes, absolute urls and uppercase tags to know when this no longer happens.

Btw, it won't matter which filters are running on the server, the clientside editors have no connection to them.

Thanks, Henrik, it seems to make sense.

However, clearly very few Drupal users will create a custom module just to be able to escape PHP code in CKEditor under Wysiwyg.
That said, wouldn't it be more straightforward to include your code in Wysiwyg module itself, loading conditionally if CKEditor is being used?

Ideally, I'd like to be able to add escape-patterns like the ones above directly in the GUI, but we can't pass regular expressions via JSON, and we don't have the ability to customize the editor profile GUI for each editor yet. (It's options/widgets match those that were supported when this module only worked with TinyMCE, which is less than ideal for other editors.) I am putting as much time as I can into solving #313497: Allow configuration of advanced editor settings, which isn't much at this point but I am nearing a usable patch. That patch will allow full GUI/form customization per editor [and its plugins], as well as better handling of regular expressions and callbacks as setting values.

In essence, I'd like to hit the root cause of these custom-settings-problems with the biggest sledge I've got, instead of poking at it one setting at a time.

In the mean time, #1 works very well.

i've the same trouble...wysiwyg seem to replace <? by <!--? , trying differents editors tinymce, ckeditor ; same issue...if i do that disabling editor => no change...so how can i add php code with wysiwyg ?

go to try codeprotect plugin for tinymce...but how to add plugin to tinymce via wysiwyg ?

Version:7.x-2.x-dev» 6.x-2.x-dev
Status:Postponed (maintainer needs more info)» Active

@aiphes, note that it's not Wysiwyg itself which turns PHP tags into comments but the editors. This is because most editors are not designed to handle PHP (it's not very WYSIWYG-like by nature).

If the editors have settings you can change or plugins to activate to work around some problems with PHP tags in content, you can create a small Drupal module to do this. In the case of CKEditor, create a small Drupal module by following the instructions in #1.

For TinyMCE, we need to implement another hook as the code we need lives in a separate plugin. There is no need to modify any of TinyMCE's or Wysiwyg's files for this. Instead, create these files:

sites/all/modules/tinymce_cp/tinymce_cp.info

name = TinyMCE CodeProtect plugin
description = A wrapper for using the TinyMCE CodeProtect plugin via Wysiwyg module
core = 6.x
dependencies[] = wysiwyg

Note: Change 6.x to 7.x if you're using Drupal 7.

sites/all/modules/tinymce_cp/tinymce_cp.module

<?php
function tinymce_cp_wysiwyg_plugin($editor, $version) {
 
$plugins = array();
  switch (
$editor) {
    case
'tinymce':
      if (
$version > 3) {
       
$plugins['codeprotect'] = array(
         
'title' => t('CodeProtect'),
         
'url' => 'http://sourceforge.net/tracker/?func=detail&aid=2859676&group_id=103281&atid=738747',
         
'buttons' => array(
           
'codeprotect' => t('CodeProtect'),
          ),
         
'load' => TRUE,
         
'internal' => TRUE,
        );
      }
  }
  return
$plugins;
}
?>

Extract all the plugin files from http://sourceforge.net/tracker/?func=detail&aid=2859676&group_id=103281&... to sites/all/libraries/tinymce/jscripts/tiny_mce/plugins/codeprotect.

Enable the new "TinyMCE CodeProtect plugin" module in Drupal as usual. You might need to clear the Drupal caches.

Go to the Wysiwyg settings and enable the new "CodeProtect" button for the editor profile you need it in.

Note: Disable the Teaser Break plugin, it converts the contents to a DOM tree and back to a string to do its thing, in this process the browser will most likely change your PHP tags to HTML comments. Follow #510552: Invalid XHTML: missing trailing slashes, absolute urls and uppercase tags to know when that is fixed and Teaser Break will no longer do this.

thanks
if i enable this custom module + tinymce.inc modified => editor disappear

so i think i must choose between these solutions...yours seem to be better,so i will test it later and give you results

Version:6.x-2.x-dev» 7.x-2.x-dev

hi there -- @TwoD, i tried implementing the wee module you suggested but i'm still not able to escape the "!--" from php tags in my wysiwyg (using ckeditor) with either rich text enabled or disabled... am i missing something? i'm trying to use a php function, views_embed_view(), to embed a view inline within the body of a node that will have content above and below the view input by the wysiwyg...

Did you use the three files from #1?

Do you have the Teaser Break module enabled? If so, try disabling it. The contents are passed to it after they've been fetched from CKEditor. It is known to mess up some markup, especially if used in IE. Plugins provided by other Drupal modules may also have this effect, so try disabling them all and see if php tags stays escaped when saving the node.

hi - thanks for your quick reply -- i'm just now getting back to this issue which i'm still having -- still using your 3 files from #1 -- i disabled Teaser Break but still can't get the php to read properly -- i have a million modules installed -- not sure i can isolate this issue by disabling them one by one... if you have any other thoughts or suggestions, i am much obliged...

Status:Active» Postponed (maintainer needs more info)

Could you provide a simple sample of what the markup you want should look like, and what it actually looks like after you've put it in the editor and clicked "Disable rich-text"?

hi again -- if you go look at http://www.msbstore.org/drupal/TheLINK and scroll down a little ways, you'll see the php block code doing nothing -- it's a simple view embed -- if i disable rich-text the page breaks out of its template and it still doesn't read the php -- what am i doing wrong?

Status:Closed (duplicate)» Postponed (maintainer needs more info)

@aiphes, I've updated #6 with more accurate instructions on how to make the TinyMCE plugin work. You must move it to TinyMCE's internal plugins folder and change the module code to reflect that (set 'internal' => TRUE;). The plugin has hardcoded paths to some of TinyMCE's own files inside its popup code, making it difficult to use from another folder.

Also disable the Teaser Break plugin, since it passes the content through the browsers functions, which makes it change the PHP tags into comments.

Version:6.x-2.x-dev» 7.x-2.x-dev
Status:Active» Closed (duplicate)

I'll close this as a duplicate of #525776: Add support for (keeping) PHP code in HTML editors, please follow that issue for updates and info on if Wysiwyg will support this on its own.

but i'm using CKEditor -- and your files from #1, not TinyMCE... and teaser break plugin is disabled... does your module only work when rich-text is disabled? because disabling rich-text ruins the template, not to mention that even when i do disable rich-text, the page still doesn't render the php code...

@TwoD : thanks for advise , i go to change the plugins of Tinymce and see if php work as desired
EDIT: finally choosing the codeprotect plugin in buttons after enabling custom module break editor display,if uncheck the button plugin, editor appear...
wrong path in codeprotect folder...now it's ok

Status:Postponed (maintainer needs more info)» Closed (duplicate)

@zopa, I'm sorry, that was meant for @aiphes. I've corrected the post and I have updated #1 as well. The code for CKEditor was missing a call to base_path() so the custom config file didn't get loaded correctly, and the directive to escape PHP tags did not get into the editor.

Version:6.x-2.x-dev» 7.x-2.x-dev
Status:Active» Closed (duplicate)

@TwoD: thanks! base_path() was the missing link... here's another Q for you -- is it possible to use API functions and other PHP snippets within the wysiwyg? i want to embed a view using php but calling functions like views_get_view or views_embed_view from within the wysiwyg doesn't seem to be working...

I am the maintainer of Code Filter module. Thanks to TwoD's excellent instructions, I have created a module that implements the code in #1 for compatibility with CKEditor.

http://drupal.org/project/codefilter_wysiwyg

Give it a shot and see if it helps.

Module from #19 works also for CKEDITOR Version 4.0

I am using TinyMCE and #6 works for me. Thanks TwoD!!

#19 and codefilter_wysiwyg module works with Ckeditor 3.6.6.1, Thanks!

Hi,

I'm new to Drupal (longtime WordPress themer), and am struggling to get <code> tags working with Ckeditor and the WYWIWYG module. I'm making a tutorial website and need to be able to display HTML, CSS, JavaScript, PHP, etc on the front-end.

I've installed the Code Filter module, and the Code Filter WYSIWYG module, but things still get all screwed up - <ul> or <?php /* stuff */ ?> don't display properly. The front-end markup is all funky: the <code> tags don't contain the code, and the other tags aren't closed properly.

If anyone could help me on this I would be very grateful :-)