#! CRADDON 1
#! NAME GEA
#! VERSION 1.2
#! DESCRIPTION Generic Editor Adaptor
#! AUTHOR Jahandar
#! DOC 1
$GEA_Version = '1.2';
my $addon = new Addon('GEA');
$addon->checkBuild(30);
$addon->isPrivacyCompatible;
$addon->hook(CRHTMLHead_Head,GEA_Header);
# HOOK: GEA_Init1
if($Addons{'GEA_Init1'}){my $w;foreach $w (@{$Addons{'GEA_Init1'}}){my $addon=$w->[2];eval ${$w->[0]};AErr($addon,$@)if $@;};}
# Editor Settings
%GEA_editorSettings = ();
$GEA_editorSettings{'FieldName'} = ['Field Name', qq~This is the name of the textarea field element in your form.
This will almost always be 'Text'~,''];
$GEA_editorSettings{'Path'} = ['Path', qq~This is the path to the editor.
Example: /content/includes/editor/~,''];
$GEA_editorSettings{'XHTML'} = ['Generate XHTML?', qq~If your editor supports it, indicate whether XHTML should be enabled.~,'yn'];
$GEA_editorSettings{'Width'} = ['Editor Width',qq~Indicate the width of the editor.
Example: 600~,''];
$GEA_editorSettings{'Height'} = ['Editor Height',qq~Indicate the height of the editor.
Example: 200~,''];
$GEA_editorSettings{'ShowButtons'} = ['ShowButtons',qq~If your editor supports it, you can indicate whether buttons should be shown.~,'yn'];
$GEA_editorSettings{'ReadOnly'} = ['Read-Only Mode',qq~If your editor supports it, you can enable read-only mode.~,'yn'];
$GEA_editorSettings{'FullScreen'} = ['Full-Screen Mode',qq~If your editor supports it, indicate whether your editor should start in full-screen mode.~,'yn'];
$GEA_editorSettings{'NoNewLines'} = ['NoNewLines',qq~This is a GEA setting, not an editor setting. Indicate whether GEA should strip new line characters from a post\'s content before feeding it to the editor, used when modifying posts.~,'yn'];
$GEA_editorSettings{'CSSFile'} = ['Path to editor CSS File', qq~If your editor supports CSS files, indicate the path.
Example: /content/includes/editor/editor.css~,''];
$GEA_editorSettings{'CFGFile'} = ['Path to editor Configuration File', qq~If your editor uses a CFG file, indicate the path.
Example: /content/includes/editor/config.cfg~,''];
$GEA_editorSettings{'HeaderHTML'} = ['Header HTML', qq~This is the code that should go in the page header.
Example: <script type=\"text/javascript\" src=\"/content/includes/editor/editor.js\">~,qq~~];
$GEA_editorSettings{'InlineHTML'} = ['Inline HTML', qq~This is the code that goes in the body of the page to actually create the generate the editor. Here you can use [GEA: XXX] tags.~,qq~~];
$GEA_editorSettings{'editorInsertionFunction'} = ['Editor Insertion Function', qq~This line specifies the line used to write to the editor, most editors have a special function for this. This allows addons that normally wrote to the old plain-text textarea (like SelectPic and QuickTags) to write to your new editor if they have been updated to take advantage of GEA. Only give the member function/method, not the object and no arguments.
Example: For FCKeditor you type: FCKeditorAPI.GetInstance('[GEA: FieldName]').InsertHtml
Example: For RTE you type: currentRTE='[GEA: FieldName]';insertHTML
Notice the use of [GEA: FieldName]. GEA will automatically replace this with the field name value specified above.~,''];
# HOOK: GEA_Init2
if($Addons{'GEA_Init2'}){my $w;foreach $w (@{$Addons{'GEA_Init2'}}){my $addon=$w->[2];eval ${$w->[0]};AErr($addon,$@)if $@;};}
# Set the form actions
$Subs{DisplaySubForm} =~ s~(name="submitnews")~onSubmit="return submitForm();" $1~;
$Subs{ModifyNews_Edit} =~ s~(name="submitnews")~onSubmit="return submitForm();" $1~;
# HOOK: GEA_Init3
if($Addons{'GEA_Init3'}){my $w;foreach $w (@{$Addons{'GEA_Init3'}}){my $addon=$w->[2];eval ${$w->[0]};AErr($addon,$@)if $@;};}
# Get the User-Submitted codes for the editor
my $GEA_headerHTML = $CConfig{"GEA_HeaderHTML"};
my $GEA_inlineHTML = $CConfig{"GEA_InlineHTML"};
my $GEA_editorInsertionFunction = $CConfig{"GEA_editorInsertionFunction"};
# HOOK: GEA_Init4
if($Addons{'GEA_Init4'}){my $w;foreach $w (@{$Addons{'GEA_Init4'}}){my $addon=$w->[2];eval ${$w->[0]};AErr($addon,$@)if $@;};}
sub GEA_buildEditor
{
# HOOK: GEA_BuildEditor_Beginning
if($Addons{'GEA_BuildEditor_Beginning'}){my $w;foreach $w (@{$Addons{'GEA_BuildEditor_Beginning'}}){my $addon=$w->[2];eval ${$w->[0]};AErr($addon,$@)if $@;};}
# Get whatever content needs to be in the editor window
my $GEA_Content = $fieldDB{'Text'}->{'DefaultValue'} if ($in{'action'} eq "submit");
my $GEA_Content = ${'Text'} if ($in{'action'} eq "modify-edit");
# HOOK: GEA_BuildEditor_Formatting1
if($Addons{'GEA_BuildEditor_Formatting1'}){my $w;foreach $w (@{$Addons{'GEA_BuildEditor_Formatting1'}}){my $addon=$w->[2];eval ${$w->[0]};AErr($addon,$@)if $@;};}
# If the user wants new lines removed, do it
if ($CConfig{"GEA_NoNewLines"} eq 'true')
{ $GEA_Content =~ s/\n//gm;
}
# HOOK: GEA_BuildEditor_Formatting2
if($Addons{'GEA_BuildEditor_Formatting2'}){my $w;foreach $w (@{$Addons{'GEA_BuildEditor_Formatting2'}}){my $addon=$w->[2];eval ${$w->[0]};AErr($addon,$@)if $@;};}
# Escape all quotation marks (\") so they don't break the javascript
$GEA_Content =~ s/(['"])/\\$1/g; # ' # Closing the quote to prevent bad syntax coloring in TextPad
$GEA_Header =~ s/(['"])/\\$1/g; # ' # Closing the quote to prevent bad syntax coloring in TextPad
# HOOK: GEA_BuildEditor_Formatting3
if($Addons{'GEA_BuildEditor_Formatting3'}){my $w;foreach $w (@{$Addons{'GEA_BuildEditor_Formatting3'}}){my $addon=$w->[2];eval ${$w->[0]};AErr($addon,$@)if $@;};}
# Replace [GEA: XXX] Tags
$GEA_inlineHTML =~ s/\[GEA\: Content\]/\[GEACONTENT\]/g; # Placeholder so we can add the content last (for speed)
$GEA_inlineHTML =~ s/\[GEA\: (.*?)\]/$CConfig{"GEA_$1"}/g;
$GEA_inlineHTML =~ s/\[GEACONTENT\]/$GEA_Content/g;
$GEA_editorInsertionFunction =~ s/\[GEA\: (.*?)\]/$CConfig{"GEA_$1"}/g;
# HOOK: GEA_BuildEditor_Formatting4
if($Addons{'GEA_BuildEditor_Formatting4'}){my $w;foreach $w (@{$Addons{'GEA_BuildEditor_Formatting4'}}){my $addon=$w->[2];eval ${$w->[0]};AErr($addon,$@)if $@;};}
# Hook: GEA_BuildEditor_InsertContentJS
if($Addons{'GEA_BuildEditor_InsertContentJS'}){my $w;foreach $w (@{$Addons{'GEA_BuildEditor_InsertContentJS'}}){my $addon=$w->[2];eval ${$w->[0]};AErr($addon,$@)if $@;};}
my $GEA_insertContentJS = qq~
~;
# Hook: GEA_BuildEditor_End
if($Addons{'GEA_BuildEditor_End'}){my $w;foreach $w (@{$Addons{'GEA_BuildEditor_End'}}){my $addon=$w->[2];eval ${$w->[0]};AErr($addon,$@)if $@;};}
# Bring her on home
$fcode = qq~
\n\n$GEA_inlineHTML
\n\n$GEA_insertContentJS
\n\n
~;
}
sub GEA_Header
{ $GEA_headerHTML =~ s/\[GEA\: Path\]/$CConfig{"GEA_Path"}/g;
$GEA_headerHTML =~ s/\[GEA\: (.*?)\]/$CConfig{"GEA_$1"}/g;
print qq~\n\n$GEA_headerHTML\n\n~;
}
$GEA_Editor = <<'END CODE';
$fcode = GEA_buildEditor if ($fn eq 'Text')
END CODE
$addon->hook("DisplaySubForm_Fields",\$GEA_Editor);
$addon->hook("ModifyNews_Edit_Fields",\$GEA_Editor);
# Settings Interface
$addon->addAdvancedSettingHeading('Generic Editor Adaptor (GEA) Settings');
foreach $setting (keys %GEA_editorSettings)
{ $addon->addAdvancedSetting("GEA_$setting", $GEA_editorSettings{$setting}[0], $GEA_editorSettings{$setting}[1], $GEA_editorSettings{$setting}[2]);
}
1;
__END__
=head1 Generic Editor Adaptor
=head2 Description
This addon allows you to setup Coranto to work with most HTML editors, including RTE, Spaw, FCKeditor, htmlArea, etc.
=head2 Configuration
Read the documentation for the editor you wish to install. Most will have a line to go in the header and some code to go in the body. Get that information, then head to the GEA section of the Coranto configuration page.
Paste the header and body text into the fields where indicated. You'll notice a few other options are available, those are prefab options that I threw in and that are commonly used by editors. If you set one, you can use the value in your code body just as you do Coranto fields. Just add the text [GEA: FieldName] and the information will be added for you.
You can add additional fields and options, but at this point the only way to do this is to add a new line in the cra_GEA.pl file, but it isn't difficult. In the file you'll see an area labelled Editor Settings, just add a new line at the bottom in the following format:
$GEA_editorSettings{'SettingName'} = ['Setting Title', qq~Setting Description~,'custom html'];
At this point, addon developers will notice that this is the same syntax as $addon->addAdvancedSetting and question the redundancy. I did it this way with future developments in mind.
Anyway, now you'll be able to configure your new setting on the configuration page and call it using [GIA: XXX].
If you're lazy, or don't plan on changing much, you don't even have to worry about the [GIA: Tags], just toss the code in and you'll be set. The only tag you HAVE to use is the [GIA: Content] tag, which tells GIA where to put the content of a page when you're modifying posts.
One thing to watch out for, though, is many times in the documentation they don't tell you right away what you need to load content into the editor. This is important because you'll need it in order to modify posts, so make sure you get that information and include it in the inline code.
For instance, for FCKeditor, the line is: oFCKeditor.Value = "[GEA: Content]"; and you make sure to insert it right above the Create(); line.
Also, be sure to disable Convert Newlines for the news Text Field.
=head2 Field Tags
The following fields/settings are included automatically, you can always add more to suit your needs (see above).
Remember, you can insert the value of these using [GIA: XXXX]
FieldName, Path, XHTML, Width, Height, ShowButtons, ReadOnly, FullScreen, NoNewLines, CSSFile, CFGFile, HeaderHTML, InlineHTML
=head2 Expansion and Hooks
If you need more functionality, or if you just want to expand the possible uses for any editor in Coranto (for instance, using your editor to edit styles), you will be pleased to know that this addon was designed to be expansion-friendly and an ideal platform for future development. I've added hooks liberally, commented my code so you can tell what is happening, and wrote my code to be readable. You can create addons that expand GIA, without having to modify GEA itself.
=head2 The Future and License
Some possible expansions for GEA.
=item *
Editor Profiles, to switch between editor setups on the fly, or have different profiles for different editor uses (for instance, separate profiles for submitting and modifying posts)
=item *
Use editor elsewhere in Coranto.. (editing styles, for instance)
=item *
Parse editor config files, allow modification of editor CFG files through Coranto
If anyone wants to implement one of these expansions or some other, feel free. Because you can make GEA expansions as separate addons, you won't need permission to modify my code. For this reason I am not making cra_GIA.pl open source. I want to ensure future developments of GEA itself are made with maximum flexibility and in mind. However, I am open to modification if it can be justified that it is better than expansion through a new addon with GIA as a platform. An expansion could be added to the core GIA (or at least distributed with GIA) if it is suitable, the author of that expansion and I can work that out.
=head2 About
Author: Thomas Weber (Jahandar) www.Antarat.net
This addon is based on my cra_RTE addon, which does essentially the same thing, but your only choice of editor is RTE.
Note: While I tried to make this as generic as possible, and it should work for most editors (every one that I've ever looked at will work), if you happen to find an incompatibility with a certain editor, report it and I'll see what I can do.
Please report any bugs, suggestions, improvements, and such on the Coranto forum.