support markdown in editor

events can be edited in markdown. markup language can be set in series
template for newly created events.
This commit is contained in:
Milan
2020-03-07 22:47:52 +01:00
parent 1607b5468f
commit 9b7a1ebc88
16 changed files with 178 additions and 48 deletions

View File

@@ -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`;

View File

@@ -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};

View File

@@ -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';
}
}
}

View File

@@ -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;

View File

@@ -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<br\/><br\/>$2/g;
#$entry->{'html_'.$attr}=~s/^\s*(<p>)?//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' ) {

View File

@@ -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;
}

View File

@@ -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"

View File

@@ -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"

View File

@@ -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."

View File

@@ -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»"

View File

@@ -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)"

View File

@@ -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"

View File

@@ -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<br\/><br\/>$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<br\/><br\/>$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<br\/><br\/>$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<br\/><br\/>$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} ) {

View File

@@ -494,6 +494,21 @@
</TMPL_IF>
</td>
</tr>
<tr>
<td class="label"><TMPL_VAR .loc.label_content_format></td>
<td>
<TMPL_IF .allow.update_event_field_content_format>
<select name="content_format" style="width:100%;" value="<TMPL_VAR content_format>">
<option value="creole"<TMPL_IF content_format_creole> selected="selected"</TMPL_IF>><TMPL_VAR .loc.label_content_format_creole></option>
<option value="markdown"<TMPL_IF content_format_markdown> selected="selected"</TMPL_IF>><TMPL_VAR .loc.label_content_format_markdown></option>
</select>
<TMPL_ELSE>
<TMPL_VAR content_format>
</TMPL_IF>
</td>
</tr>
</table>
<!-- buttons -->

View File

@@ -165,6 +165,15 @@
<tr> <td class="label"><TMPL_VAR .loc.template_predecessor_id></td>
<td><input name="predecessor_id" style="width:100%;" value="<TMPL_VAR predecessor_id>" placeholder="<TMPL_VAR .loc.template_predecessor_id>"></td></tr>
<tr>
<td class="label"><TMPL_VAR .loc.template_content_format></td>
<td>
<select name="content_format" value="<TMPL_VAR content_format>">
<option value="creole"<TMPL_IF content_format_creole> selected="selected"</TMPL_IF>><TMPL_VAR .loc.template_content_format_creole></option>
<option value="markdown"<TMPL_IF content_format_markdown> selected="selected"</TMPL_IF>><TMPL_VAR .loc.template_content_format_markdown></option>
</select>
</td>
</tr>
</table>
<div class="buttons">

View File

@@ -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};
}