# The LearningOnline Network # Syllabus # # $Id: lonsyllabus.pm,v 1.106.2.5 2010/02/17 18:42:38 faziophi Exp $ # # Copyright Michigan State University Board of Trustees # # This file is part of the LearningOnline Network with CAPA (LON-CAPA). # # LON-CAPA is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # LON-CAPA 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 LON-CAPA; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # /home/httpd/html/adm/gpl.txt # # http://www.lon-capa.org/ # package Apache::lonsyllabus; use strict; use Apache::lontemplate; use Apache::Constants qw(:common); use Apache::loncommon; use Apache::lonnet; use Apache::lontexconvert; use Apache::lonfeedback; use Apache::lonannounce; use Apache::lonlocal; use Apache::lonhtmlcommon; use Apache::lonspeller(); use HTML::Entities(); use Digest::MD5 qw(md5_hex); use Storable qw(freeze thaw); # These are strings representing types of fields # that will used to parse/display a field correctly use constant { TYPE_TEXT_HTML => 'html', #<-- default TYPE_TEXT_PLAIN => 'text', TYPE_URL_INCLUDE => 'include-url', }; sub handler { my $r = shift; &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; return OK if $r->header_only; my $target=$env{'form.grade_target'}; # --------------------------------------------------- Get course info from URL my (undef,undef,$cdom,$cnum)=split(/\//,$r->uri); # ------------------------------------------------------------ Get query string &Apache::loncommon::get_unprocessed_cgi ($ENV{'QUERY_STRING'},['delete', 'rename', 'field', 'forcestudent','register','forceedit','forceflush','wrapperdisplay']); # ----------------------------------------------------- Is this even a course? my $homeserver=&Apache::lonnet::homeserver($cnum,$cdom); if ($homeserver eq 'no_host') { &Apache::loncommon::content_type($r,'text/html'); $r->send_http_header; &Apache::loncommon::simple_error_page($r,'No syllabus available', 'No syllabus available'); return OK; } # ------------------------------------- There is such a course, get environment my %courseenv=&Apache::lonnet::dump('environment',$cdom,$cnum); # ------------------------------------------------------------ Print the screen if ($target eq 'tex') { $r->print(&Apache::lonprintout::print_latex_header($env{'form.latex_type'})); } # -------------------------------------------------- Let's see who handles this my $externalsyllabus=$courseenv{'externalsyllabus'}; if ($externalsyllabus=~/\w/) { if ($env{'form.wrapperdisplay'} eq 'menu') { $r->print(&Apache::lonwrapper::simple_menu()); } else { $r->print(&Apache::lonwrapper::wrapper("/public/$cdom/$cnum/syllabus?wrapperdisplay=menu", $externalsyllabus)); } return OK; } # --------------------------------------------------------- The old syllabus fields my %syllabusfields=&Apache::lonlocal::texthash( 'aaa_instructorinfo' => 'Instructor Information', 'bbb_description' => 'Course Description', 'ccc_prereq' => 'Prerequisites', 'cdc_classhours' => 'Class Hours', 'ddd_officehours' => 'Office Hours', 'eee_helproom' => 'Helproom Hours', 'efe_projectinfo' => 'Project Information', 'fff_examinfo' => 'Exam Information', 'fgf_deadlines' => 'Deadlines', 'ggg_grading' => 'Grading Information', 'hhh_readings' => 'Readings', 'iii_coursepack' => 'Coursepack', 'jjj_weblinks' => 'Web Links', 'kkk_textbook' => 'Textbook', 'lll_includeurl' => 'URLs To Include in Syllabus'); # --------------------------------------------------------------- Force Student my $forcestudent=''; if ($env{'form.forcestudent'}) { $forcestudent='student'; }; my $forceedit=''; if ($env{'form.forceedit'}) { $forceedit='edit'; } # ----------------------------------------------------------------- Make header if ($target ne 'tex') { my $rss_link = &Apache::lonrss::rss_link($cnum,$cdom); my $js; if ($env{'form.backto'} eq 'coursecatalog') { $js .= <<"ENDSCRIPT"; ENDSCRIPT } $js .= <<'ENDSCRIPT'; ENDSCRIPT my $start_page = &Apache::loncommon::start_page("Syllabus", $rss_link.$js, {'function' => undef, 'domain' => $cdom, 'force_register' => $env{'form.register'},}); $r->print($start_page); if ($env{'form.backto'} eq 'coursecatalog') { &Apache::lonhtmlcommon::clear_breadcrumbs(); &Apache::lonhtmlcommon::add_breadcrumb ({href=>"javascript:ToCatalog()", text=>"Course/Community Catalog"}); if ($env{'form.coursenum'} ne '') { &Apache::lonhtmlcommon::add_breadcrumb ({href=>"javascript:ToCatalog('details')", text=>"Course details"}); } &Apache::lonhtmlcommon::add_breadcrumb ({href=>$r->uri, text=>"Course syllabus"}); $r->print(&Apache::lonhtmlcommon::breadcrumbs()); } } # ---------------------------------------------------------- Load syllabus info my %syllabus=&Apache::lonnet::dump('syllabus',$cdom,$cnum); # load db my $allowed=0; # can we edit this page? my $privileged=0; my %data; if ($env{'form.forceflush'}) { delete $syllabus{'data.fields'}; &Apache::lonnet::del('syllabus', ['data.fields'], $cdom, $cnum); delete $syllabus{'properties.v2_conflict'}; &Apache::lonnet::del('syllabus', ['properties.v2_conflict'], $cdom, $cnum); delete $syllabus{'properties.v2_conflict_fail'}; &Apache::lonnet::del('syllabus', ['properties.v2_conflict_fail'], $cdom, $cnum); delete $syllabus{'properties.last_modified'}; &Apache::lonnet::del('syllabus', ['properties.last_modified'], $cdom, $cnum); delete $syllabus{'properties.v2_converted'}; &Apache::lonnet::del('syllabus', ['properties.v2_converted'], $cdom, $cnum); delete $syllabus{'data.old_new_map'}; &Apache::lonnet::del('syllabus', ['data.old_new_map'], $cdom, $cnum); delete $syllabus{'data.deleted_fields'}; &Apache::lonnet::del('syllabus', ['data.deleted_fields'], $cdom, $cnum); %syllabus=&Apache::lonnet::dump('syllabus',$cdom,$cnum); # load db $r->print("Flushed syllabus DB file.
"); $r->print("Syllabus conflict: ".$syllabus{'properties.v2_conflict'}."
"); } #$r->print("Existing fields: ".$syllabus{'data.fields'}."
"); #$r->print("Old-new map: ".$syllabus{'data.old_new_map'}."
"); #$r->print("Deleted fields: ".$syllabus{'data.deleted_fields'}."
"); if (!exists($syllabus{'data.fields'})) { # convert existing 2.x data to new DB fields # which become new primary data source for document %data = %{convert_from_v2($r, \%syllabus, \%syllabusfields, 0)}; #$r->print("New fields order: ".$data{'data.fields'}."
"); &Apache::lonnet::put('syllabus',\%data,$cdom,$cnum); } elsif ( !exists($syllabus{'properties.v2_converted'}) && exists($syllabus{'uploaded.lastmodified'}) && exists($syllabus{'properties.last_modified'}) && ($syllabus{'uploaded.lastmodified'} != $syllabus{'properties.last_modified'})) { # if the document has been saved in 3.x and later edited in # 2.x, reconvert the existing document, with extra warning %data = %{convert_from_v2($r, \%syllabus, \%syllabusfields, 1)}; delete $data{'properties.v2_converted'}; &Apache::lonnet::del('syllabus', ['properties.v2_converted'], $cdom, $cnum); $data{'properties.v2_conflict'} = 1; &Apache::lonnet::put('syllabus',\%data,$cdom,$cnum); } else { %data = %syllabus; } # ----------------------------------------------------- Only if not public call if ($env{'user.environment'}) { # does this user have privileges to post, etc? if ($env{'request.course.id'} && $cdom eq $env{'course.'.$env{'request.course.id'}.'.domain'} && $cnum eq $env{'course.'.$env{'request.course.id'}.'.num'}) { $allowed=&Apache::lonnet::allowed('mdc',$env{'request.course.id'}); $privileged=$allowed; if (($data{'uploaded.lastmodified'}) && (!$forceedit)) { $forcestudent='student'; } if ($forcestudent or $target eq 'tex') { $allowed=0; } } #store what the user typed in my @fields = @{thaw($data{'data.fields'})}; if (($allowed) && ($env{'form.delete'})) { my $field = $env{'form.delete'}; chomp($field); #allow only numbers, underscores $field=~s/[^0-9_]//g; #check if the field exists #do not delete if file in v2 conversion mode if (exists($data{'data.field.'.$field}) && !exists($data{'properties.v2_converted'})) { #$r->print("Field '$field' can be deleted.
"); # linearly parse "data.fields" and remove it for (my $i = 0; $i < length(@fields); $i++) { if ($fields[$i] eq $field) { splice(@fields, $i, 1); #$r->print("Removed entry $i from 'data.fields'
"); } } # if "data.deleted" does not exist, create it my @deleted; if (!exists($data{'data.deleted_fields'})) { @deleted = []; } else { @deleted = @{thaw($data{'data.deleted_fields'})}; } # only if deleted does not exist in 'data.deleted', push it my $push = 1; for (my $i = 0; $i < length(@deleted); $i++) { if ($deleted[$i] eq $field) { $push = 0; last; } } unless (!$push) { push(@deleted, $field); } $data{'data.fields'} = freeze(\@fields); $data{'data.deleted_fields'} = freeze(\@deleted); &Apache::lonnet::put('syllabus',\%data,$cdom,$cnum); } } if (($allowed) && ($env{'form.rename'})) { my $field = $env{'form.rename'}; my $new_title = "Hello, World!"; chomp($field); $field=~s/[^0-9_]//g; #check if the field exists #do not delete if file in v2 conversion mode if (exists($data{'data.field.'.$field}) && !exists($data{'properties.v2_converted'})) { #sanitize HTML content #$r->print("Rename -- field found.
"); my %db_entry = %{thaw($data{'data.field.'.$field})}; $new_title = &Apache::lonfeedback::clear_out_html($new_title, 1); $db_entry{title} = $new_title; $data{'data.field.'.$field} = freeze(\%db_entry); &Apache::lonnet::put('syllabus',\%data,$cdom,$cnum); } } if (($allowed) && ($env{'form.storesyl'})) { foreach my $syl_field (@fields) { my $field=$env{'form.'.$syl_field}; my $type; my %field_hash; # only update a field if it already exists! if (exists($data{'data.field.'.$syl_field})) { #$r->print("Creating/updated field ".$syl_field."
"); %field_hash = exists($data{'data.field.'.$syl_field}) ? %{thaw($data{'data.field.'.$syl_field})} : (); $type = exists($field_hash{type}) ? $field_hash{type} : TYPE_TEXT_HTML; chomp($field); $field=~s/\s+$//s; $field=~s/^\s+//s; $field=~s/\$//s; $field=&Apache::lonfeedback::clear_out_html($field,1); $field_hash{content}=$field; if ($type eq TYPE_URL_INCLUDE) { # clean up included URLs my $field=''; foreach my $value (split(/\n/,$field_hash{content})) { my $url=$value; # get rid of leading and trailing spaces $url=~s/^\s+//; $url=~s/\s+$//; if ($url=~m|^https?\://([^/]+)/(.+)$|) { my $host = $1; my $remainder=$2; # remove the hostname from internal URLs my $hostname = &Apache::lonnet::hostname($host); my %all_hostnames = &Apache::lonnet::all_hostnames(); foreach my $possible_host (keys(%all_hostnames)) { if ($possible_host =~ /\Q$hostname\E/i) { $url=$remainder; } } } # norm internal URLs unless ($url=~/^https?\:/) { $url=&Apache::lonnet::clutter($url); } # re-assemble field if ($url) { $field.=$url."\n"; } } $field_hash{content}=$field; $field_hash{type}=TYPE_URL_INCLUDE; } $data{'data.field.'.$syl_field} = freeze(\%field_hash); } } $data{'uploaded.domain'}=$env{'user.domain'}; $data{'uploaded.name'}=$env{'user.name'}; my $time = $^T; $data{'uploaded.lastmodified'}=$time; $data{'properties.last_modified'}=$time; delete $data{'properties.v2_converted'}; delete $data{'properties.v2_conflict'}; delete $data{'properties.v2_conflict_fail'}; &Apache::lonnet::del('syllabus', ['properties.v2_converted', 'properties.v2_conflict', 'properties.v2_conflict_fail'], $cdom, $cnum); #2.x compatibility: write to old fields with new mapped fields my %old_new_map = %{thaw($data{'data.old_new_map'})}; foreach my $old_field (keys(%old_new_map)) { #$r->print("Looking for: ".$old_field." at ".$old_new_map{$old_field}."
"); if (exists($data{'data.field.'.$old_new_map{$old_field}})) { #$r->print("updating old field ".$old_field."
"); my %new_field = %{thaw($data{'data.field.'.$old_new_map{$old_field}})}; $data{$old_field} = $new_field{content}; } } &Apache::lonnet::put('syllabus',\%data,$cdom,$cnum); } } #--------Functions if( ($allowed || $privileged) && $target ne 'tex') { my $functions=&Apache::lonhtmlcommon::start_funclist(); if ($allowed) { #if you have the register flag, keep it if($env{'form.register'} == 1) { $functions.=&Apache::lonhtmlcommon::add_item_funclist( '' .&mt('Show Public View').'' .&Apache::loncommon::help_open_topic( 'Uploaded_Templates_PublicView')); } else { $functions.=&Apache::lonhtmlcommon::add_item_funclist( '' .&mt('Show Public View').'' .&Apache::loncommon::help_open_topic( 'Uploaded_Templates_PublicView')); } } elsif ($privileged) { if($env{'form.register'} == 1) { $functions.=&Apache::lonhtmlcommon::add_item_funclist( '' .&mt('Edit').''); } else { $functions.=&Apache::lonhtmlcommon::add_item_funclist( '' .&mt('Edit').''); } } $functions.=&Apache::lonhtmlcommon::end_funclist(); $r->print(&Apache::loncommon::head_subbox($functions)); } #---------------------Print External URL Syllabus Info and Help Text if( ($allowed) && ($target ne 'tex') ) { my $protocol = $Apache::lonnet::protocol{$homeserver}; $protocol = 'http' if ($protocol ne 'https'); $r->print('

