S2 Syntax Test

""";       close_module;    } } function print_module_syndicate {    var Page p = get_page;

if ((size $p.data_links_order) < 1) { return; } open_module("syndicate", $*text_module_syndicate, "");

foreach var string k ($p.data_links_order) { print " $p.data_link{$k} "; }

close_module; } function print_module_customtext { var Page p = get_page; open_module("customtext", $*text_module_customtext, $*text_module_customtext_url); print safe $*text_module_customtext_content; close_module; } function print_module_links { var Page p = get_page; var UserLink[] links = $p.linklist; if (size($links) < 1 or not $*linklist_support) { return; }

var bool box_open = false; if (not $links[0].is_heading) { open_module("typelist", $*text_module_links, ""); $box_open = true; }

var string[] items = []; foreach var UserLink link ($links) { if ($link.is_heading and $link.title != "") { if ($box_open) { print_module_list($items); close_module; $items = []; }           open_module("typelist", $link.title, ""); $box_open = true; }       if ($link.title == "") { print_module_list($items); $items = []; }       if (not $link.is_heading and $link.title != "") { $items[size $items] = """$link.title"""; }   }    if ($box_open) { print_module_list($items); close_module; } } function print_module_credit { var string ret = ""; var int authors_size = size $*layout_authors; if ( $authors_size > 0 ) { var int count = 0; $ret = $ret + "$*text_layout_authors "; foreach var string{} author ( $*layout_authors ) { var string item; if ( $author{"url"} != "" ) { $item = "" + $author{"name"} + ""; } elseif ( $author{"type"} == "user" ) { var UserLite u = UserLite( $author{"name"} ); if ( defined $u ) { $item = $u->ljuser; }           }            if ( $item == "" ) { $item = $author{"name"}; }

$ret = $ret + "$item"; $count++; if ($count < $authors_size ) { $ret = $ret + ","; } $ret = $ret + "\n"; }   }

var int resources_size = size $*layout_resources; if ( $resources_size > 0 ) { var int count = 0; $ret = $ret + "$*text_layout_resources "; foreach var string{} resource ( $*layout_resources ) { var string item; if ( $resource{"url"} != "" ) { $item = "" + $resource{"name"} + ""; } else { $item = $resource{"name"}; }

$ret = $ret + "$item"; $count++; if ($count < $resources_size ) { $ret = $ret + ","; } $ret = $ret + "\n"; }   }

if ( $ret != "" ) { open_module("credit", $*text_module_credit, ""); print safe "$ret"; close_module; } }

function handle_module_group_array(string[][] list) { foreach var string[] item ($list) { var string module = $item[0];

# we can have blank modulenames because the ordering will not necessarily be consecutive if ($module == "") { continue; }       elseif ($module == "userprofile") { print_module_userprofile; }       elseif ($module == "navlinks") { print_module_navlinks; }       elseif ($module == "time") { print_module_time; }       elseif ($module == "poweredby") { print_module_poweredby; }       elseif ($module == "pagesummary") { print_module_pagesummary; }       elseif ($module == "tags") { print_module_tags; }       elseif ($module == "active") { print_module_active; }       elseif ($module == "calendar") { print_module_calendar; }       elseif ($module == "syndicate") { print_module_syndicate; }       elseif ($module == "customtext") { print_module_customtext; }       elseif ($module == "links") { print_module_links; }       elseif ($module == "credit") { print_module_credit; }       elseif ($module == "search") { print_module_search; }   } }

function Page::print_module_section ( string section_name ) { """   \n<div class="module-section-$section_name">\n """; handle_module_group_array( $*module_sections{$section_name} ); """ \n  \n """; }

function Page::print "The meat of each new layout. Describes how each page will look. In nearly all cases, the logic and decision-making processes should come from pre-existing functions in core2, and should not get written here. If you limit the structure of the page to HTML, function calls, and attached CSS, then you will be able to pick up all of the enhancements and accessibility requirements managed by core2." {   """<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n<head profile="http://www.w3.org/2006/03/hcard http://purl.org/uF/hAtom/0.1/ http://gmpg.org/xfn/11">\n"""; $this->print_head; $this->print_stylesheets; $this->print_head_title; """ """;   $this->print_wrapper_start; $this->print_control_strip; """                   """;                    $this->print_global_title; $this->print_global_subtitle; $this->print_title; """                       """;                         $this->print_body; """                       """;                        $this->print_module_section("one"); """                       """;                        $this->print_module_section("two"); """   """;    """            """;            print safe """                <a href="#">$*text_page_top</a>     """; $this->print_wrapper_end; """ """; }

function Page::print_time { $this->print_time("",""); }

function Page::print_time(string datefmt, string timefmt) { if ($datefmt == "") { $datefmt = "med"; }   if ($timefmt == "") { if ($this.timeformat24) { $timefmt = "short_24"; } else { $timefmt = "short"; }   }

var string ret; if ($datefmt != "none") { $ret = $ret + $this.local_time->date_format($datefmt); } if ($datefmt != "none" and $timefmt != "none") { $ret = $ret + " "; } if ($timefmt != "none") { $ret = $ret + $this.local_time->time_format($timefmt); }

print safe """ $*text_generated_on $ret """; }

function Page::print_body { """ No Default Renderer There is no body renderer for viewtype <tt>$.view</tt> defined. """; }

function Page::print_navigation { $this->print_navigation( { "" => "" } ); } function Page::print_navigation( string{} opts ) {}

function Page::print_head { print $.head_content; $this->print_custom_head; }

function Page::print_custom_head { # blank }

function Page::print_linklist { if (size $.linklist <= 0) { return; } elseif (not $*linklist_support) { return; }

foreach var UserLink l ($.linklist) { if ($l.title) { if ($l.is_heading) { "$l.title"; } else { "<a href='$l.url'>$l.title</a>"; }       }        " ";    } }

function Entry::print_poster { var Page p = get_page; print safe "<span class=\"poster entry-poster\">"; if ($p isa FriendsPage or $p isa EntryPage or $p isa ReplyPage) { $this.poster->print; if (not $this.poster->equals($this.journal)) { print $*text_posting_in; $this.journal->print; }   }    else { if (not $this.poster->equals($this.journal)) { $this.poster->print; }   }    print safe " "; }
 * 1) Prints the name of the account which posted the entry

function Comment::print_poster { var string poster = defined $this.poster ? $this.poster->as_string : "<span class=\"anonymous\">$*text_poster_anonymous "; if ($this.metadata{"imported_from"}) { $poster = "<span class=\"imported-from\">$poster ($*text_openid_from " + $this.metadata{"imported_from"} + ") "; }
 * 1) For any given comment, print the commentor's name (local, anonymous, or openid)

print safe "<span class=\"poster comment-poster\">$*text_comment_from $poster \n"; }

function Page::print_entry(Entry e) "The meat of each new layout. Describes how each page will look. In nearly all cases, the logic and decision-making processes should come from pre-existing functions in core2, and should not get written here. If you limit the structure of the page to HTML, function calls, and attached CSS, then you will be able to pick up all of the enhancements and accessibility requirements managed by core2." {   ## For most styles, this will be overridden by FriendsPage::print_entry and such. $e->print_wrapper_start; """ \n"""; $e->print_subject; $e->print_metatypes; $e->print_time; """ \n"""; """ \n"""; """ \n"""; """ \n"""; $e->print_userpic; $e->print_poster; if ($*entry_metadata_position == "top") { $e->print_metadata; } $e->print_text; if ($*entry_metadata_position == "bottom") { $e->print_metadata; } """ \n"""; """ \n"""; """ \n"""; """ \n"""; """ \n"""; $e->print_tags; $e->print_management_links; if ($this isa EntryPage) { """<hr class="above-entry-interaction-links" />"""; $e->print_interaction_links("topcomment"); $this->print_reply_container({ "target" => "topcomment" }); """<hr class="below-reply-container" />"""; }   else { $e->print_interaction_links; }   " \n \n"; $e->print_wrapper_end;

}

function RecentPage::print_sticky_entry(StickyEntry s) "function to print the sticky entry. can be overrised by styles to print it differently than other entries." {   $this->print_entry( $s ); }

function Comment::print_edit_text { if ($this.edited) { var string editreason = $this.editreason == "" ? "" : "($this.editreason) "; print " $*text_comment_edittime $editreason"; $this->print_edittime; print " "; } }

function EntryLite::print_text [fixed] { if ($this isa Comment) { """ """;       print $.text; var Comment c = $this as Comment; $c->print_edit_text; """ """;   }    else { """ """;       print $.text; """ """;   } }

function EntryLite::print_subject [fixed] { $this->print_subject({ "" => "" }); }

function EntryLite::print_subject( string{} opts ) [fixed] { if ($this isa Comment) { var Comment c = $this as Comment; """ """;       if ($c.screened) { print $*text_screened; }       if ($c.frozen) { print $*text_frozen; }       print $this->formatted_subject( $opts ); " ";   }    else { if ($this isa StickyEntry) { var StickyEntry s = $this as StickyEntry; """<h3 class="sticky-entry-title entry-title">"""; $s->print_sticky_icon; print $*text_stickyentry_subject + $this->formatted_subject( $opts ); " ";       }        else { """<h3 class="entry-title">"""; print $this->formatted_subject( $opts ); " ";       }    } }

function StickyEntry::print_sticky_icon { """ """;   $this.sticky_entry_icon->print($*text_icon_alt_sticky_entry); """ \n"""; }

function EntryLite::print_wrapper_start { } function Entry::print_wrapper_start { var string alternate = alternate ("entry-wrapper-odd", "entry-wrapper-even"); var string security = $this.security ? $this.security : "public"; var string adult_content_level = $this.adult_content_level ? $this.adult_content_level : "none"; var string journal_type = "journal-type-$this.journal.journal_type"; var string poster; var string journal; if ($this.journal.journal_type != "I") { $poster = "poster-$this.poster.username"; $journal = "journal-$this.journal.username"; }   var string userpic = $this.userpic ? "has-userpic" : "no-userpic";
 * 1) FIXME: need to ensure that calling the alternate function doesn't interfere with the printing of comments or the printing of module groups.

#additional classes for sticky entries added if ($this isa StickyEntry) { """<div class="sticky-entry-wrapper entry-wrapper $alternate security-$security restrictions-$adult_content_level $journal_type $poster $journal $userpic" id="sticky-entry-wrapper-$this.itemid">\n"""; """  \n"""; """<div class="sticky-entry entry" id="sticky-entry-$this.itemid">\n"""; }   else { """<div class="entry-wrapper $alternate security-$security restrictions-$adult_content_level $journal_type $poster $journal $userpic" id="entry-wrapper-$this.itemid">\n"""; """  \n"""; """<div class="entry" id="entry-$this.itemid">\n"""; }   """ \n"""; } function Comment::print_wrapper_start { var EntryPage ep = get_page as EntryPage; var string alternate = alternate ("comment-wrapper-odd", "comment-wrapper-even"); var string screened = $this.screened ? "screened" : "visible"; var string deletedstate = $this.deleted ? "deleted" : ""; var string frozen = $this.frozen ? "frozen" : ""; var string poster = defined $this.poster ? "poster-" + $this.poster.username : "poster-anonymous"; var string full = $this.full ? "full" : "partial"; var string userpic = $this.userpic ? "has-userpic" : "no-userpic"; var string entryauthor = ""; if (not isnull $ep and defined $this.poster and $this.poster.username == $ep.entry.poster.username) { $entryauthor = "entry-author"; }   """<div class="comment-wrapper $alternate $screened $frozen $deletedstate $poster $entryauthor $full $userpic">\n"""; """  \n"""; """<div class="comment" id="comment-$this.dom_id">\n"""; """ \n"""; }

function EntryLite::print_wrapper_end { } function Entry::print_wrapper_end { " \n \n"; """  \n"""; " \n"; } function Comment::print_wrapper_end { " \n \n"; """  \n"""; " \n"; }

function EntryLite::print_metadata { } function Entry::print_metadata { if (size $.metadata) { var string position = ($*entry_metadata_position == "top") ? " top-metadata" : " bottom-metadata"; """<div class="metadata$position">\n<ul>\n"""; foreach var string m ($.metadata) { var string metadata_name = lang_metadata_title($m); """<li><span class="metadata-label metadata-label-$m">$metadata_name: """; if ($m == "mood") { " $.mood_icon "; }           """<span class="metadata-item metadata-item-$m">$.metadata{$m} </li>\n"""; }       "</ul>\n \n"; } } function Comment::print_metadata { if ($.metadata{"poster_ip"}) { print safe "<span class=\"poster-ip\">$*text_comment_ipaddr (" + $.metadata{"poster_ip"} + ") "; } }

function EntryLite::print_metatypes { } function Entry::print_metatypes(bool icon, bool info) { if ($this.security) { """ """;       if ($icon) { $this.security_icon->print($this.security); }       if ($info) { print $this.security; }       """ \n"""; }   if ($this.adult_content_level) { """ """;       if ($icon) { $this.adult_content_icon->print($this.adult_content_level); }       if ($info) { print $this.adult_content_level; }       """ \n"""; } }

function Entry::print_metatypes { $this->print_metatypes(true, false); }

function Comment::print_metatypes { if (defined $this.subject_icon) { """<h3 class="comment-subjecticon">$this.subject_icon """; } }

function Entry::print_tags [fixed] { if ($this.tags) { var int tag_count = 0; """ $*text_tags <ul>\n"""; foreach var Tag t ($this.tags) { """<li><a rel="tag" href="$t.url">$t.name</a>"""; $tag_count++; if ($tag_count < size $.tags) { print $*text_tags_item_sep; } "</li>\n"; }       "</ul> "; } }

function EntryLite::print_userpic { print "<div class=\"userpic\">"; if ( defined $this.userpic ) {       if ( $*use_shared_pic ) {           print """<a href="$this.journal.userpic_listing_url">"""; }       else {           print """<a href="$this.poster.userpic_listing_url">"""; }       $this.userpic->print; print "</a>"; }   println " "; }

function EntryLite::print_management_links {} function Comment::print_management_links "Prints comment management links, aka delete/screen/freeze/track." {   # FIXME: HTML is not valid if there are no items inside a list, so there should # be a check that there are comment management links before opening the ul class. """<ul class="comment-management-links">"""; var Link link; var int count; var string extras; $count = 0; foreach var string k ($.link_keyseq) { $link = $this->get_link($k); if ($link.url) { $count ++; if ($*comment_management_links == "text") { foreach var string extra ( $link.extra ) { var string value = $link.extra{$extra}; $extras = $extras + "$extra='$value' "; }               """<li class="link $k""" + ( ($count == 1) ? " first-item" : "" ) + """"><a href="$link.url" $extras>$link.caption</a></li>\n"""; }           else { ## if ($*comment_management_links == "icon") """<li class="link $k""" + ( ($count == 1) ? " first-item" : "" ) + """">$link</li>\n"""; }       }    }    """</ul>"""; }

function EntryLite::print_interaction_links {} function Comment::print_interaction_links "Prints comment interaction links, aka reply/thread/parent/expand." {   """<ul class="comment-interaction-links">"""; print safe """<li class="link commentpermalink"><a href="$this.permalink_url">$*text_comment_link</a></li>\n"""; if ($this.frozen) { print safe """<li class="link frozen first-item">$*text_comment_frozen</li>\n"""; } else { """<li class="link reply first-item">"""; $this->print_reply_link({"linktext" => $*text_comment_reply}); """</li>\n"""; }   if ($this.threadroot_url != "") { print safe """<li class="link threadroot"><a href="$this.threadroot_url">$*text_comment_threadroot</a></li>\n""";} if ($this.parent_url != "") { print safe """<li class="link commentparent"><a href="$this.parent_url">$*text_comment_parent</a></li>\n"""; } if ($this.thread_url != "") { print safe """ <a href="$this.thread_url">$*text_comment_thread</a></li>\n"""; }   var Link expand_link = $this->get_link("expand_comments"); if (defined $expand_link) { """ """;       $this->print_expand_link; """</li>\n"""; }   """</ul>"""; }

function Entry::print_link_next { var Link link = $this->get_link("nav_next"); if ($*entry_management_links == "text") { """<a href="$link.url">$link.caption</a>"""; }   else { " $link"; } } function Entry::print_link_prev { var Link link = $this->get_link("nav_prev"); if ($*entry_management_links == "text") { """<a href="$link.url">$link.caption</a>"""; }   else { " $link"; } } function Entry::print_management_links "Prints entry management links, aka prev/edit/tag/memory/tag/next, with standarized CSS." {   ## There's no point in showing previous/next links on pages which show ## multiple entries anyway, so we only print them on EntryPage and ReplyPage.

var Page p = get_page; var int count; var string extras; $count = 0; """<ul class="entry-management-links">"""; var bool show_interentry = ($p.view == "entry" or $p.view == "reply"); if ($show_interentry) { $count ++; """<li class="link link_prev first-item">"""; $this->print_link_prev; """</li>\n"""; }   var Link link; foreach var string k ($.link_keyseq) { $link = $this->get_link($k); if ($link.url) { $count ++; if ($*entry_management_links == "text") { foreach var string extra ( $link.extra ) { var string value = $link.extra{$extra}; $extras = $extras + "$extra='$value' "; }               """<li class="link $k""" + ( $count == 1 ? " first-item" : "" ) + """"><a href="$link.url" $extras>$link.caption</a></li>\n"""; }           else { ## if ($*entry_management_links == "icon") """<li class="link $k""" + ( $count == 1 ? " first-item" : "" ) + """">$link</li>\n"""; }       }    }    if ($show_interentry) { """<li class="link link_next">"""; $this->print_link_next; """</li>\n"""; }   """</ul>"""; } function Entry::print_interaction_links { $this->print_interaction_links( "" ); }

function Entry::print_interaction_links(string target) "Prints entry interaction links, aka # comments/leave a comment, with standardized CSS." {   var Page p = get_page; var int count; $count = 0; if ($p isa EntryPage) { """<ul class="entry-interaction-links">"""; var EntryPage ep = $p as EntryPage; if ($.comments.enabled and $ep.comment_pages.total_subitems > 0) { $count ++; """<li class="entry-readlink first-item">"""; $this.comments->print_readlink; "</li>\n"; }       if ($.comments.enabled) { $count ++; """<li class="entry-replylink""" + ( $count == 1 ? " first-item" : "" ) + """">"""; $ep->print_reply_link({ "linktext" => $*text_post_comment, "target" => $target }); "</li>\n"; }       "</ul>"; } else { $this.comments->print; }   }


 * 1) RecentPage and related functions

function RecentPage::print_body { # Creator for both the Recent and Friends views, since they are similar # If someone wants to do the two views differently, they can create # FriendsPage::print_body since FriendsPage extends RecentPage. """           """;        $this->print_navigation( { "class" => "topnav" } );

foreach var Entry e ($.entries) { # Print the entry if ( $e isa StickyEntry ) { var StickyEntry s = $e as StickyEntry; $this->print_sticky_entry($s); }        else { $this->print_entry($e); }   }

$this->print_navigation( { "class" => "bottomnav" } ); """   """;

}

function RecentPage::print_navigation( string{} opts ) [fixed] { var bool empty = $.nav.backward_url == "" and $.nav.forward_url == ""; """   <div class="navigation $opts{"class"}">    """;

if ( not $empty ) { "<ul>"; } if ( $.nav.backward_url != "" ) { print safe """<li class="page-back"><a href="$.nav.backward_url">""" + get_plural_phrase( $.nav.backward_count, "text_skiplinks_back" ) + "</a></li>\n"; }   if ( $.nav.backward_url != "" and $.nav.forward_url != "" ) { print safe """<li class="page-separator">|</li>"""; }   if ( $.nav.forward_url != "" ) { print safe """<li class="page-forward"><a href="$.nav.forward_url">""" + get_plural_phrase( $.nav.forward_count, "text_skiplinks_forward" ) + "</a></li>\n"; }   if ( not $empty ) { "</ul>"; } """   """; }

function secs_to_string (int sec) : string { if ($sec < 60) { return string($sec) + " seconds"; }  if ($sec < 3600) { return string($sec / 60) + " minutes"; }  if ($sec < 86400) { return string($sec / 3600) + " hours"; }  return string($sec / 86400) + " days"; }

function EntryLite::print_time(string datefmt, string timefmt) { print $this->time_display($datefmt, $timefmt); }

function EntryLite::time_display(string datefmt, string timefmt) : string { if ($datefmt == "") { $datefmt = "med"; }   if ($timefmt == "") { if ($this.timeformat24) { $timefmt = "short_24"; } else { $timefmt = "short"; }   }

var string ret; if ($datefmt != "none") { $ret = $ret + $this.time->date_format($datefmt); } if ($datefmt != "none" and $timefmt != "none") { $ret = $ret + " "; } if ($timefmt != "none") { $ret = $ret + $this.time->time_format($timefmt); }

return $ret; }

function Entry::time_display(string datefmt, string timefmt) : string { var Page p = get_page; var bool linkify = ( $p.view == "recent" or $p.view == "entry" or $p.view == "reply" or $p.view == "day" );

if ($datefmt == "") { $datefmt = "med"; }   if ($timefmt == "") { if ($this.timeformat24) { $timefmt = "short_24"; } else { $timefmt = "short"; }   }

var string ret; if ($datefmt != "none") { $ret = $ret + """ """ + $this.time->date_format($datefmt, $linkify) + " "; } if ($datefmt != "none" and $timefmt != "none") { $ret = $ret + " "; } if ($timefmt != "none") { $ret = $ret + """ """ + $this.time->time_format($timefmt) + " "; }

if ($ret != "") { $ret = """ $ret """; }

return $ret; }

function Comment::print_time (string datefmt, string timefmt, bool edittime) { print $this->time_display($datefmt, $timefmt, $edittime); } function Comment::time_display (string datefmt, string timefmt, bool edittime) : string { var DateTime time = ($edittime ? $this.edittime : $this.time); var DateTime time_remote = ($edittime ? $this.edittime_remote : $this.time_remote); var DateTime time_poster = ($edittime ? $this.edittime_poster : $this.time_poster);
 * 1) edittime argument is true if we want the get the edit time of the comment

if ($datefmt == "") { $datefmt = "iso"; }   if ($timefmt == "") { if ($this.timeformat24) { $timefmt = "short_24"; } else { $timefmt = "short"; }   }

var string tooltip = ""; if ($edittime == false) { var string etime = secs_to_string($this.seconds_since_entry); $tooltip = $etime + " after journal entry"; }

var string main;

var string display_date; var string display_time;

if ($time_remote) { $display_date = $time_remote->date_format($datefmt); if ($timefmt == "none") { $display_date = $display_date + " (local)"; } $display_time = $time_remote->time_format($timefmt) + " (local)"; } else { $display_date = $time->date_format($datefmt); if ($timefmt == "none") { $display_date = $display_date + " (UTC)"; } $display_time = $time->time_format($timefmt) + " (UTC)"; }

if (defined $time_poster and defined $this.poster) {       var string poster_date = $time_poster->date_format($datefmt); if ($edittime == false) { $tooltip = $tooltip + ", "; }

if ($poster_date == $display_date and $timefmt != "none") { $poster_date = ""; } else { $poster_date = $poster_date + " "; }

if ($timefmt != "none") { $tooltip = $tooltip + $poster_date + $time_poster->time_format($timefmt) + " (" + $this.poster.username + "'s time)"; } else { $tooltip = $tooltip + $poster_date + "(" + $this.poster.username + "'s time)"; }   }

if ($datefmt != "none") { $main = $main + $display_date; } if ($datefmt != "none" and $timefmt != "none") { $main = $main + " "; } if ($timefmt != "none") { $main = $main + $display_time; }

return "<span class=\"datetime\">" + $*text_comment_date + " <span title=\"" + ehtml($tooltip) + "\">" + ehtml($main) + " "; }

function Comment::print_time (string datefmt, string timefmt) { $this->print_time($datefmt, $timefmt, false); }

function Comment::time_display (string datefmt, string timefmt) : string { return $this->time_display($datefmt, $timefmt, false); }

function EntryLite::print_time { print $this->time_display; }

function EntryLite::time_display : string { # Let the real function decide on some nice defaults return $this->time_display("", ""); }

function Comment::print_edittime { print $this->edittime_display; }

function Comment::edittime_display : string { return $this->time_display("", "", true); }

function Comment::print_edittime (string datefmt, string timefmt){ print $this->edittime_display($datefmt, $timefmt); }

function Comment::edittime_display (string datefmt, string timefmt) : string { return $this->time_display($datefmt, $timefmt, true); }


 * 1) Year view

function YearPage::print_body { """           """;            $this->print_navigation( { "class" => "topnav" } ); """                   """;                    foreach var YearMonth m ($.months) { $this->print_month($m); }                   """            """;            $this->print_navigation( { "class" => "bottomnav" } ); """   """; }

function YearPage::print_navigation( string{} opts ) [fixed] { """   <div class="navigation $opts{"class"}">    """;

$this->print_year_links;

"""   """; }

function YearPage::print_year_links { if (size $.years) { """<ul>\n"""; foreach var YearYear y ($.years) { if ($y.displayed) { """ $y.year</li>\n"""; } else { """<li><a href="$y.url">$y.year</a></li>\n"""; }       }       """</ul>\n"""; } } function YearPage::print_month(YearMonth m) {

if (not $m.has_entries) { return; }

var string month_label = $m->month_format; """                   $month_label                         <a href="$m.url">$*text_view_month</a>    """; }

function YearWeek::print { " ";  if ($.pre_empty > 0) { """<td class="day-empty" colspan="$.pre_empty"> \n"""; }  foreach var YearDay d ($.days) { if ($d.num_entries > 0) { """           <td class="day day-has-entries">                $d.day                 <a href="$d.url">$d.num_entries</a>             """; } else { """               $d.day             """; }  }   if ($.post_empty > 0) { """<td class="day-empty" colspan="$.post_empty"> \n"""; }

" "; }

function MonthPage::view_title : string { return $.date->date_format($*lang_fmt_month_long); }

function MonthPage::print_body { """   """;    $this->print_navigation( { "class" => "topnav" } );

"""                                       """; foreach var MonthDay d ($.days) { if ($d.has_entries) { """<a href="$d.url">"""; print lang_ordinal($d.day); "</a></dt>";

"\n"; $d->print_subjectlist; "</dd>\n"; }   }                """                </dl>    """; $this->print_navigation( { "class" => "bottomnav" } ); """   """; }

function MonthPage::print_navigation( string{} opts ) [fixed] { """   <div class="navigation $opts{"class"}">            <ul>            <form method='post' action='$.redir.url'>            """;

$.redir->print_hiddens; if ($.prev_url != "") { "<li class='month-back'>[<a href='$.prev_url'>&lt;&lt;&lt;</a>]</li>\n"; }

if (size $.months > 1) { "<li><select name='redir_key'>\n"; foreach var MonthEntryInfo mei ($.months) { var string sel; if ($mei.date.year == $.date.year and $mei.date.month == $.date.month) { $sel = " selected='selected'"; }                   "<option value='$mei.redir_key'$sel>" + $mei.date->date_format($*lang_fmt_month_long) + " "; }               " \n<input type='submit' value='View' /></li>\n"; }

if ($.next_url != "") { "\n<li class='month-forward'>[<a href='$.next_url'>&gt;&gt;&gt;</a>]</li>\n"; }

"""           </ul>    """; }

function MonthDay::print_subjectlist { # Too many tables... var Page p = get_page; foreach var Entry e ($.entries) { if ($p.timeformat24) { $e->print_time("none", "short_24"); } else { $e->print_time("none", "short"); }       $e->print_poster; $e->print_metatypes; $e->print_subject; if ($e.comments.count > 0) { print safe " - " + get_plural_phrase($e.comments.count, "text_read_comments"); }       if ($e.comments.screened) { print safe " $*text_month_screened_comments"; }       " \n"; $e->print_tags; " \n"; } }


 * 1) Day view

function DayPage::print_body { """                   """;                    $this->print_navigation( { "class" => "topnav" } ); """                   """;                    print "<h3 class='day-date'>" + $.date->date_format( "long" ) + " "; if ($.has_entries) { foreach var Entry e ($.entries) { $this->print_entry($e); }                   } else { print safe "<div class=\"text_noentries text_noentries_day\">$*text_noentries_day "; }                   """                    """;                    $this->print_navigation( { "class" => "bottomnav" } ); """   """; }

function DayPage::print_navigation( string{} opts ) [fixed] { var bool empty = $.prev_url == "" and $.next_url == ""; """   <div class="navigation $opts{"class"}">    """; if ( not $empty ) { "<ul>"; } if ( $.prev_url != "" ) { print safe """<li class="page-back"><a href="$.prev_url">$*text_day_prev</a></li>\n"""; }   if ( $.next_url != "" ) { print safe """<li class="page-forward"><a href="$.next_url">$*text_day_next</a></li>\n"""; }   if ( not $empty ) { "</ul>"; }

"""   """; }


 * 1) CommentInfo functions

function CommentInfo::print_readlink { var Page p = get_page; print safe "<a href=\"$.read_url#comments\">"+ get_plural_phrase($.count, $p.view == "read" ?                         "text_read_comments_friends" : "text_read_comments")+ "</a>"; } function CommentInfo::print_postlink { var Page p = get_page; if ($.maxcomments) { print safe "$*text_max_comments"; } else { print safe "<a href=\"$.post_url\">"+($p.view == "read" or $p.view == "network" ? $*text_post_comment_friends : $*text_post_comment)+"</a>"; } } function CommentInfo::print { """<ul class="entry-interaction-links">\n"""; """<li class="entry-permalink first-item"><a href="$.permalink_url">$*text_permalink</a></li>\n"""; if ($.show_readlink) { """<li class="entry-readlink">"""; $this->print_readlink; "</li>\n"; }       if ($.show_postlink and $.enabled) { """<li class="entry-replylink">"""; $this->print_postlink; "</li>\n"; }       "</ul>"; }


 * 1) Link object functions

function Link::print_button [fixed] { print $this->as_string; }

function Link::as_string [fixed] : string { if ($.url == "") { return ""; } var string ealt = ehtml($.caption); var string{} extraLink = $.extra; var string{} extraImg = $.icon.extra; var string extraParamsLink = ""; var string extraParamsImg = "";

foreach var string extraKeyLink ($extraLink) { $extraParamsLink = $extraParamsLink + """$extraKeyLink="$extraLink{$extraKeyLink}" """; }

foreach var string extraKeyImg ($extraImg) { $extraParamsImg = $extraParamsImg + """$extraKeyImg="$extraImg{$extraKeyImg}" """; }

return """<a href="$.url" $extraParamsLink><img border='0' width="$.icon.width" height="$.icon.height" alt="$ealt" title="$ealt" src="$.icon.url" $extraParamsImg /></a>"""; }


 * 1) Redirector

function Redirector::start_form {   "<form method='post' action='$.url' style='display: inline'>"; $this->print_hiddens; } function Redirector::print_hiddens {   "<input type='hidden' name='redir_user' value='$.user' />\n"; "<input type='hidden' name='redir_vhost' value='$.vhost' />\n"; "<input type='hidden' name='redir_type' value='$.type' />\n"; } function Redirector::end_form {   " "; }


 * 1) EntryPage functions

