From 9b7a1ebc88abaa9c85af6f17fcddfb2f57f2376b Mon Sep 17 00:00:00 2001 From: Milan Date: Sat, 7 Mar 2020 22:47:52 +0100 Subject: [PATCH] support markdown in editor events can be edited in markdown. markup language can be set in series template for newly created events. --- install/migrate.sql | 10 +++++ lib/calcms/eventOps.pm | 4 +- lib/calcms/events.pm | 25 +++++++---- lib/calcms/markup.pm | 8 ++++ lib/calcms/series_events.pm | 22 ++++++---- website/agenda/planung/event.cgi | 16 ++++++-- website/agenda/planung/pot/de/event.po | 10 +++++ website/agenda/planung/pot/de/roles.po | 3 ++ website/agenda/planung/pot/de/series.po | 14 ++++++- website/agenda/planung/pot/en/event.po | 10 +++++ website/agenda/planung/pot/en/roles.po | 3 ++ website/agenda/planung/pot/en/series.po | 9 ++++ website/agenda/planung/series.cgi | 27 +++++++++--- .../agenda/planung/templates/edit-event.html | 15 +++++++ .../agenda/planung/templates/edit-series.html | 9 ++++ website/agenda/planung/user-settings.cgi | 41 +++++++++++-------- 16 files changed, 178 insertions(+), 48 deletions(-) diff --git a/install/migrate.sql b/install/migrate.sql index 753fb33..cee4b82 100644 --- a/install/migrate.sql +++ b/install/migrate.sql @@ -258,3 +258,13 @@ CREATE TABLE `calcms`.`calcms_user_default_studios` ( PRIMARY KEY (`id`), INDEX `user` (`user` ASC)); + +ALTER TABLE `calcms`.`calcms_series` +ADD COLUMN `content_format` VARCHAR(45) NULL AFTER `predecessor_id`; + +ALTER TABLE `calcms`.`calcms_events` +ADD COLUMN `content_format` VARCHAR(45) NULL DEFAULT NULL AFTER `disable_event_sync`; + +ALTER TABLE `calcms`.`calcms_roles` +ADD COLUMN `update_event_field_content_format` TINYINT(1) UNSIGNED NOT NULL AFTER `modified_at`; + diff --git a/lib/calcms/eventOps.pm b/lib/calcms/eventOps.pm index c260167..34700af 100644 --- a/lib/calcms/eventOps.pm +++ b/lib/calcms/eventOps.pm @@ -46,7 +46,7 @@ sub setAttributesFromSeriesTemplate($$$) { my $serie = $series->[0]; for my $attr ( 'program', 'series_name', 'title', 'excerpt', 'topic', 'content', 'html_content', 'project', - 'category', 'location', 'image', 'live', 'archive_url', 'podcast_url' + 'category', 'location', 'image', 'live', 'archive_url', 'podcast_url', 'content_format' ) { $event->{$attr} = $serie->{$attr}; @@ -109,7 +109,7 @@ sub setAttributesFromOtherEvent ($$$){ for my $attr ( 'title', 'user_title', 'excerpt', 'user_excerpt', 'content', 'html_content', 'topics', 'image', 'series_image', 'live', 'no_event_sync', 'podcast_url', - 'archive_url', 'image_label', 'series_image_label' + 'archive_url', 'image_label', 'series_image_label', 'content_format' ) { $event->{$attr} = $event2->{$attr}; diff --git a/lib/calcms/events.pm b/lib/calcms/events.pm index 701d4f3..1b82878 100644 --- a/lib/calcms/events.pm +++ b/lib/calcms/events.pm @@ -333,16 +333,22 @@ sub modify_results ($$$$) { && ( $params->{template} =~ /\.html/ ) ) { if ( defined $result->{content} ) { - $result->{content} = - markup::fix_line_ends( $result->{content} ); - $result->{content} = - markup::creole_to_html( $result->{content} ); + if (($result->{content_format}//'') eq 'markdown'){ + $result->{content} = markup::markdown_to_html( $result->{content} ); + }else{ + $result->{content} = markup::fix_line_ends( $result->{content} ); + $result->{content} = markup::creole_to_html( $result->{content} ); + } $result->{html_content} = $result->{content}; - } + if ( defined $result->{topic} ) { - $result->{topic} = markup::fix_line_ends( $result->{topic} ); - $result->{topic} = markup::creole_to_html( $result->{topic} ); + if (($result->{content_format}//'') eq 'markdown'){ + $result->{topic} = markup::markdown_to_html( $result->{topic} ); + }else{ + $result->{topic} = markup::fix_line_ends( $result->{topic} ); + $result->{topic} = markup::creole_to_html( $result->{topic} ); + } $result->{html_topic} = $result->{topic}; } } @@ -1029,13 +1035,14 @@ sub get_query($$$) { unless ( $get eq 'no_content' ) { if ( $template =~ /\.html/ ) { unless ( $template =~ /menu/ || $template =~ /list/ ) { - $query .= ', e.content, e.topic, e.html_content, e.html_topic'; + $query .= ', e.content, e.topic, e.html_content, e.html_topic, e.content_format + '; #$query.=',html_content content, html_topic topic' ; } } else { unless ( $template =~ /menu/ || $template =~ /list/ ) { - $query .= ', e.content, e.topic, e.html_content, e.html_topic'; + $query .= ', e.content, e.topic, e.html_content, e.html_topic, e.content_format'; } } } diff --git a/lib/calcms/markup.pm b/lib/calcms/markup.pm index e98c885..b116fff 100644 --- a/lib/calcms/markup.pm +++ b/lib/calcms/markup.pm @@ -10,6 +10,7 @@ use HTML::Parse(); use HTML::FormatText(); use Encode(); use HTML::Entities(); +use Text::Markdown(); use log(); @@ -144,6 +145,13 @@ sub creole_to_html ($) { return $s; } +sub markdown_to_html($){ + my $text = $_[0] // ''; + print STDERR "markwon!\n"; + my $html = Text::Markdown::markdown($text); + return $html; +} + sub creole_to_plain($) { my $s = shift; diff --git a/lib/calcms/series_events.pm b/lib/calcms/series_events.pm index 1a21cf6..bd8888f 100644 --- a/lib/calcms/series_events.pm +++ b/lib/calcms/series_events.pm @@ -54,12 +54,11 @@ sub save_content($$) { } for my $attr ( 'content', 'topic' ) { - if ( defined $entry->{$attr} ) { + next unless defined $entry->{$attr}; + if (($entry->{content_format}//'') eq 'markdown'){ + $entry->{ 'html_' . $attr } = markup::markdown_to_html( $entry->{$attr} ); + }else{ $entry->{ 'html_' . $attr } = markup::creole_to_html( $entry->{$attr} ); - - #$entry->{'html_'.$attr}=~s/([^\>])\n+([^\<])/$1$2/g; - #$entry->{'html_'.$attr}=~s/^\s*(

)?//g; - #$entry->{'html_'.$attr}=~s/(<\/p>)?\s*$//g; } } @@ -74,7 +73,8 @@ sub save_content($$) { 'html_topic', 'episode', 'image', 'image_label', 'series_image', 'series_image_label', 'podcast_url', 'archive_url', 'live', 'published', 'playout', 'archived', - 'rerun', 'draft', 'disable_event_sync', 'modified_by' + 'rerun', 'draft', 'disable_event_sync', 'modified_by', + 'content_format' ) { push @keys, $key if defined $entry->{$key}; @@ -467,8 +467,14 @@ sub insert_event ($$) { { $event->{$attr} = $params->{$attr} if defined $params->{$attr}; } - $event->{'html_content'} = markup::creole_to_html( $event->{'content'} ) if defined $event->{'content'}; - $event->{'html_topic'} = markup::creole_to_html( $event->{'topic'} ) if defined $event->{'topic'}; + + if (($event->{'content_format'}//'') eq 'markdown'){ + $event->{'html_content'} = markup::markdown_to_html( $event->{'content'} ) if defined $event->{'content'}; + $event->{'html_topic'} = markup::markdown_to_html( $event->{'topic'} ) if defined $event->{'topic'}; + }else{ + $event->{'html_content'} = markup::creole_to_html( $event->{'content'} ) if defined $event->{'content'}; + $event->{'html_topic'} = markup::creole_to_html( $event->{'topic'} ) if defined $event->{'topic'}; + } #add event status for my $attr ( 'live', 'published', 'playout', 'archived', 'rerun', 'draft', 'disable_event_sync' ) { diff --git a/website/agenda/planung/event.cgi b/website/agenda/planung/event.cgi index befc21c..b8d0681 100755 --- a/website/agenda/planung/event.cgi +++ b/website/agenda/planung/event.cgi @@ -207,7 +207,7 @@ sub show_event { 'image', 'image_label', 'series_image', 'series_image_label', 'live no_event_sync', 'podcast_url', - 'archive_url' + 'archive_url', 'content_format' ) { $event->{$attr} = $event2->{$attr}; @@ -314,6 +314,10 @@ sub show_event { } $params->{edit_lock} = 1; } + + for my $value ('markdown', 'creole'){ + $params->{"content_format_$value"}=1 if ($params->{content_format}//'') eq $value; + } $params->{loc} = localization::get( $config, { user => $params->{presets}->{user}, file => 'event' } ); @@ -460,6 +464,10 @@ sub show_new_event { $params->{'allow'}->{$permission} = $request->{permissions}->{$permission}; } + for my $value ('markdown', 'creole'){ + $params->{"content_format_$value"}=1 if ($params->{content_format}//'') eq $value; + } + $params->{loc} = localization::get( $config, { user => $params->{presets}->{user}, file => 'event,comment' } ); template::process( $config, 'print', template::check( $config, 'edit-event' ), $params ); @@ -567,7 +575,7 @@ sub save_event { for my $key ( 'content', 'topic', 'title', 'excerpt', 'episode', 'image', 'series_image', 'image_label', - 'series_image_label', 'podcast_url', 'archive_url' + 'series_image_label', 'podcast_url', 'archive_url', 'content_format' ) { next unless defined $permissions->{ 'update_event_field_' . $key }; @@ -616,6 +624,7 @@ sub save_event { return; } + # set series image my $series = series::get( $config, { @@ -848,7 +857,7 @@ sub check_params { 'series_name', 'title', 'excerpt', 'content', 'topic', 'program', 'category', 'image', 'series_image', 'user_content', 'user_title', 'user_excerpt', - 'podcast_url', 'archive_url', 'setImage' + 'podcast_url', 'archive_url', 'setImage', 'content_format' ) { if ( defined $params->{$param} ) { @@ -877,6 +886,5 @@ sub check_params { create_event create_event_from_schedule get_json }; } - print STDERR Dumper($checked); return $checked; } diff --git a/website/agenda/planung/pot/de/event.po b/website/agenda/planung/pot/de/event.po index c0bfedc..95db5c1 100644 --- a/website/agenda/planung/pot/de/event.po +++ b/website/agenda/planung/pot/de/event.po @@ -1,3 +1,4 @@ + msgid "region" msgstr "de" @@ -121,6 +122,15 @@ msgstr "bearbeitet am" msgid "label_modified_by" msgstr "von" +msgid "label_content_format" +msgstr "Wiki-Sprache" + +msgid "label_content_format_markdown" +msgstr "Markdown" + +msgid "label_content_format_creole" +msgstr "Creole" + msgid "button_event_list" msgstr "Sendungen zeigen" diff --git a/website/agenda/planung/pot/de/roles.po b/website/agenda/planung/pot/de/roles.po index 81d65ce..ac53ee6 100644 --- a/website/agenda/planung/pot/de/roles.po +++ b/website/agenda/planung/pot/de/roles.po @@ -73,6 +73,9 @@ msgstr "Podcast-URL bearbeiten" msgid "label_update_event_field_archive_url" msgstr "Archiv-URL bearbeiten" +msgid "label_update_event_field_content_format" +msgstr "Wiki-Format setzen" + msgid "label_create_event_from_schedule" msgstr "Sendungen vom Plan anlegen" diff --git a/website/agenda/planung/pot/de/series.po b/website/agenda/planung/pot/de/series.po index e1db460..0fd0693 100644 --- a/website/agenda/planung/pot/de/series.po +++ b/website/agenda/planung/pot/de/series.po @@ -77,11 +77,20 @@ msgstr "interne Kommentare" msgid "template_podcast_url" msgstr "Podcast URL" +msgid "template_archive_url" +msgstr "Archiv URL" + msgid "template_predecessor_id" msgstr "ID der Vorgänger-Serie" -msgid "template_archive_url" -msgstr "Archiv URL" +msgid "template_content_format" +msgstr "Wiki-Sprache" + +msgid "template_content_format_markdown" +msgstr "Markdown" + +msgid "template_content_format_creole" +msgstr "Creole" msgid "tab_schedule" msgstr "Planung" @@ -333,3 +342,4 @@ msgstr "löschen" msgid "label_excerpt_too_long" msgstr "Auszug ist zu lang. Für längeren Text bitte das Feld «aktuelle Themen» verwenden." + diff --git a/website/agenda/planung/pot/en/event.po b/website/agenda/planung/pot/en/event.po index 997c12d..9b52477 100644 --- a/website/agenda/planung/pot/en/event.po +++ b/website/agenda/planung/pot/en/event.po @@ -121,6 +121,15 @@ msgstr "modified at" msgid "label_modified_by" msgstr "by" +msgid "label_content_format" +msgstr "wiki Language" + +msgid "label_content_format_markdown" +msgstr "Markdown" + +msgid "label_content_format_creole" +msgstr "Creole" + msgid "button_event_list" msgstr "show events" @@ -165,3 +174,4 @@ msgstr "excerpt is too long. for longer text please use the field «Current Topi msgid "label_excerpt_extension_too_long" msgstr "excerpt is too long. for longer text please use the field «Current Topics»" + diff --git a/website/agenda/planung/pot/en/roles.po b/website/agenda/planung/pot/en/roles.po index d5fcded..8379cf5 100644 --- a/website/agenda/planung/pot/en/roles.po +++ b/website/agenda/planung/pot/en/roles.po @@ -76,6 +76,9 @@ msgstr "edit podcast URL" msgid "label_update_event_field_archive_url" msgstr "edit archive URL" +msgid "label_update_event_field_content_format" +msgstr "set Wiki-Format" + msgid "label_create_event_from_schedule" msgstr "create new events (with date from an existing schedule)" diff --git a/website/agenda/planung/pot/en/series.po b/website/agenda/planung/pot/en/series.po index 26c1642..ec240e7 100644 --- a/website/agenda/planung/pot/en/series.po +++ b/website/agenda/planung/pot/en/series.po @@ -83,6 +83,15 @@ msgstr "Archive URL" msgid "template_predecessor_id" msgstr "Series Predecessor ID" +msgid "template_content_format" +msgstr "wiki Language" + +msgid "template_content_format_markdown" +msgstr "Markdown" + +msgid "template_content_format_creole" +msgstr "Creole" + msgid "tab_schedule" msgstr "Schedule" diff --git a/website/agenda/planung/series.cgi b/website/agenda/planung/series.cgi index 0a4d695..2f8a1a1 100755 --- a/website/agenda/planung/series.cgi +++ b/website/agenda/planung/series.cgi @@ -343,10 +343,16 @@ sub save_series { $entry->{live} = $params->{live} // 0; $entry->{count_episodes} = $params->{count_episodes} // 0; $entry->{predecessor_id} = $params->{predecessor_id} // 0; + #$entry->{content} = $params->{content}; + #$entry->{content_format} = $params->{content_format}; #$entry->{html_content} = Encode::decode( 'utf-8', $entry->{content} ); - $entry->{html_content} = markup::creole_to_html( $entry->{content} ); - $entry->{html_content} =~ s/([^\>])\n+([^\<])/$1$2/g; + if ($entry->{content_format} //'' eq "markdown"){ + $entry->{html_content} = markup::markdown_to_html( $entry->{content} ); + }else{ + $entry->{html_content} = markup::creole_to_html( $entry->{content} ); + $entry->{html_content} =~ s/([^\>])\n+([^\<])/$1$2/g; + } $entry->{modified_at} = time::time_to_datetime( time() ); $entry->{modified_by} = $request->{user}; @@ -356,6 +362,7 @@ sub save_series { return; } + # make sure name is not used anywhere else my $series_ids = series::get( $config, { @@ -416,6 +423,7 @@ sub save_series { uac::print_error('series is not assigned to project!'); return undef; } + if ( scalar(@$series_ids) > 1 ) { uac::permissions_denied('update due to entry already exists'); return; @@ -1145,8 +1153,12 @@ sub show_series { $serie->{studio_users} = $studio_users; - $serie->{html_content} = markup::creole_to_html( $serie->{content} ); - $serie->{html_content} =~ s/([^\>])\n+([^\<])/$1$2/g; + if (($serie->{markup_format}//'') eq 'markdown'){ + $serie->{html_content} = markup::markdown_to_html( $serie->{content} ); + }else{ + $serie->{html_content} = markup::creole_to_html( $serie->{content} ); + $serie->{html_content} =~ s/([^\>])\n+([^\<])/$1$2/g; + } for my $user ( @{ $serie->{series_users} } ) { $user->{user_id} = $user->{id}; @@ -1214,11 +1226,14 @@ sub show_series { } #copy series to params - #$params->{series}=[$serie]; for my $key ( keys %$serie ) { $params->{$key} = $serie->{$key}; } + for my $value ('markdown', 'creole'){ + $params->{"content_format_$value"}=1 if $params->{content_format} eq $value; + } + $params->{loc} = localization::get( $config, { user => $params->{presets}->{user}, file => 'all,series' } ); template::process( $config, 'print', $params->{template}, $params ); @@ -1476,7 +1491,7 @@ sub check_params { 'image_label', 'assign_event_series_name', 'assign_event_title', 'comment', 'podcast_url', 'archive_url', - 'setImage' + 'setImage', 'content_format' ) { if ( defined $params->{$param} ) { diff --git a/website/agenda/planung/templates/edit-event.html b/website/agenda/planung/templates/edit-event.html index 6ed03b9..a5b5fb8 100644 --- a/website/agenda/planung/templates/edit-event.html +++ b/website/agenda/planung/templates/edit-event.html @@ -494,6 +494,21 @@ + + + + + + + + + + + + diff --git a/website/agenda/planung/templates/edit-series.html b/website/agenda/planung/templates/edit-series.html index 9dabc9d..8f3eabd 100644 --- a/website/agenda/planung/templates/edit-series.html +++ b/website/agenda/planung/templates/edit-series.html @@ -165,6 +165,15 @@ + + + + + +

diff --git a/website/agenda/planung/user-settings.cgi b/website/agenda/planung/user-settings.cgi index 30dbcb0..34445e3 100755 --- a/website/agenda/planung/user-settings.cgi +++ b/website/agenda/planung/user-settings.cgi @@ -60,7 +60,8 @@ our $errors = []; if ( defined $params->{action} ) { update_settings( $config, $request ) if ( $params->{action} eq 'save' ); - updateDefaultProjectStudio( $config, $request ) if ( $params->{action} eq 'updateDefaultProjectStudio' ); + updateDefaultProjectStudio( $config, $request ) + if ( $params->{action} eq 'updateDefaultProjectStudio' ); } $config->{access}->{write} = 0; show_settings( $config, $request ); @@ -106,7 +107,8 @@ sub show_settings { my $period = $user_settings->{period} || 'month'; $params->{ 'period_' . $period } = 1; - $params->{loc} = localization::get( $config, { language => $language, file => 'user-settings' } ); + $params->{loc} = + localization::get( $config, { language => $language, file => 'user-settings' } ); for my $color ( @{ $params->{colors} } ) { $color->{title} = $params->{loc}->{ $color->{title} }; @@ -132,12 +134,13 @@ sub updateDefaultProjectStudio { }; $config->{access}->{write} = 1; - if ( - defined user_settings::get( - $config, - { user => $user } - ) - ) { + if ( + defined user_settings::get( + $config, + { user => $user } + ) + ) + { uac::print_info("update project and studio settings"); user_settings::update( $config, $entry ); } else { @@ -145,14 +148,16 @@ sub updateDefaultProjectStudio { update_settings( $config, $request ); } - if ( - defined user_default_studios::get( - $config, { - user => $user, - project_id => $params->{project_id} - } - ) - ) { + if ( + defined user_default_studios::get( + $config, + { + user => $user, + project_id => $params->{project_id} + } + ) + ) + { uac::print_info("update user default studio"); user_default_studios::update( $config, $entry ); } else { @@ -217,7 +222,9 @@ sub check_params { $checked->{template} = $template; #numeric values - for my $param ( 'project_id', 'default_studio_id', 'studio_id', 'default_studio', 'default_project' ) { + for my $param ( 'project_id', 'default_studio_id', 'studio_id', 'default_studio', + 'default_project' ) + { if ( ( defined $params->{$param} ) && ( $params->{$param} =~ /^\d+$/ ) ) { $checked->{$param} = $params->{$param}; }