' .&mt('This syllabus can be publicly viewed at [_1]' ,''.$protocol.'://'.&Apache::lonnet::hostname($homeserver).$r->uri.'') .' '.&Apache::loncommon::help_open_topic('Syllabus_ExtLink') .'

' .'

' .&mt('Instead of using this template you can specify an external URL as Syllabus in the [_1]Course Configuration[_2].' ,'','') .'

' ); #-Print Help Text $r->print(&Apache::loncommon::help_open_topic( 'Uploaded_Templates_TextBoxes', &mt('Help with filling in text boxes'))); } #----------Print last update my $lastmod=$syllabus{'uploaded.lastmodified'}; $lastmod=($lastmod?&Apache::lonlocal::locallocaltime($lastmod):&mt('never')); my $who = &Apache::loncommon::aboutmewrapper( &Apache::loncommon::plainname($syllabus{'uploaded.name'}, $syllabus{'uploaded.domain'}),$syllabus{'uploaded.name'}, $syllabus{'uploaded.domain'}); if ($target ne 'tex') { $r->print('
'.&mt('Last updated').': '. $lastmod . ' '. ($who ? &mt('by').' '.$who : '' ) . '
' ); } else { $r->print('\\\\ '.&mt('Last updated').': '.$lastmod.' '. ($who? &mt('by').'\\\\ '. &Apache::loncommon::plainname($syllabus{'uploaded.name'},$syllabus{'uploaded.domain'}) :'') .'\\\\'); } if ($allowed && $data{'properties.v2_converted'} == 1) { $r->print("This document was created with LON-CAPA 2.x. Modifying it may cause it to not display correctly on older servers.
"); } if ($allowed && $data{'properties.v2_conflict'} == 1) { $r->print("This document was saved with LON-CAPA 3.x, then further edited in LON-CAPA 2.x.
"); if ($data{'properties.v2_conflict_fail'} == 1) { $r->print("Some fields in LON-CAPA 2.x no longer have an equivalent in LON-CAPA 3.x. These fields were appended; some fields may be duplicated or not match.
"); } else { $r->print("These changes were automatically transferred to LON-CAPA 3.x"); } } #----------------------------Print Headtitle if ($target ne 'tex') { $r->print('