function EntryPage::print_comment_section(Entry e) { " ";   $.comment_pages->print({ "anchor" => "comments", "class" => "comment-pages" }); if ( $e.comments.comments_disabled_maintainer ) { """ $*text_comments_disabled_maintainer """; }   if ($.comment_pages.total_subitems > 0) { $this->print_multiform_start; }  $this->print_comments($.comments); if ($.comment_pages.total_subitems > 0) { " ";       $e->print_management_links; $e->print_interaction_links("bottomcomment"); $this->print_reply_container({ "target" => "bottomcomment" }); $this->print_multiform_actionline; $this->print_multiform_end; " ";  }   $.comment_pages->print({ "anchor" => "comments", "class" => "comment-pages" }); " "; }

function EntryPage::print_comments (Comment[] cs) { if (size $cs == 0) { return; } foreach var Comment c ($cs) { var string parity = $c.depth % 2 ? "odd" : "even"; var int indent = ($c.depth - 1) * 25; "<div class='comment-thread comment-depth-$parity comment-depth-$c.depth'>\n"; "<div id='$c.dom_id' style='margin-left: ${indent}px; margin-top: 5px'>\n"; if ($c.full) { $this->print_comment($c); } else { $this->print_comment_partial($c); }       " ";        $this->print_comments($c.replies); " ";    } }

