[Rt-commit] rt branch 5.0/add-richtext-customfields created. rt-5.0.2-61-gdcff44d8cd

BPS Git Server git at git.bestpractical.com
Tue Feb 15 19:58:43 UTC 2022


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "rt".

The branch, 5.0/add-richtext-customfields has been created
        at  dcff44d8cd5c03d6351874d5e6a28a29fb1273a3 (commit)

- Log -----------------------------------------------------------------
commit dcff44d8cd5c03d6351874d5e6a28a29fb1273a3
Author: Brian Conry <bconry at bestpractical.com>
Date:   Thu Feb 10 11:55:22 2022 -0600

    Add the Richtext CustomField type
    
    This custom field has HTML content and uses the same WYSIWYG editor
    that's used for rich text ticket updates.
    
    If used on an article, the article's class must allow HTML content or
    else the field's content will be treated the same as if the HTML had
    been put into a regular text custom field.
    
    Extracting an article from a ticket has been updated so that the ticket
    transaction content is displayed as HTML where available and imported
    into Richtext custom fields as Richtext after it passes through the
    standard HTML filtering used by RT.

diff --git a/docs/customizing/articles_introduction.pod b/docs/customizing/articles_introduction.pod
index 297ad2c8d6..80ee0d88f6 100644
--- a/docs/customizing/articles_introduction.pod
+++ b/docs/customizing/articles_introduction.pod
@@ -98,8 +98,9 @@ corner of RT's UI when working with tickets. When you click that
 button, RT will ask you which Class to create your new Article in.
 Once you click on a Class name, the Ticket's transactions will be
 displayed, along with a set of select boxes. For each transaction, you
-can pick which Custom Field that transaction should be extracted to.
-From there on in, it's just regular Article creation.
+can pick which Custom Field that transaction should be extracted to.  Note that
+ticket data is always extracted as plain text.  From there on in, it's just
+regular Article creation.
 
 =head2 Including an Article
 
@@ -114,6 +115,11 @@ automatically turns into a search box which allows you to type an
 article name. The search box will help you by auto-completing to
 matching articles as you type.
 
+On the Modify Class page there are options for controlling which custom fields
+are used when an article is included.  All custom fields are included by
+default.  There are also options for controlling the generation of header
+labels for the article and for each custom field.
+
 =head3 Disabling Escaped HTML
 
 By default, when an article is inserted into the ticket message box,
@@ -135,6 +141,9 @@ tags per article class. This can be done by unchecking the "Escape HTML"
 box on the Modify Class page. Please note this is potentially unsafe and
 its use should be limited to trusted administrators.
 
+The content of Richtext custom fields is stored as HTML and is subject to the
+same restrictions as HTML content in any other custom field.
+
 =head3 Disabling Ticket Linking
 
 When an article is included in a ticket's comment or reply, the article
diff --git a/docs/initialdata.pod b/docs/initialdata.pod
index def6dc0ab3..49c5d63c33 100644
--- a/docs/initialdata.pod
+++ b/docs/initialdata.pod
@@ -173,6 +173,7 @@ One of the following on the left hand side:
     FreeformMultiple        # Enter multiple values
 
     Text                    # Fill in one text area
+    Richtext                # Fill in one richtext area
     Wikitext                # Fill in one wikitext area
 
     BinarySingle            # Upload one file