'.$courseenv{'description'}.'

'); $r->print('

'. &Apache::lonnet::domain($cdom,'description').'

'); } else { $r->print('\noindent{\large\textbf{'.$courseenv{'description'}.'}}\\\\\\\\\textbf{'. &Apache::lonnet::domain($cdom,'description').'}\\\\'); } # -------------------------------------------------------- Get course personnel my %coursepersonnel=&Apache::lonnet::get_course_adv_roles($cdom.'/'.$cnum); if ($target ne 'tex') { $r->print(&Apache::lonhtmlcommon::start_pick_box()); } else { $r->print('\begin{tabular}{|p{0.45\textwidth}|p{0.45\textwidth}|}\hline'); } my @personnel=sort(keys(%coursepersonnel)); my $lastpers=$personnel[$#personnel]; foreach my $element (@personnel) { if ($target ne 'tex') { $r->print(&Apache::lonhtmlcommon::row_title($element)); } else { $r->print(' '.&Apache::lonxml::xmlparse($r,'tex',$element).' & '); } foreach (split(/\,/,$coursepersonnel{$element})) { my ($puname,$pudom)=split(/\:/,$_); if ($target ne 'tex') { my $courseperson = &Apache::loncommon::plainname($puname,$pudom); if (($env{'user.name'} eq '') || ($env{'user.name'} eq 'public') || ($env{'user.domain'} eq '') || ($env{'user.domain'} eq 'public')) { $r->print(' '.$courseperson); } else { $r->print(' '.&Apache::loncommon::aboutmewrapper($courseperson, $puname,$pudom)); } } else { $r->print(' '.&Apache::loncommon::plainname($puname, $pudom).' '); } } if ($target ne 'tex') { my $lastclose=$element eq $lastpers?1:0; $r->print(&Apache::lonhtmlcommon::row_closure($lastclose)); } else { $r->print('\\\\ \hline'); } } if ($target ne 'tex') { $r->print(&Apache::lonhtmlcommon::end_pick_box()); } else { $r->print('\end{tabular}\\\\'); } # -------------------------------------------------------------- Announcements? my $day = &Apache::lonannounce::showday(time,2, &Apache::lonannounce::readcalendar($cdom.'_'.$cnum)); if ($target ne 'tex') { if ($allowed) { &print_activity_bar($r, \%data, $target, $allowed, Apache::lontemplate->RICH_TEXT_DETECT_HTML); &print_field_sortable($r, \%data, $target, $allowed, Apache::lontemplate->RICH_TEXT_DETECT_HTML); &print_title_bar($r, \%data, $target, $allowed, Apache::lontemplate->RICH_TEXT_DETECT_HTML); &print_context_bar($r, \%data, $target, $allowed, Apache::lontemplate->RICH_TEXT_DETECT_HTML); } $r->print("
\n"); } else { $r->print(&Apache::lonxml::xmlparse($r,'tex',$day)); } # ---------------------------------------------------------------- Get syllabus if (($syllabus{'uploaded.lastmodified'}) || ($allowed)) { if ($allowed) { $r->print('
'. ''); } my @htmlids=(); my $url_include_handler = sub { my ($r, $field, $json_ref, $group, $target, $allowed) = @_; my $message = $json_ref->{items}{$field}{content}; my $title = $json_ref->{items}{$field}{title}; my $urls = $message; foreach my $filelink (split(/\n/,$urls)) { my $output=''; # embed style? my ($curfext)=($filelink=~/\.([^\.]+)$/); my $embstyle=&Apache::loncommon::fileembstyle($curfext); if (($embstyle eq 'ssi') || ($curfext=~/\/$/)) {# make ssi call and remove everything but the body contents $output=&Apache::lonnet::ssi_body($filelink); } elsif ($embstyle eq 'img') {# embed as an image $output=''; } if ($output ne '') { $message=''; if ($target ne 'tex') { $message.='