function ReplyPage::print_comment (Comment c) {
 * 1) ReplyPage and EntryPage work nicest if they output the same structure for printing comments and entries, but this requires to manually change both ReplyPage::print_comment and EntryPage::print_comment.  Layout authors can also choose to override separately for different structures.
 * 2) Note that there is no multiform check on the ReplyPage.

$c->print_wrapper_start; """ \n"""; $c->print_subject; $c->print_metatypes; $c->print_time; """ \n"""; """ \n"""; """ \n"""; $c->print_userpic; """ \n"""; $c->print_poster; $c->print_metadata; """ \n"""; $c->print_text; """ \n"""; """ \n"""; """ \n"""; """ \n"""; $c->print_management_links; $c->print_interaction_links; $c->print_reply_container; " \n \n"; $c->print_wrapper_end; }

function EntryPage::print_comment (Comment c) {
 * 1) ReplyPage and EntryPage work nicest if they output the same structure for printing comments and entries, but this requires to manually change both ReplyPage::print_comment and EntryPage::print_entry.  Layout authors can also choose to override separately for different structures.

$c->print_wrapper_start; """ \n"""; $c->print_subject; $c->print_metatypes; $c->print_time; """ \n"""; """ \n"""; """ \n"""; $c->print_userpic; $c->print_poster; $c->print_metadata; $c->print_text; """ \n"""; """ \n"""; """ \n"""; """ \n"""; if ($this.multiform_on) { """ """;       print safe " <label for='ljcomsel_$c.talkid'>$*text_multiform_check "; $c->print_multiform_check; " ";   }    $c->print_management_links; $c->print_interaction_links; $c->print_reply_container; " \n \n"; $c->print_wrapper_end; }