diff --git a/lib/RT/Action/CreateTickets.pm b/lib/RT/Action/CreateTickets.pm
index 9127106a59..6ca2550b25 100644
--- a/lib/RT/Action/CreateTickets.pm
+++ b/lib/RT/Action/CreateTickets.pm
@@ -1156,7 +1156,7 @@ sub UpdateCustomFields {
         $CustomFieldObj->LoadById($cf);
 
         my @values;
-        if ($CustomFieldObj->Type =~ /text/i) { # Both Text and Wikitext
+        if ($CustomFieldObj->Type =~ /text/i) { # Text, Richtext, and Wikitext
             @values = ($args->{$arg});
         } else {
             @values = split /\n/, $args->{$arg};
diff --git a/lib/RT/CustomField.pm b/lib/RT/CustomField.pm
index a89ad6a4b9..168fce26fe 100644
--- a/lib/RT/CustomField.pm
+++ b/lib/RT/CustomField.pm
@@ -111,19 +111,28 @@ our %FieldTypes = (
                     'Fill in up to [quant,_1,text area,text areas]', # loc
                   ]
             },
-    Wikitext => {
+    Richtext => {
         sort_order => 40,
         selection_type => 0,
         canonicalizes => 1,
+        labels         => [
+                    'Fill in multiple richtext areas',                       # loc
+                    'Fill in one richtext area',                             # loc
+                    'Fill in up to [quant,_1,richtext area,richtext areas]', # loc
+                  ]
+                },
+    Wikitext => {
+        sort_order => 50,
+        selection_type => 0,
+        canonicalizes => 1,
         labels         => [
                     'Fill in multiple wikitext areas',                       # loc
                     'Fill in one wikitext area',                             # loc
                     'Fill in up to [quant,_1,wikitext area,wikitext areas]', # loc
                   ]
                 },
-
     Image => {
-        sort_order => 50,
+        sort_order => 60,
         selection_type => 0,
         canonicalizes => 0,
         labels         => [
@@ -133,7 +142,7 @@ our %FieldTypes = (
                   ]
              },
     Binary => {
-        sort_order => 60,
+        sort_order => 70,
         selection_type => 0,
         canonicalizes => 0,
         labels         => [
@@ -144,7 +153,7 @@ our %FieldTypes = (
               },
 
     Combobox => {
-        sort_order => 70,
+        sort_order => 80,
         selection_type => 1,
         canonicalizes => 1,
         labels         => [
@@ -154,7 +163,7 @@ our %FieldTypes = (
                   ]
                 },
     Autocomplete => {
-        sort_order => 80,
+        sort_order => 90,
         selection_type => 1,
         canonicalizes => 1,
         labels         => [
@@ -165,7 +174,7 @@ our %FieldTypes = (
     },
 
     Date => {
-        sort_order => 90,
+        sort_order => 100,
         selection_type => 0,
         canonicalizes => 0,
         labels         => [
@@ -175,7 +184,7 @@ our %FieldTypes = (
                   ]
             },
     DateTime => {
-        sort_order => 100,
+        sort_order => 110,
         selection_type => 0,
         canonicalizes => 0,
         labels         => [
@@ -186,7 +195,7 @@ our %FieldTypes = (
                 },
 
     IPAddress => {
-        sort_order => 110,
+        sort_order => 120,
         selection_type => 0,
         canonicalizes => 0,
 
@@ -196,7 +205,7 @@ our %FieldTypes = (
                   ]
                 },
     IPAddressRange => {
-        sort_order => 120,
+        sort_order => 130,
         selection_type => 0,
         canonicalizes => 0,
 
diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index bb5e158516..58980438ff 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -1915,7 +1915,7 @@ sub GetCustomFieldInputName {
     elsif ( $args{CustomField}->Type =~ /^(?:Binary|Image)$/ ) {
         $name .= 'Upload';
     }
-    elsif ( $args{CustomField}->Type =~ /^(?:Date|DateTime|Text|Wikitext)$/ ) {
+    elsif ( $args{CustomField}->Type =~ /^(?:Date|DateTime|Text|Richtext|Wikitext)$/ ) {
         $name .= 'Values';
     }
     else {
@@ -3378,6 +3378,11 @@ sub _ProcessObjectCustomFieldUpdates {
         delete $args{'ARGS'}->{'Values'};
     }
 
+    if ($cf_type eq 'Richtext') {
+        # this field is needed only to create the rich text editor
+        delete $args{'ARGS'}->{'ValuesType'};
+    }
+
     my @results;
     foreach my $arg ( keys %{ $args{'ARGS'} } ) {
 
@@ -3581,7 +3586,7 @@ sub _NormalizeObjectCustomFieldValue {
 
     if ( ref $args{'Value'} eq 'ARRAY' ) {
         @values = @{ $args{'Value'} };
-    } elsif ( $cf_type =~ /text/i ) {    # Both Text and Wikitext
+    } elsif ( $cf_type =~ /text/i ) {    # Text, Richtext, and Wikitext
         @values = ( $args{'Value'} );
     } else {
         @values = split /\r*\n/, $args{'Value'}
diff --git a/share/html/Articles/Article/Edit.html b/share/html/Articles/Article/Edit.html
index 697f1d287a..d4ea6cb7a9 100644
--- a/share/html/Articles/Article/Edit.html
+++ b/share/html/Articles/Article/Edit.html
@@ -136,8 +136,18 @@ if ( !$id ) {
         if ( $arg =~ /^Transaction-(\d+)$/ ) {
             my $trans = RT::Transaction->new( $session{'CurrentUser'} );
             $trans->Load($1);
-            $CFContent{ $ARGS{$arg} } .= "\n\n" if $CFContent{ $ARGS{$arg} };
-            $CFContent{ $ARGS{$arg} } .= $trans->Content;
+            my $cf_id = $ARGS{$arg};
+            my $cf = RT::CustomField->new( $session{'CurrentUser'} );
+            $cf->Load( $cf_id );
+            if ($CFContent{$cf_id}) {
+                if ($cf->Type eq 'Richtext') {
+                    $CFContent{$cf_id} .= "<br /><br />";
+                }
+                else {
+                    $CFContent{$cf_id} .= "\n\n";
+                }
+            }
+            $CFContent{$cf_id} .= $trans->Content( ($cf->Type eq 'Richtext') ? (Type => 'text/html') : () );
         }
     }
 
diff --git a/share/html/Articles/Article/ExtractFromTicket.html b/share/html/Articles/Article/ExtractFromTicket.html
index be9a2c0f64..7893c6fcf5 100644
--- a/share/html/Articles/Article/ExtractFromTicket.html
+++ b/share/html/Articles/Article/ExtractFromTicket.html
@@ -55,7 +55,7 @@
 % }
 <input type="hidden" name="new-RefersTo" value="t:<% $ticket->id%>" />
 <p><&|/l&>Use the dropdown menus to select which ticket updates you want to extract into a new article.</&>
-<&|/l&>You can insert ticket content into any freeform, text or wiki field.</&>
+<&|/l&>You can insert ticket content into any freeform, text, richtext, or wiki field.</&>
 </p>
 <div class="form-row">
   <div class="label col-2 text-left">
@@ -79,7 +79,15 @@
   </div>
   <div class="value col-auto">
     <b><%$trans->CreatedObj->AsString%>: <%$trans->Description%></b>
+% my $content_obj = $trans->ContentObj('text/html');
+% if ($content_obj->ContentType eq 'text/html') {
+    <span class="current-value">
+      <%$content_obj->Content|n%>
+    </span>
+% }
+% else {
     <pre><%$trans->Content%></pre>
+% }
   </div>
 </div>
 % } 
@@ -102,6 +110,7 @@ unless ($ClassObj->Id) {
 my     $CustomFields = $ClassObj->ArticleCustomFields();
 
 $CustomFields->Limit(FIELD => 'Type', OPERATOR => '=', VALUE => 'Text');
+$CustomFields->Limit(FIELD => 'Type', OPERATOR => '=', VALUE => 'Richtext');
 $CustomFields->Limit(FIELD => 'Type', OPERATOR => '=', VALUE => 'Wikitext');
 $CustomFields->Limit(FIELD => 'Type', OPERATOR => '=', VALUE => 'Freeform');
 </%init>
diff --git a/share/html/Elements/BulkCustomFields b/share/html/Elements/BulkCustomFields
index e19b181d9b..7a820b3805 100644
--- a/share/html/Elements/BulkCustomFields
+++ b/share/html/Elements/BulkCustomFields
@@ -97,6 +97,9 @@
 % } elsif ($cf->Type eq 'Text') {
     <div class="value col-4">
       <& /Elements/EditCustomFieldText, @add &>
+% } elsif ($cf->Type eq 'Richtext') {
+    <div class="value col-4">
+      <& /Elements/EditCustomFieldRichtext, @add &>
 % } elsif ($cf->Type eq 'Wikitext') {
     <div class="value col-4">
       <& /Elements/EditCustomFieldWikitext, @add &>
diff --git a/share/html/Elements/EditCustomFieldRichtext b/share/html/Elements/EditCustomFieldRichtext
new file mode 100644
index 0000000000..a906dfa5e7
--- /dev/null
+++ b/share/html/Elements/EditCustomFieldRichtext
@@ -0,0 +1,84 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2021 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<input type="text" style="display:none" name="<%$name%>Type" id="<%$name%>Type" value="text/html" />
+% while ($Values and my $value = $Values->Next ) {
+<textarea \
+% if ( defined $Cols ) {
+cols="<% $Cols %>" \
+% }
+% if ( defined $Rows ) {
+rows="<% $Rows %>" \
+% }
+name="<%$name%>" class="CF-<%$CustomField->id%>-Edit form-control richtext"><% $value->Content %></textarea><br />
+% }
+% if (!$MaxValues or !$Values or $Values->Count < $MaxValues) {
+<textarea \
+% if ( defined $Cols ) {
+cols="<% $Cols %>" \
+% }
+% if ( defined $Rows ) {
+rows="<% $Rows %>" \
+% }
+name="<%$name%>" class="CF-<%$CustomField->id%>-Edit form-control richtext"><% $Default %></textarea>
+% }
+<%INIT>
+# XXX - MultiValue textarea is for now outlawed.
+$MaxValues = 1;
+my $name = $Name || $NamePrefix . $CustomField->Id . '-Values';
+</%INIT>
+<%ARGS>
+$Object => undef
+$CustomField => undef
+$NamePrefix => undef
+$Name => undef
+$Default => undef
+$Values => undef
+$MaxValues => undef
+$Cols
+$Rows
+</%ARGS>
diff --git a/share/html/Elements/ShowCustomFieldRichtext b/share/html/Elements/ShowCustomFieldRichtext
new file mode 100644
index 0000000000..86e4bbfd95
--- /dev/null
+++ b/share/html/Elements/ShowCustomFieldRichtext
@@ -0,0 +1,55 @@
+%# BEGIN BPS TAGGED BLOCK {{{
+%#
+%# COPYRIGHT:
+%#
+%# This software is Copyright (c) 1996-2021 Best Practical Solutions, LLC
+%#                                          <sales at bestpractical.com>
+%#
+%# (Except where explicitly superseded by other copyright notices)
+%#
+%#
+%# LICENSE:
+%#
+%# This work is made available to you under the terms of Version 2 of
+%# the GNU General Public License. A copy of that license should have
+%# been provided with this software, but in any event can be snarfed
+%# from www.gnu.org.
+%#
+%# This work is distributed in the hope that it will be useful, but
+%# WITHOUT ANY WARRANTY; without even the implied warranty of
+%# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+%# General Public License for more details.
+%#
+%# You should have received a copy of the GNU General Public License
+%# along with this program; if not, write to the Free Software
+%# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+%# 02110-1301 or visit their web page on the internet at
+%# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
+%#
+%#
+%# CONTRIBUTION SUBMISSION POLICY:
+%#
+%# (The following paragraph is not intended to limit the rights granted
+%# to you to modify and distribute this software under the terms of
+%# the GNU General Public License and is only of importance to you if
+%# you choose to contribute your changes and enhancements to the
+%# community by submitting them to Best Practical Solutions, LLC.)
+%#
+%# By intentionally submitting any modifications, corrections or
+%# derivatives to this work, or any other work intended for use with
+%# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+%# you are the copyright holder for those contributions and you grant
+%# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
+%# royalty-free, perpetual, license to use, copy, create derivative
+%# works based on those contributions, and sublicense and distribute
+%# those contributions and any derivatives thereof.
+%#
+%# END BPS TAGGED BLOCK }}}
+<%$content|n%>
+<%init>
+my $content = $Object->LargeContent || $Object->Content;
+$content = $m->comp('/Elements/ScrubHTML', Content => $content);
+</%init>
+<%ARGS>
+$Object
+</%ARGS>
diff --git a/share/static/js/util.js b/share/static/js/util.js
index ddd122575f..33a23a764d 100644
--- a/share/static/js/util.js
+++ b/share/static/js/util.js
@@ -365,9 +365,9 @@ function ReplaceAllTextareas() {
 
     for (var i=0; i < allTextAreas.length; i++) {
         var textArea = allTextAreas[i];
-        if (jQuery(textArea).hasClass("messagebox richtext")) {
+        if (jQuery(textArea).hasClass("richtext")) {
             // Turn the original plain text content into HTML
-            var type = jQuery("#"+textArea.name+"Type");
+            var type = jQuery('[name="'+textArea.name+'Type"]');
             if (type.val() != "text/html")
                 textArea.value = textToHTML(textArea.value);
 
@@ -376,7 +376,7 @@ function ReplaceAllTextareas() {
 
             CKEDITOR.replace(textArea.name,{ width: '100%', height: RT.Config.MessageBoxRichTextHeight });
 
-            jQuery("#" + textArea.name + "___Frame").addClass("richtext-editor");
+            jQuery('[name="' + textArea.name + '___Frame"]').addClass("richtext-editor");
         }
     }
 };

-----------------------------------------------------------------------


hooks/post-receive
-- 
rt


More information about the rt-commit mailing list