'.$output.'

'; } else { $message.=' '.&Apache::lonxml::xmlparse($r,'tex','

'.$output.'

').' '; } } } if ($allowed) { &Apache::lonfeedback::newline_to_br(\$urls); &Apache::lontemplate::print_start_template($r,$title. &Apache::loncommon::help_open_topic('Syllabus_URLs'),'LC_Box'); $r->print($urls); $r->print("
"); &Apache::lontemplate::print_textarea_template($r, $message, $field, Apache::lontemplate->RICH_TEXT_ALWAYS_OFF); &Apache::lontemplate::print_saveall_template($r); $r->print("
"); &Apache::lontemplate::print_end_template($r); } else { $r->print($message); } }; my %custom_hash = ( TYPE_URL_INCLUDE() => $url_include_handler ); @htmlids = &print_template_new_fields($r, \%data, $target, $allowed, Apache::lontemplate->RICH_TEXT_DETECT_HTML, \%custom_hash); if ($allowed) { $r->print('
'); $r->print(&Apache::lonhtmlcommon::htmlareaselectactive(@htmlids)); } if ($target ne 'tex') {$r->print('

 

');} if ($allowed) { &Apache::lontemplate::print_start_template($r,'RSS Feeds and Blogs','LC_Box'); $r->print(&Apache::lonrss::advertisefeeds($cnum,$cdom,$forceedit)); my $editurl= &Apache::lonnet::absolute_url().'/adm/'.$cdom.'/'.$cnum.'/_rss.html'; $r->print( ''.&mt('New RSS Feed or Blog').''); &Apache::lontemplate::print_end_template($r); } elsif (&Apache::lonrss::advertisefeeds($cnum,$cdom) ne '') { &Apache::lontemplate::print_start_template($r,'RSS Feeds and Blogs','LC_Box'); $r->print(&Apache::lonrss::advertisefeeds($cnum,$cdom,$forceedit)); &Apache::lontemplate::print_end_template($r); } } else { if ($target ne 'tex') {$r->print('