function EntryPage::print_comment_partial (Comment c) { $c->print_wrapper_start; if ($c.deleted) { print $*text_deleted; } elseif ($c.fromsuspended) { print $*text_fromsuspended; } else { var string poster = defined $c.poster ? $c.poster->as_string : "$*text_poster_anonymous"; $c->print_subject; print safe " - $poster"; var Link expand_link = $c->get_link("expand_comments"); if (defined $expand_link) { " "; $c->print_expand_link; }   }    $c->print_wrapper_end; }

function ItemRange::print { $this->print({ "anchor" => "", "class" => "" }); }

function ItemRange::print(string{} opts) { if ($.all_subitems_displayed) { return; }

var string anchor = $opts{"anchor"} ? "#$opts{"anchor"}" : ""; var string class = $opts{"class"} ? $opts{"class"} : "pages";

"""<div class="$class">"""; print "" + lang_page_of_pages($.current, $.total) + ""; var string url_prev = $this->url_of($.current - 1); if ($.current != 1) { print " <a href='$url_prev$anchor'>$*comment_page_prev</a> "; } else { print " $*comment_page_prev "; }   foreach var int i (1..$.total) { if ($i == $.current) { "[$i] "; } else { var string url_of = $this->url_of($i); "<a href='$url_of$anchor'>[$i]</a> "; }   }    var string url_next = $this->url_of($.current + 1); if ($.current != $.total) { print " <a href='$url_next$anchor'>$*comment_page_next</a> "; } else { print " $*comment_page_next "; }   " "; }