');} else {$r->print('\par ');} $r->print(&mt('No syllabus information provided.')); if ($target ne 'tex') {$r->print('

');} } if ($target ne 'tex') { if ($env{'form.backto'} eq 'coursecatalog') { $r->print('
'. &Apache::lonhtmlcommon::echo_form_input(['backto','courseid']). '
'); } $r->print(&Apache::loncommon::end_page()); } else { $r->print('\end{document}'); } return OK; } sub print_activity_bar { my ($r, $data_ref, $target, $allowed, $default_rich_text, $group) = @_; $r->print("
"); } sub print_title_bar { my ($r, $data_ref, $target, $allowed, $default_rich_text, $group) = @_; $r->print("

Title Goes Here

"); } sub print_context_bar { my ($r, $data_ref, $target, $allowed, $default_rich_text, $group) = @_; $r->print("
"); } sub print_field_sortable { my ($r, $data_ref, $target, $allowed, $default_rich_text, $group) = @_; my %data = %{$data_ref}; my @fields = @{thaw($data{'data.fields'})}; $r->print("
\n"); foreach my $key (@fields) { my %field = %{thaw($data{'data.field.'.$key})}; $r->print("
  • $field{title}
  • \n"); } $r->print("
    \n"); } sub print_template_new_fields { my ($r, $data_ref, $target, $allowed, $default_rich_text, $custom_handlers_ref, $group) = @_; my @html_ids = (); my %data = %{$data_ref}; my @fields = @{thaw($data{'data.fields'})}; my %custom_handlers = %{$custom_handlers_ref}; foreach my $key (@fields) { my %field = %{thaw($data{'data.field.'.$key})}; my $title = $field{title}; my $raw_message = $field{content}; my $type = $field{type}; my $message = $raw_message if (($raw_message=~/\w/) || ($allowed)); if ((%custom_handlers) && exists($custom_handlers{$type})) { #$custom_handlers{$type}->($r, $field, $json_ref, $group, $target, $allowed); } else { if (($raw_message=~/\w/) || ($allowed)) { if (!&Apache::lonfeedback::contains_block_html($message)) { &Apache::lonfeedback::newline_to_br(\$message); } else { $message = &Apache::lonfeedback::tidy_html($message); } $message=&Apache::lonhtmlcommon::raw_href_to_link($message); if ($allowed) { $message=&Apache::lonspeller::markeduptext($message); } $message=&Apache::lontexconvert::msgtexconverted($message); if ($target ne 'tex') { #output of syllabusfields will be generated here. &Apache::lontemplate::print_start_template($r,$title,'LC_Box', 'box-'.$key); #$r->print($message); if ($allowed) { $r->print("
    "); &Apache::lontemplate::print_textarea_template($r, $raw_message, $key, $default_rich_text); # &Apache::lontemplate::print_saveall_template($r); # if (!exists($data{'properties.v2_converted'})) { # $r->print("Delete "); # $r->print("Rename to \"Hello, World!\""); # } $r->print("
    "); } &Apache::lontemplate::print_end_template($r); } else { my $safeinit; $r->print(&Apache::lonxml::xmlparse($r,'tex','

    '.$title.'

    ')); $r->print(&Apache::lonxml::xmlparse($r,'tex',$message)); } push(@html_ids,"hello"); } } } return @html_ids; } sub convert_from_v2 { my ($r, $data_ref, $fields_ref, $conflict) = @_; my %data = %{$data_ref}; my %fields = %{$fields_ref}; my @fields_order = (!$conflict) ? () : @{thaw($data{'data.fields'})}; my %old_new_map = (!$conflict) ? () : %{thaw($data{'data.old_new_map'})}; my $repeat_int = 0; #ensure fields with created timestamp are unique foreach my $element (sort(keys(%fields))) { my %new_element = (); my $title = $fields{$element}; my $title_hash = time."_".$$; if (exists($data{'data.field.'.$title_hash})) { $title_hash .= "_".$repeat_int++; } my $content = $data{$element}; $new_element{title} = $title; $new_element{content} = $content; if ($element eq 'lll_includeurl') { $new_element{type} = TYPE_URL_INCLUDE; } else { $new_element{type} = TYPE_TEXT_HTML; } if (!$conflict) { $r->print("Creating new field with ID: ".$title_hash."
    "); $data{'data.field.'.$title_hash} = freeze(\%new_element); $old_new_map{$element} = $title_hash; push(@fields_order, $title_hash); } else { if (exists($old_new_map{$element})) { $r->print("Transferring old field ".$element." to new ID: ".$old_new_map{$element}."
    "); if (exists($data{'data.field.'.$old_new_map{$element}})) { my %new_field = %{thaw($data{'data.field.'.$old_new_map{$element}})}; $new_field{content} = $content; $data{'data.field.'.$old_new_map{$element}} = freeze(\%new_field); } } else { $data{'data.field.'.$title_hash} = freeze(\%new_element); $old_new_map{$element} = $title_hash; $data{'properties.v2_conflict_fail'} = 1; push(@fields_order, $title_hash); } } } $data{'data.fields'} = freeze(\@fields_order); $data{'data.old_new_map'} = freeze(\%old_new_map); $data{'properties.last_modified'} = time; $data{'properties.v2_converted'} = 1; $data{'properties.type'} = 'syllabus'; return \%data; } 1; __END__