function EntryPage::print_body {   var Entry e = $.entry; $this->print_entry($e); $this->print_comment_section($e); }

function ReplyPage::print_body {   if (not $.entry.comments.enabled) { print safe " $*text_reply_nocomments_header $*text_reply_nocomments "; return; }

if ($.replyto isa Entry) { var Entry e = $.replyto as Entry; $this->print_entry($e); }   elseif ($.replyto isa Comment) { var Comment c = $.replyto as Comment; $this->print_comment($c); }   $.form->print; }


 * 1) TagsPage functions

function TagsPage::print_body {   print safe " $*text_tags_page_header ";

if ($*tags_page_type == "multi") { print_multilevel_tags($.tags, { "list-class" => "ljtaglist tags_multilevel", "print_uses" => $*tags_page_count_type }); print_tag_manage_link; }   elseif ($*tags_page_type == "cloud") { print_cloud_tags($.tags, { "list-class" => "ljtaglist tags_cloud", "print_uses" => $*tags_page_count_type }); print_tag_manage_link; }   else { print_list_tags($.tags, { "list-class" => "ljtaglist tags_list", "print_uses" => $*tags_page_count_type }); print_tag_manage_link; }   print safe " "; }


 * 1) MessagePage functions

function MessagePage::view_title : string { return $.title; }

function MessagePage::print_body { $this->print_links; $this->print_message; }

function MessagePage::print_message { print $.message; }

function MessagePage::print_links { println """ """; foreach var string k ($.link_keyseq) { println """ $.links{$k} """; }   println """ """; }