2797 lines
68 KiB
Text
2797 lines
68 KiB
Text
|
|
# -*-s2-*-
|
||
|
|
layerinfo "type" = "layout";
|
||
|
|
layerinfo "name" = "Zesty";
|
||
|
|
layerinfo "lang" = "en";
|
||
|
|
layerinfo "author" = "Sam Angove";
|
||
|
|
layerinfo "author_email" = "net.rephrase@sam";
|
||
|
|
layerinfo "is_public" = 1;
|
||
|
|
layerinfo "source_viewable" = 1;
|
||
|
|
layerinfo "redist_uniq" = "zesty/layout";
|
||
|
|
|
||
|
|
###################################################
|
||
|
|
# #
|
||
|
|
# [S2] Zesty #
|
||
|
|
# #
|
||
|
|
# Table of Contents #
|
||
|
|
# ================= #
|
||
|
|
# #
|
||
|
|
# ~i. Changelog #
|
||
|
|
# ~ii. License #
|
||
|
|
# ~iii. Notes #
|
||
|
|
# #
|
||
|
|
# Customization/i18n Properties #
|
||
|
|
# ----------------------------- #
|
||
|
|
# ~1. Properties #
|
||
|
|
# #
|
||
|
|
# Utility functions #
|
||
|
|
# ----------------- #
|
||
|
|
# ~2. Utility functions #
|
||
|
|
# #
|
||
|
|
# CSS #
|
||
|
|
# --- #
|
||
|
|
# ~3. Stylesheet #
|
||
|
|
# #
|
||
|
|
# Shared methods #
|
||
|
|
# -------------- #
|
||
|
|
# Methods used on multiple views for getting or #
|
||
|
|
# printing information about entries. #
|
||
|
|
# #
|
||
|
|
# ~4. EntryLite #
|
||
|
|
# ~5. CommentInfo #
|
||
|
|
# ~6. Entry #
|
||
|
|
# #
|
||
|
|
# Global view #
|
||
|
|
# ----------- #
|
||
|
|
# Templates used on all views as well as methods #
|
||
|
|
# overridden by specific views. #
|
||
|
|
# #
|
||
|
|
# ~7. Page #
|
||
|
|
# #
|
||
|
|
# Regular views #
|
||
|
|
# ------------- #
|
||
|
|
# These four views have substantially similar #
|
||
|
|
# logic. #
|
||
|
|
# #
|
||
|
|
# ~8. RecentPage #
|
||
|
|
# ~9. FriendsPage #
|
||
|
|
# ~10. DayPage #
|
||
|
|
# ~11. MonthPage #
|
||
|
|
# #
|
||
|
|
# Entry views #
|
||
|
|
# ----------- #
|
||
|
|
# These views require significant extra logic. #
|
||
|
|
# They are not available to free users. #
|
||
|
|
# #
|
||
|
|
# ~12. EntryPage #
|
||
|
|
# ~13. ReplyPage #
|
||
|
|
# #
|
||
|
|
# Miscellaneous views #
|
||
|
|
# ------------------- #
|
||
|
|
# These views cannot print entries. #
|
||
|
|
# #
|
||
|
|
# ~14. YearPage #
|
||
|
|
# ~15. MessagePage #
|
||
|
|
# ~16. TagsPage #
|
||
|
|
# #
|
||
|
|
###################################################
|
||
|
|
|
||
|
|
###################################################
|
||
|
|
# # #
|
||
|
|
# ~i. # ~Changelog #
|
||
|
|
# # #
|
||
|
|
###################################################
|
||
|
|
|
||
|
|
# 2006-07-18 -- I can't remember, but I'm releasing it now. ;)
|
||
|
|
# 2006-07-10 -- English stripping
|
||
|
|
# 2006-07-09 -- general cleanup, fix footer
|
||
|
|
# 2006-07-03 -- initial build
|
||
|
|
#
|
||
|
|
|
||
|
|
###################################################
|
||
|
|
# # #
|
||
|
|
# ~ii. # ~License #
|
||
|
|
# # #
|
||
|
|
###################################################
|
||
|
|
|
||
|
|
# "Zesty" LiveJournal S2 style
|
||
|
|
#
|
||
|
|
# Copyright (c) 2006 Sam Angove
|
||
|
|
#
|
||
|
|
# This program 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.
|
||
|
|
#
|
||
|
|
# This program is distributed in the hope that it will be useful,
|
||
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
|
# GNU General Public License for more details.
|
||
|
|
#
|
||
|
|
# You should have received a copy of the GNU General Public License along
|
||
|
|
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||
|
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||
|
|
|
||
|
|
###################################################
|
||
|
|
# # #
|
||
|
|
# ~ii. # ~Notes #
|
||
|
|
# # #
|
||
|
|
###################################################
|
||
|
|
|
||
|
|
# - The CSS is very messy. Haven't had time to clean it up. Sorry!
|
||
|
|
#
|
||
|
|
# - Most customization properties are for i18n purposes. Note that many of
|
||
|
|
# them use the `lay_string_placeholders()` function; it's not wholly
|
||
|
|
# satisfactory but it's more flexible than the core.
|
||
|
|
#
|
||
|
|
# - There are no props for colours, borders etc. It's a huge headache and
|
||
|
|
# I can't be bothered. Since this isn't a core style, no-one but a paid
|
||
|
|
# user can use it anyway, and they'll be able to edit the CSS directly.
|
||
|
|
#
|
||
|
|
# - I have deliberately ignored OOP and used
|
||
|
|
# `View::lay_print_obj(Obj o)` over `var Obj o; $o->print()`
|
||
|
|
# wherever possible. It's usually futile to use the latter because
|
||
|
|
# the method needs to be overridable in different views -- different
|
||
|
|
# requirements for entry printing on MonthPage and EntryPage, for example.
|
||
|
|
#
|
||
|
|
# Global functions have been avoided for the same reason.
|
||
|
|
|
||
|
|
|
||
|
|
###################################################
|
||
|
|
# # #
|
||
|
|
# !1. # !Properties #
|
||
|
|
# # #
|
||
|
|
###################################################
|
||
|
|
|
||
|
|
propgroup presentation {
|
||
|
|
property use num_items_recent;
|
||
|
|
property use num_items_reading;
|
||
|
|
property use num_items_icons;
|
||
|
|
property use use_journalstyle_entry_page;
|
||
|
|
property use tags_page_type;
|
||
|
|
property use icons_page_sort;
|
||
|
|
property use use_shared_pic;
|
||
|
|
property use userlite_interaction_links;
|
||
|
|
property use entry_management_links;
|
||
|
|
property use comment_management_links;
|
||
|
|
property use medium_breakpoint_width;
|
||
|
|
property use large_breakpoint_width;
|
||
|
|
}
|
||
|
|
|
||
|
|
set num_items_recent = 10;
|
||
|
|
set num_items_reading = 20;
|
||
|
|
|
||
|
|
propgroup Text {
|
||
|
|
property use text_day_next;
|
||
|
|
property use text_day_prev;
|
||
|
|
property use text_skiplinks_back;
|
||
|
|
property use text_skiplinks_forward;
|
||
|
|
|
||
|
|
property use text_permalink;
|
||
|
|
property use text_stickyentry_subject;
|
||
|
|
property use text_post_comment;
|
||
|
|
property use text_post_comment_friends;
|
||
|
|
|
||
|
|
set text_permalink = "permalink";
|
||
|
|
set text_stickyentry_subject = "Sticky:";
|
||
|
|
set text_post_comment = "reply";
|
||
|
|
set text_post_comment_friends = "reply";
|
||
|
|
|
||
|
|
property use text_nosubject;
|
||
|
|
property use text_poster_anonymous;
|
||
|
|
|
||
|
|
set text_nosubject = "(no subject)";
|
||
|
|
set text_poster_anonymous = "(anonymous)";
|
||
|
|
|
||
|
|
property use text_meta_mood;
|
||
|
|
property use text_meta_music;
|
||
|
|
|
||
|
|
set text_meta_mood = "Mood:";
|
||
|
|
set text_meta_music = "Music:";
|
||
|
|
|
||
|
|
property use text_view_archive;
|
||
|
|
property use text_view_recent;
|
||
|
|
property use text_view_friends;
|
||
|
|
property use text_view_friends_comm;
|
||
|
|
property use text_view_month;
|
||
|
|
property use text_view_userinfo;
|
||
|
|
|
||
|
|
set text_view_archive = "Calendar";
|
||
|
|
set text_view_recent = "Recent";
|
||
|
|
set text_view_friends = "Read";
|
||
|
|
set text_view_month = "Monthly Archive";
|
||
|
|
set text_view_userinfo = "Profile";
|
||
|
|
|
||
|
|
|
||
|
|
# For these properties I use a format vaguely similar to printf/sprintf.
|
||
|
|
# They're passed to a method which gives them an array of strings.
|
||
|
|
# you can use printf-style %s to insert the strings one at a time, or
|
||
|
|
# use %1, %2 .. %9 to select them by number.
|
||
|
|
#
|
||
|
|
# Example: this string "posted by %1 at %2 on %3" is passed an array
|
||
|
|
# containing the entry poster, the time of posting and the date of
|
||
|
|
# posting.
|
||
|
|
#
|
||
|
|
# %1 will always refer to the poster, so a reformulation might be
|
||
|
|
# something like "at %2 on %3, %1 wrote:".
|
||
|
|
#
|
||
|
|
# It's perfectly okay to ignore some or all of the arguments. That is,
|
||
|
|
# there's nothing wrong with something like "I said on %3".
|
||
|
|
|
||
|
|
property string posted_by_at_on {
|
||
|
|
noui = 1;
|
||
|
|
des = "Posted by [1:poster] at [2:time] on [3:date] string.";
|
||
|
|
}
|
||
|
|
set posted_by_at_on = "posted by %1 at %2 on %3";
|
||
|
|
|
||
|
|
property string posted_by_at_on_in {
|
||
|
|
noui = 1;
|
||
|
|
des = "Posted by [1:poster] at [2:time] on [3:date] under [4:tags] string.";
|
||
|
|
}
|
||
|
|
set posted_by_at_on_in = "posted by %1 at %2 on %3 under %4";
|
||
|
|
|
||
|
|
property string posted_by_at_on_from {
|
||
|
|
noui = 1;
|
||
|
|
des = "Posted by [1:poster] at [2:time] on [3:date] from [4:ip address] string.";
|
||
|
|
}
|
||
|
|
set posted_by_at_on_from = "posted by %1 at %2 on %3 from %4";
|
||
|
|
|
||
|
|
property string poster_in_journal {
|
||
|
|
noui = 1;
|
||
|
|
des = "[1:poster] in [2:journal] string";
|
||
|
|
}
|
||
|
|
set poster_in_journal = "%1 in %2";
|
||
|
|
|
||
|
|
property string posted_time_format {
|
||
|
|
noui = 1;
|
||
|
|
des = "[time] format for from 'posted by [poster] at [time] ...'";
|
||
|
|
}
|
||
|
|
set posted_time_format = "%%hh%%:%%min%%%%a%%m";
|
||
|
|
|
||
|
|
property string posted_time_format_24 {
|
||
|
|
noui = 1;
|
||
|
|
des = "[time] format for from 'posted by [poster] at [time] ...'";
|
||
|
|
}
|
||
|
|
set posted_time_format_24 = "%%HH%%:%%min%%";
|
||
|
|
|
||
|
|
property string posted_date_format {
|
||
|
|
noui = 1;
|
||
|
|
des = "[date] format for 'posted by [poster] at [time] on [date] ...'";
|
||
|
|
}
|
||
|
|
set posted_date_format = "%%dd%%/%%mm%%/%%yyyy%%";
|
||
|
|
|
||
|
|
|
||
|
|
# I want to have links like this:
|
||
|
|
#
|
||
|
|
# There are <a href="...">2 comments</a> on this entry.
|
||
|
|
#
|
||
|
|
# The HTML can't be part of the property, because S2 "helpfully" escapes
|
||
|
|
# it for me. This ugly hack is used instead, wrapping $*text_a_comment_link
|
||
|
|
# inside $*text_a_comment.
|
||
|
|
#
|
||
|
|
# ('There is <a href="%1">%2 comment</a> on this entry.')
|
||
|
|
property string text_a_comment_link { }
|
||
|
|
property string text_a_comment { }
|
||
|
|
set text_a_comment_link = "%1 comment";
|
||
|
|
set text_a_comment = "There is %1 on this entry.";
|
||
|
|
|
||
|
|
property string text_some_comments_link { }
|
||
|
|
property string text_some_comments { }
|
||
|
|
set text_some_comments_link = "%1 comments";
|
||
|
|
set text_some_comments = "There are %1 on this entry.";
|
||
|
|
|
||
|
|
property string text_some_comments_over_pages { }
|
||
|
|
set text_some_comments_over_pages = "There are %1 over %2 pages.";
|
||
|
|
|
||
|
|
property string text_no_comments {}
|
||
|
|
set text_no_comments = "There are no comments on this entry.";
|
||
|
|
|
||
|
|
property string text_comments_disabled {}
|
||
|
|
set text_comments_disabled = "Comments are disabled.";
|
||
|
|
|
||
|
|
property string text_errorpage_title {
|
||
|
|
des = "Error page title.";
|
||
|
|
noui = 1;
|
||
|
|
}
|
||
|
|
set text_errorpage_title = "No content";
|
||
|
|
|
||
|
|
|
||
|
|
# For some reason the core only provides a message for recent and day pages.
|
||
|
|
#
|
||
|
|
property string error_monthpage_no_entries {
|
||
|
|
noui = 1;
|
||
|
|
des = "Error message shown if no entries are available on a MonthPage";
|
||
|
|
}
|
||
|
|
set error_monthpage_no_entries = "No entries were posted on the selected month.";
|
||
|
|
|
||
|
|
property string error_yearpage_no_entries {
|
||
|
|
noui = 1;
|
||
|
|
des = "Error message shown if no entries are available on a YearPage";
|
||
|
|
}
|
||
|
|
set error_yearpage_no_entries = "No entries were posted on the selected year.";
|
||
|
|
|
||
|
|
property string text_html_title {
|
||
|
|
des = "Title that goes in the HTML <title> element. Is given two parameters, global title and view title.";
|
||
|
|
}
|
||
|
|
set text_html_title = "%2 [%1]";
|
||
|
|
|
||
|
|
property string collapsed_entry_comments_disabled {
|
||
|
|
des = "String shown on a collapsed entry if comments are disabled.";
|
||
|
|
}
|
||
|
|
set collapsed_entry_comments_disabled = "(-)";
|
||
|
|
|
||
|
|
property string collapsed_entry_comments_max_flag {
|
||
|
|
des = "Passed into the comment-count string as %2 if an entry's maximum comments have been reached.";
|
||
|
|
}
|
||
|
|
set collapsed_entry_comments_max_flag = "!";
|
||
|
|
property string collapsed_entry_comments_screened_flag {
|
||
|
|
des = "Passed into the comment-count string as %3 if an entry has screened comments visible to the user.";
|
||
|
|
}
|
||
|
|
set collapsed_entry_comments_screened_flag = "*";
|
||
|
|
|
||
|
|
property string collapsed_entry_comments_count {
|
||
|
|
des = "Comment-count shown on a collapsed entry, not shown if there are no comments.";
|
||
|
|
note = "'%1' will be replaced by the number of comments. If the maximum number of comments
|
||
|
|
has been reached, %2 will contain the max flag. If there are screened comments visible to
|
||
|
|
the user, %3 will contain the screened flag.";
|
||
|
|
}
|
||
|
|
set collapsed_entry_comments_count = "(%1%2%3)";
|
||
|
|
|
||
|
|
property string linklist_default_title {
|
||
|
|
des = "Linklist title.";
|
||
|
|
}
|
||
|
|
set linklist_default_title = "Links";
|
||
|
|
|
||
|
|
property string reply_link_link_text {
|
||
|
|
des = "Text for the reply link.";
|
||
|
|
}
|
||
|
|
set reply_link_link_text = "Reply";
|
||
|
|
|
||
|
|
property string reply_link_text {
|
||
|
|
des = "Non-linked reply link text. %1 is replaced with the link.";
|
||
|
|
}
|
||
|
|
set reply_link_text = "(%1.)";
|
||
|
|
|
||
|
|
property string top_link_text {
|
||
|
|
des = "Text of the link to return to the top of the page.";
|
||
|
|
}
|
||
|
|
set top_link_text = "Top";
|
||
|
|
|
||
|
|
property use text_comment_frozen;
|
||
|
|
property use text_comment_parent;
|
||
|
|
property use text_comment_reply;
|
||
|
|
|
||
|
|
set text_comment_frozen = "thread is frozen";
|
||
|
|
set text_comment_parent = "parent";
|
||
|
|
set text_comment_reply = "reply";
|
||
|
|
|
||
|
|
|
||
|
|
property string text_comment_permalink {
|
||
|
|
des = "Permalink to the comment.";
|
||
|
|
}
|
||
|
|
set text_comment_permalink = "link";
|
||
|
|
|
||
|
|
property string text_comment_poster_is_suspended {
|
||
|
|
des = "Show on comments posted by suspended users.";
|
||
|
|
note = "Due to limitations in S2 this text will only be displayed if the comment is shown directly, i.e. as the focus of the thread.";
|
||
|
|
}
|
||
|
|
set text_comment_poster_is_suspended = "user is suspended";
|
||
|
|
|
||
|
|
property string text_comment_parent_entry {
|
||
|
|
des = "Text for linking to a comment's parent.";
|
||
|
|
}
|
||
|
|
set text_comment_parent_entry = "parent entry";
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
propgroup Miscellaneous {
|
||
|
|
|
||
|
|
property string custom_favicon {
|
||
|
|
des = "URL of custom favicon.";
|
||
|
|
example = "http://example.com/favicon.ico";
|
||
|
|
}
|
||
|
|
set custom_favicon = "";
|
||
|
|
|
||
|
|
property string default_view_mode {
|
||
|
|
des = "Show entries expanded or collapsed by default. Currently this setting affects the reading page only.";
|
||
|
|
values = "collapsed|Entries collapsed|expanded|Entries expanded";
|
||
|
|
}
|
||
|
|
set default_view_mode = "expanded";
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
#
|
||
|
|
# Yes, tags are enabled.
|
||
|
|
#
|
||
|
|
set tags_aware = true;
|
||
|
|
|
||
|
|
###################################################
|
||
|
|
# # #
|
||
|
|
# !2. # Utility functions. #
|
||
|
|
# # #
|
||
|
|
###################################################
|
||
|
|
|
||
|
|
|
||
|
|
# Converts an associative array to an argument list:
|
||
|
|
#
|
||
|
|
# var string var = {"id" => "5", "page" => "b"};
|
||
|
|
# lay_array_to_args($var);
|
||
|
|
#
|
||
|
|
# "?id=5&page=b"
|
||
|
|
#
|
||
|
|
function lay_array_to_args(string{} items) : string
|
||
|
|
"Converts an associative array to an argument list, i.e. {\"id\" => \"5\", \"page\" => \"b\"} => ?id=5&page=b"
|
||
|
|
{
|
||
|
|
var string args;
|
||
|
|
var bool q = false;
|
||
|
|
|
||
|
|
foreach var string key ($items) {
|
||
|
|
if ($key != "") {
|
||
|
|
if (not $q) {
|
||
|
|
$args = "?";
|
||
|
|
$q = true;
|
||
|
|
} else {
|
||
|
|
$args = $args + "&";
|
||
|
|
}
|
||
|
|
$args = $args + "$key=" + $items{"$key"};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return $args;
|
||
|
|
}
|
||
|
|
|
||
|
|
# pushes a string on to the end of an array, assuming that it's
|
||
|
|
# indexed naturally from zero.
|
||
|
|
#
|
||
|
|
function lay_array_push(string[] input, string add) : string[]
|
||
|
|
"Pushes a new element on to the end of an array."
|
||
|
|
{
|
||
|
|
$input[size $input] = $add;
|
||
|
|
return $input;
|
||
|
|
}
|
||
|
|
|
||
|
|
# A bit like sprintf, this inserts an array of strings into a string.
|
||
|
|
# Knows %s, literal %%, and numbered placeholders %1 .. %9.
|
||
|
|
#
|
||
|
|
function lay_string_placeholders( string format, string[] args ) : string
|
||
|
|
"A bit like sprintf, this inserts an array of strings into a string.
|
||
|
|
Handles %s, literal %%, and numbered placeholders %1 .. %9."
|
||
|
|
{
|
||
|
|
var string output = "";
|
||
|
|
|
||
|
|
var bool state_found_placeholder = false;
|
||
|
|
var int found_count = 0;
|
||
|
|
|
||
|
|
foreach var string s ($format) {
|
||
|
|
if ( $state_found_placeholder ) {
|
||
|
|
if ( $s == "%" ) {
|
||
|
|
$output = $output + $s;
|
||
|
|
}
|
||
|
|
# string placeholder
|
||
|
|
elseif ( $s == "s" ) {
|
||
|
|
$output = $output + $args[$found_count];
|
||
|
|
$found_count++;
|
||
|
|
$state_found_placeholder = false;
|
||
|
|
}
|
||
|
|
# numbered placeholder
|
||
|
|
elseif ( $s == "1" or $s == "2" or $s == "3" or $s == "4" or $s == "5" or $s == "6" or $s == "7" or $s == "8" or $s == "9" ) {
|
||
|
|
$output = $output + $args[int($s) - 1];
|
||
|
|
$state_found_placeholder = false;
|
||
|
|
}
|
||
|
|
} elseif ( $s == "%" ) {
|
||
|
|
$state_found_placeholder = true;
|
||
|
|
} else {
|
||
|
|
$output = $output + $s;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return $output;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
# Returns the current url plus arguments. Needs to be overridden
|
||
|
|
# on most views where it's used.
|
||
|
|
#
|
||
|
|
function Page::lay_build_url(string{} items) : string {
|
||
|
|
return $.base_url + lay_array_to_args($items);
|
||
|
|
}
|
||
|
|
|
||
|
|
# For paid user override in theme layers
|
||
|
|
function lay_print_extra_boxes() : void
|
||
|
|
"Paid users can override this in theme layers to easily add content in the 'extra boxes' section of the footer."
|
||
|
|
{ }
|
||
|
|
|
||
|
|
###################################################
|
||
|
|
# # #
|
||
|
|
# !3. # Stylesheet. #
|
||
|
|
# # #
|
||
|
|
###################################################
|
||
|
|
|
||
|
|
function print_stylesheet() {
|
||
|
|
var string medium_media_query = generate_medium_media_query();
|
||
|
|
var string large_media_query = generate_large_media_query();
|
||
|
|
|
||
|
|
"""
|
||
|
|
|
||
|
|
html, body {
|
||
|
|
margin: 0;
|
||
|
|
padding: 0;
|
||
|
|
font-family: Verdana, sans-serif;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* regular links */
|
||
|
|
|
||
|
|
a {
|
||
|
|
color: #2452FF;
|
||
|
|
}
|
||
|
|
a:visited {
|
||
|
|
color: #142D8B;
|
||
|
|
}
|
||
|
|
a:active, a:hover {
|
||
|
|
color: #178FFF;
|
||
|
|
}
|
||
|
|
|
||
|
|
img {
|
||
|
|
border: 0px;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/* the main header */
|
||
|
|
|
||
|
|
#header {
|
||
|
|
background: #eee;
|
||
|
|
padding: 20px 10px 20px 10px;
|
||
|
|
margin: 0px;
|
||
|
|
}
|
||
|
|
#header h1 {
|
||
|
|
font-weight: normal;
|
||
|
|
font-family: Georgia, serif;
|
||
|
|
font-size: 2.5em;
|
||
|
|
color: #333;
|
||
|
|
margin: 0px;
|
||
|
|
padding: 20px 0 0 0;
|
||
|
|
}
|
||
|
|
#header p {
|
||
|
|
color: #999;
|
||
|
|
font: 1.2em normal Verdana, sans-serif;
|
||
|
|
margin-top: 5px;
|
||
|
|
}
|
||
|
|
|
||
|
|
@media $medium_media_query {
|
||
|
|
font-size: 4em;
|
||
|
|
padding: 40px 0 0 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* the navigation menu */
|
||
|
|
|
||
|
|
/*
|
||
|
|
This had to be hacked up to work with IE and I haven't gotten around
|
||
|
|
to cleaning it up yet. Sorry!
|
||
|
|
*/
|
||
|
|
|
||
|
|
#navi {
|
||
|
|
float:left;
|
||
|
|
width:100%;
|
||
|
|
background: #fff;
|
||
|
|
line-height:normal;
|
||
|
|
font: normal 0.6em Verdana, sans-serif;
|
||
|
|
color: #666;
|
||
|
|
}
|
||
|
|
#navi ul {
|
||
|
|
margin:0;
|
||
|
|
padding:0px 10px 0 5px;
|
||
|
|
list-style:none;
|
||
|
|
}
|
||
|
|
#navi li {
|
||
|
|
display:block;
|
||
|
|
float:left;
|
||
|
|
margin: 0 0 0 0;
|
||
|
|
padding:0;
|
||
|
|
text-align: center;
|
||
|
|
border-top: 1px solid #bbb;
|
||
|
|
}
|
||
|
|
|
||
|
|
#navi span {
|
||
|
|
float:left;
|
||
|
|
display:block;
|
||
|
|
padding:4px 12px 5px 10px;
|
||
|
|
margin: 0 1px 0 1px;
|
||
|
|
}
|
||
|
|
#navi a {
|
||
|
|
display: block;
|
||
|
|
color: #666;
|
||
|
|
text-decoration: none;
|
||
|
|
background: #ddd;
|
||
|
|
float: left;
|
||
|
|
padding: 0;
|
||
|
|
margin-right: 1px;
|
||
|
|
border-bottom: 1px solid white;
|
||
|
|
}
|
||
|
|
|
||
|
|
#navi a:hover,
|
||
|
|
#navi a:active {
|
||
|
|
background: #888;
|
||
|
|
color: #fff;
|
||
|
|
}
|
||
|
|
|
||
|
|
#navi li#tab-current {
|
||
|
|
border-top: 1px solid #eee;
|
||
|
|
}
|
||
|
|
|
||
|
|
#navi li#tab-current a {
|
||
|
|
display: inline;
|
||
|
|
float: none;
|
||
|
|
background: #eee;
|
||
|
|
border: 0;
|
||
|
|
margin: 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
#navi li#tab-current span {
|
||
|
|
background: #eee;
|
||
|
|
border-bottom: 1px solid #eee;
|
||
|
|
color: #555;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* back-and-forward navigation */
|
||
|
|
|
||
|
|
.back-forward {
|
||
|
|
width: 100%;
|
||
|
|
float: left;
|
||
|
|
clear: both;
|
||
|
|
}
|
||
|
|
.back-forward a, .back-forward a:visited {
|
||
|
|
color: #999;
|
||
|
|
text-decoration: none;
|
||
|
|
}
|
||
|
|
|
||
|
|
.back-forward a:active,
|
||
|
|
.back-forward a:hover {
|
||
|
|
color: #333;
|
||
|
|
}
|
||
|
|
.back-forward .back,
|
||
|
|
.back-forward .forward {
|
||
|
|
padding: 10px;
|
||
|
|
font: normal 2em Verdana, sans-serif;
|
||
|
|
|
||
|
|
}
|
||
|
|
.back-forward .back {
|
||
|
|
float: left;
|
||
|
|
clear: left;
|
||
|
|
}
|
||
|
|
.back-forward .forward {
|
||
|
|
float: right;
|
||
|
|
clear: right;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/* global footer */
|
||
|
|
|
||
|
|
#footer {
|
||
|
|
color: #999;
|
||
|
|
font: 0.6em normal Verdana, sans-serif;
|
||
|
|
margin: 0;
|
||
|
|
text-align: right;
|
||
|
|
padding: 10px 5px 5px 5px;
|
||
|
|
background-color: #fff;
|
||
|
|
clear: both;
|
||
|
|
}
|
||
|
|
|
||
|
|
.top-link {
|
||
|
|
float: left;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* extra boxes below main content */
|
||
|
|
|
||
|
|
.extra-box {
|
||
|
|
margin: 20px;
|
||
|
|
padding: 10px;
|
||
|
|
}
|
||
|
|
.extra-box > ul {
|
||
|
|
list-style-type: square;
|
||
|
|
margin: 0;
|
||
|
|
padding: 2px 2px 2px 10px;
|
||
|
|
}
|
||
|
|
.extra-box .title {
|
||
|
|
color: #3c0;
|
||
|
|
font: normal 1.4em Verdana, sans-serif;
|
||
|
|
}
|
||
|
|
|
||
|
|
@media $medium_media_query {
|
||
|
|
.extra-box {
|
||
|
|
float:left;
|
||
|
|
width: 25%;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/* entries */
|
||
|
|
|
||
|
|
#entries {
|
||
|
|
clear: both;
|
||
|
|
margin: 10px;
|
||
|
|
margin-left: 10px;
|
||
|
|
padding: 10px;
|
||
|
|
}
|
||
|
|
.entry .left {
|
||
|
|
text-align: center;
|
||
|
|
float: left;
|
||
|
|
width: 80px;
|
||
|
|
padding-top: 10px;
|
||
|
|
}
|
||
|
|
.entry .right {
|
||
|
|
margin-left: 80px;
|
||
|
|
}
|
||
|
|
|
||
|
|
@media $medium_media_query {
|
||
|
|
.entry .left {
|
||
|
|
width: 120px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry .right {
|
||
|
|
margin-left: 150px;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/* ENTRY */
|
||
|
|
|
||
|
|
h2,
|
||
|
|
h3 {
|
||
|
|
color: #3c0;
|
||
|
|
font: normal 2em Verdana, sans-serif;
|
||
|
|
letter-spacing: -0.1em;
|
||
|
|
margin: 0;
|
||
|
|
padding: 0;
|
||
|
|
display: inline;
|
||
|
|
}
|
||
|
|
|
||
|
|
.title a {
|
||
|
|
color: #3c0;
|
||
|
|
text-decoration: none;
|
||
|
|
}
|
||
|
|
.title a:visited {
|
||
|
|
color: #2b0;
|
||
|
|
}
|
||
|
|
.title a:hover,
|
||
|
|
.title a:active {
|
||
|
|
color: #4d1;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* shared entry and comments */
|
||
|
|
|
||
|
|
.comment-title {
|
||
|
|
margin: 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.tools {
|
||
|
|
text-align: center;
|
||
|
|
padding: 10px;
|
||
|
|
border: 1px solid #cde;
|
||
|
|
background: #def;
|
||
|
|
clear: both;
|
||
|
|
}
|
||
|
|
|
||
|
|
.frozen .tools {
|
||
|
|
border: 1px solid #dee;
|
||
|
|
background: #eff;
|
||
|
|
}
|
||
|
|
.screened .tools {
|
||
|
|
border: 1px dashed #999;
|
||
|
|
background: #fff;
|
||
|
|
}
|
||
|
|
.text {
|
||
|
|
font-size: 90%;
|
||
|
|
}
|
||
|
|
.userpic {
|
||
|
|
margin-bottom: 5px;
|
||
|
|
width: 80%;
|
||
|
|
}
|
||
|
|
|
||
|
|
.userpic img {
|
||
|
|
width: 100%;
|
||
|
|
height: 100%;
|
||
|
|
}
|
||
|
|
|
||
|
|
.userpic.empty {
|
||
|
|
width: calc(100% - 20px);
|
||
|
|
padding-top: calc(100% - 20px);
|
||
|
|
margin-bottom: 10px;
|
||
|
|
border: 1px solid #eee;
|
||
|
|
}
|
||
|
|
|
||
|
|
@media $medium_media_query {
|
||
|
|
.userpic {
|
||
|
|
width: auto;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/* Entries */
|
||
|
|
|
||
|
|
.entry {
|
||
|
|
line-height: 1.3em;
|
||
|
|
letter-spacing: 0.01em;
|
||
|
|
margin: 10px 0 40px 0;
|
||
|
|
}
|
||
|
|
.entry .header {
|
||
|
|
color: #999;
|
||
|
|
padding: 0px 10px 10px 0;
|
||
|
|
margin-bottom: 10px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry .posted {
|
||
|
|
margin-left: 5px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry .datetime {
|
||
|
|
margin-left: 20px;
|
||
|
|
}
|
||
|
|
.entry .security {
|
||
|
|
margin: 0.5em;
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry .meta {
|
||
|
|
float: left;
|
||
|
|
clear: both;
|
||
|
|
padding: 5px;
|
||
|
|
margin: 10px;
|
||
|
|
font-size: 80%;
|
||
|
|
color: #333;
|
||
|
|
background-color: #def;
|
||
|
|
border: 1px solid #cde;
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry .links {
|
||
|
|
color: #999;
|
||
|
|
clear: both;
|
||
|
|
}
|
||
|
|
|
||
|
|
.entry .meta-label {
|
||
|
|
font-weight: bold;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
.new-day {
|
||
|
|
margin: 2px 0 2px 150px;
|
||
|
|
font: normal 1.4em Verdana, sans-serif;
|
||
|
|
color: #666;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/* collapsed entries */
|
||
|
|
|
||
|
|
.collapsed-entry {
|
||
|
|
margin-left: 130px;
|
||
|
|
|
||
|
|
}
|
||
|
|
.collapsed-entry .poster {
|
||
|
|
font-weight: bold;
|
||
|
|
font-size: 0.8em;
|
||
|
|
}
|
||
|
|
.expand {
|
||
|
|
font: normal 1.4em Verdana, sans-serif;
|
||
|
|
}
|
||
|
|
.expand a,
|
||
|
|
.expand a:visited {
|
||
|
|
color: #ccc;
|
||
|
|
text-decoration: none;
|
||
|
|
}
|
||
|
|
.expand a:hover,
|
||
|
|
.expand a:active {
|
||
|
|
color: #333;
|
||
|
|
}
|
||
|
|
.collapsed-entry .title {
|
||
|
|
font: normal 1.2em Verdana, sans-serif;
|
||
|
|
letter-spacing: -0.1em;
|
||
|
|
margin: 0;
|
||
|
|
padding: 0;
|
||
|
|
display: inline;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
/* Comments */
|
||
|
|
|
||
|
|
#comments {
|
||
|
|
clear: both;
|
||
|
|
margin: 10px;
|
||
|
|
margin-left: 10px;
|
||
|
|
padding: 10px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.nest {
|
||
|
|
margin-left: 20px;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
.comment {
|
||
|
|
line-height: 1.3em;
|
||
|
|
letter-spacing: 0.01em;
|
||
|
|
margin: 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.comment .left {
|
||
|
|
text-align: center;
|
||
|
|
float: left;
|
||
|
|
padding: 5px;
|
||
|
|
width: 120px;
|
||
|
|
margin-top: 15px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.comment .right {
|
||
|
|
padding: 10px;
|
||
|
|
margin-left: 130px;
|
||
|
|
background: #fff;
|
||
|
|
border-bottom: 1px solid #eee;
|
||
|
|
}
|
||
|
|
|
||
|
|
.comment h2 {
|
||
|
|
color: #3c0;
|
||
|
|
font: normal 1.3em Verdana, sans-serif;
|
||
|
|
letter-spacing: -0.1em;
|
||
|
|
margin: 0;
|
||
|
|
padding: 0;
|
||
|
|
display: inline;
|
||
|
|
}
|
||
|
|
|
||
|
|
.comment.odd {
|
||
|
|
background: #fff;
|
||
|
|
}
|
||
|
|
.comment.even {
|
||
|
|
background: #fff;
|
||
|
|
}
|
||
|
|
.comment .header {
|
||
|
|
color: #999;
|
||
|
|
padding: 10px 10px 10px 0;
|
||
|
|
margin-bottom: 10px;
|
||
|
|
}
|
||
|
|
.comment .posted {
|
||
|
|
margin-left: 5px;
|
||
|
|
}
|
||
|
|
.comment .datetime {
|
||
|
|
margin-left: 20px;
|
||
|
|
}
|
||
|
|
.comment .icon {
|
||
|
|
margin: 0.5em;
|
||
|
|
}
|
||
|
|
|
||
|
|
.comment .meta {
|
||
|
|
float: left;
|
||
|
|
padding: 5px;
|
||
|
|
margin: 10px;
|
||
|
|
font-size: 80%;
|
||
|
|
color: #333;
|
||
|
|
background-color: #def;
|
||
|
|
border: 1px solid #cde;
|
||
|
|
}
|
||
|
|
|
||
|
|
.comment .links {
|
||
|
|
color: #999;
|
||
|
|
clear: both;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Collapsed comments */
|
||
|
|
|
||
|
|
.collapsed-comment {
|
||
|
|
margin: 5px;
|
||
|
|
}
|
||
|
|
.collapsed-comment .title {
|
||
|
|
font: normal 1.2em Verdana, sans-serif;
|
||
|
|
letter-spacing: -0.1em;
|
||
|
|
text-decoration: none;
|
||
|
|
color: #3c0;
|
||
|
|
}
|
||
|
|
.collapsed-comment .poster {
|
||
|
|
font-size: 0.8em;
|
||
|
|
}
|
||
|
|
.comment-pagination {
|
||
|
|
clear: both;
|
||
|
|
padding: 10px;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
.entry-comments-bar {
|
||
|
|
background: #eee;
|
||
|
|
clear: both;
|
||
|
|
padding: 10px;
|
||
|
|
}
|
||
|
|
.entry-comments-bar .comments-title {
|
||
|
|
font: normal 1.5em Georgia, serif;
|
||
|
|
color: #333;
|
||
|
|
padding: 5px;
|
||
|
|
letter-spacing: 0;
|
||
|
|
display: block;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
#multiform {
|
||
|
|
font-size: 0.8em;
|
||
|
|
margin: 10px;
|
||
|
|
padding: 10px;
|
||
|
|
border: 1px solid #cde;
|
||
|
|
background: #def;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/* YearPage calendar */
|
||
|
|
|
||
|
|
#calendar {
|
||
|
|
margin: 10px;
|
||
|
|
padding: 5px;
|
||
|
|
}
|
||
|
|
|
||
|
|
#calendar .month {
|
||
|
|
margin: 10px;
|
||
|
|
float: left;
|
||
|
|
}
|
||
|
|
|
||
|
|
#calendar .header a {
|
||
|
|
color: #3c0;
|
||
|
|
text-decoration: none;
|
||
|
|
}
|
||
|
|
|
||
|
|
.month th.weekday {
|
||
|
|
color: #333;
|
||
|
|
}
|
||
|
|
|
||
|
|
.month .cell {
|
||
|
|
height: 3em;
|
||
|
|
width: 3em;
|
||
|
|
}
|
||
|
|
.month .cell.full {
|
||
|
|
background: #def;
|
||
|
|
border: 1px solid #cde;
|
||
|
|
}
|
||
|
|
.month .cell.empty {
|
||
|
|
border: 1px solid #eee;
|
||
|
|
}
|
||
|
|
|
||
|
|
.month .day {
|
||
|
|
text-align: left;
|
||
|
|
color: #999;
|
||
|
|
font-size: 0.8em;
|
||
|
|
}
|
||
|
|
.month .cell.empty .day {
|
||
|
|
color: #ddd;
|
||
|
|
}
|
||
|
|
.month .count {
|
||
|
|
text-align: center;
|
||
|
|
}
|
||
|
|
|
||
|
|
.extra-box .month {
|
||
|
|
font-size: 0.5em;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Comment quickreply */
|
||
|
|
|
||
|
|
.quickreply {
|
||
|
|
padding: 5px;
|
||
|
|
}
|
||
|
|
.quickreply table {
|
||
|
|
border: 0px !important;
|
||
|
|
|
||
|
|
}
|
||
|
|
.quickreply span.de {
|
||
|
|
display: block;
|
||
|
|
float: left;
|
||
|
|
font-size: 0.7em;
|
||
|
|
background: #def;
|
||
|
|
padding: 5px;
|
||
|
|
margin: 5px;
|
||
|
|
border: 1px solid #cde;
|
||
|
|
}
|
||
|
|
.quickreply td[align="right"] {
|
||
|
|
font-size: 0.8em;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/* TagsPage tag cloud */
|
||
|
|
|
||
|
|
#tag-cloud {
|
||
|
|
margin: 10px;
|
||
|
|
padding: 5px;
|
||
|
|
}
|
||
|
|
|
||
|
|
#tag-cloud a {
|
||
|
|
color: #3c0;
|
||
|
|
text-decoration: none;
|
||
|
|
}
|
||
|
|
|
||
|
|
.module-tags_cloud li, .tags_cloud li {
|
||
|
|
display: inline;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/* IconsPage */
|
||
|
|
|
||
|
|
.icons-container {
|
||
|
|
margin: 10px;
|
||
|
|
padding: 10px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.sorting-options ul {
|
||
|
|
padding-left: 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.sorting-options ul li {
|
||
|
|
display: inline;
|
||
|
|
}
|
||
|
|
|
||
|
|
.icons-container .icon {
|
||
|
|
margin: 1em 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.icon-image {
|
||
|
|
float: left;
|
||
|
|
clear: left;
|
||
|
|
margin-bottom: .25em;
|
||
|
|
min-width: 100px;
|
||
|
|
padding-right: 1em;
|
||
|
|
}
|
||
|
|
|
||
|
|
.icon-info {
|
||
|
|
min-height: 100px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.icon-info span {
|
||
|
|
font-weight: bold;
|
||
|
|
}
|
||
|
|
|
||
|
|
.icon-info .default {
|
||
|
|
text-decoration: underline;
|
||
|
|
}
|
||
|
|
|
||
|
|
.icon-keywords ul {
|
||
|
|
display: inline;
|
||
|
|
padding-left: 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
.icon-keywords ul li {
|
||
|
|
display: inline;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* ReplyPage reply box */
|
||
|
|
|
||
|
|
#reply {
|
||
|
|
margin: 10px 10px 10px 165px;
|
||
|
|
padding: 5px;
|
||
|
|
}
|
||
|
|
|
||
|
|
#postform {
|
||
|
|
background: #def;
|
||
|
|
border: 1px solid #cde;
|
||
|
|
padding: 5px;
|
||
|
|
margin-top: 10px;
|
||
|
|
font-size: 0.8em;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
"""; }
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
###################################################
|
||
|
|
# # #
|
||
|
|
# ~4. # EntryLite #
|
||
|
|
# # #
|
||
|
|
###################################################
|
||
|
|
|
||
|
|
# Shared methods used on/for both entries and comments.
|
||
|
|
#
|
||
|
|
#
|
||
|
|
|
||
|
|
|
||
|
|
# Gets the entry or comment's link icons (freeze, add to memories etc.),
|
||
|
|
# with the exception of the 'nav_prev' and 'nav_next' which are handled by
|
||
|
|
# Page::lay_back_forward().
|
||
|
|
#
|
||
|
|
function EntryLite::lay_get_linkbar() : string {
|
||
|
|
var string o;
|
||
|
|
var Link link;
|
||
|
|
foreach var string k ($.link_keyseq) {
|
||
|
|
if ( $k != "nav_prev" and $k != "nav_next" ) {
|
||
|
|
$link = $this->get_link($k);
|
||
|
|
if ( defined $link ) {
|
||
|
|
$o = $o + $link->as_string();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return $o;
|
||
|
|
}
|
||
|
|
|
||
|
|
# Returns a comma-separated string of tags.
|
||
|
|
#
|
||
|
|
function EntryLite::lay_get_tags() : string {
|
||
|
|
var string tags = "";
|
||
|
|
if ($.tags) {
|
||
|
|
foreach var int i (0 .. (size $.tags - 1)) {
|
||
|
|
var Tag t = $.tags[$i];
|
||
|
|
|
||
|
|
$tags = $tags + """<a rel="tag" href="$t.url">$t.name</a>""";
|
||
|
|
|
||
|
|
if ( $i < size $.tags - 1 ) {
|
||
|
|
$tags = $tags + ", ";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return $tags;
|
||
|
|
}
|
||
|
|
|
||
|
|
# Return a string representing the poster of this entry or comment.
|
||
|
|
#
|
||
|
|
function Page::lay_get_poster(EntryLite e) : string {
|
||
|
|
if ( not defined $e.poster ) {
|
||
|
|
return $*text_poster_anonymous;
|
||
|
|
} elseif ( not $e.poster->equals($e.journal) and $.view == "read" ) {
|
||
|
|
|
||
|
|
# default: "%1 in %2"
|
||
|
|
return lay_string_placeholders( $*poster_in_journal, [$e.poster->as_string(), $e.journal->as_string()] );
|
||
|
|
} else {
|
||
|
|
return $e.poster->as_string();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
# Print a string containing any or all of the poster, date, time, tags
|
||
|
|
# and ip address of this entry or comment.
|
||
|
|
#
|
||
|
|
function Page::lay_print_posted_by(EntryLite e) : void {
|
||
|
|
var string format;
|
||
|
|
var string[] args;
|
||
|
|
var string tags;
|
||
|
|
var string timeformat;
|
||
|
|
|
||
|
|
if ($this.timeformat24) {
|
||
|
|
$timeformat = $*posted_time_format_24;
|
||
|
|
} else {
|
||
|
|
$timeformat = $*posted_time_format;
|
||
|
|
}
|
||
|
|
|
||
|
|
# default: "posted by %1 at %2 on %3";
|
||
|
|
$format = $*posted_by_at_on;
|
||
|
|
|
||
|
|
$args = [
|
||
|
|
$this->lay_get_poster($e),
|
||
|
|
$e.time->date_format( $timeformat ),
|
||
|
|
$e.time->date_format( $*posted_date_format )
|
||
|
|
];
|
||
|
|
|
||
|
|
$tags = $e->lay_get_tags();
|
||
|
|
if ( $tags != "" ) {
|
||
|
|
|
||
|
|
# default: "posted by %1 at %2 on %3 under %4";
|
||
|
|
$format = $*posted_by_at_on_in;
|
||
|
|
lay_array_push($args, $tags);
|
||
|
|
|
||
|
|
} elseif ($e.metadata{"poster_ip"}) {
|
||
|
|
|
||
|
|
# default: "posted by %1 at %2 on %3 from %4";
|
||
|
|
$format = $*posted_by_at_on_from;
|
||
|
|
lay_array_push($args, $e.metadata{"poster_ip"});
|
||
|
|
}
|
||
|
|
|
||
|
|
print lay_string_placeholders( $format, $args );
|
||
|
|
}
|
||
|
|
|
||
|
|
# Prints an entry or comment's text.
|
||
|
|
#
|
||
|
|
function Page::lay_print_text(EntryLite e) : void
|
||
|
|
"Prints an entry or comment's text."
|
||
|
|
{
|
||
|
|
println """<div class="text">""";
|
||
|
|
|
||
|
|
$e->print_text();
|
||
|
|
|
||
|
|
println "</div>";
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
###################################################
|
||
|
|
# # #
|
||
|
|
# ~5. # CommentInfo #
|
||
|
|
# # #
|
||
|
|
###################################################
|
||
|
|
|
||
|
|
# Get details of an entry's comments.
|
||
|
|
# show_read_link is included so EntryPage needn't show a link to itself.
|
||
|
|
#
|
||
|
|
function CommentInfo::lay_get_details(int pages, bool show_read_link) : string {
|
||
|
|
var string link;
|
||
|
|
if ($.count > 0) {
|
||
|
|
|
||
|
|
if ( lang_map_plural($.count) ) {
|
||
|
|
# "%1 comments"
|
||
|
|
$link = lay_string_placeholders($*text_some_comments_link, [string($.count)]);
|
||
|
|
|
||
|
|
if ( $show_read_link ) {
|
||
|
|
$link = """<a href="$.read_url">$link</a>""";
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( $pages > 1 ) {
|
||
|
|
$link = lay_string_placeholders($*text_some_comments_over_pages, [$link, string($pages)]);
|
||
|
|
} else {
|
||
|
|
$link = lay_string_placeholders($*text_some_comments, [$link]);
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
# "%1 comment"
|
||
|
|
$link = lay_string_placeholders($*text_a_comment_link, [string($.count)]);
|
||
|
|
if ( $show_read_link ) {
|
||
|
|
$link = """<a href="$.read_url">$link</a>""";
|
||
|
|
}
|
||
|
|
$link = lay_string_placeholders($*text_a_comment, [$link]);
|
||
|
|
}
|
||
|
|
|
||
|
|
} else {
|
||
|
|
|
||
|
|
# default: "There are no comments on this entry."
|
||
|
|
$link = $*text_no_comments;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (not $.enabled) {
|
||
|
|
|
||
|
|
# default: "Comments are disabled."
|
||
|
|
$link = $link + " " + $*text_comments_disabled;
|
||
|
|
}
|
||
|
|
return $link;
|
||
|
|
}
|
||
|
|
|
||
|
|
function Page::lay_print_comment_details(CommentInfo c) : void {
|
||
|
|
print $c->lay_get_details(0, true);
|
||
|
|
}
|
||
|
|
|
||
|
|
# Prints a link to an entry's ReplyPage.
|
||
|
|
#
|
||
|
|
function Page::lay_print_entry_reply_link(CommentInfo c) : void {
|
||
|
|
if ($c.show_postlink) {
|
||
|
|
var string link = """<a href="$c.post_url">$*reply_link_link_text</a>""";
|
||
|
|
print " " + lay_string_placeholders( $*reply_link_text, [$link] );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
###################################################
|
||
|
|
# # #
|
||
|
|
# ~6. # Entry #
|
||
|
|
# # #
|
||
|
|
###################################################
|
||
|
|
|
||
|
|
function Page::lay_print_entry_linkbar(Entry e) {
|
||
|
|
|
||
|
|
var string bar = $e->lay_get_linkbar();
|
||
|
|
if ( $bar == "" ) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
println """<div class="tools">$bar</div>""";
|
||
|
|
}
|
||
|
|
|
||
|
|
function Page::lay_print_entry_meta(Entry e) : void {
|
||
|
|
var string o = "";
|
||
|
|
var string caption;
|
||
|
|
var string val;
|
||
|
|
var Image i;
|
||
|
|
|
||
|
|
if (size $e.metadata == 0) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
"""
|
||
|
|
<div class="meta">
|
||
|
|
""";
|
||
|
|
|
||
|
|
foreach var string k ($e.metadata) {
|
||
|
|
$caption = $k;
|
||
|
|
$val = $e.metadata{$k};
|
||
|
|
if ($k == "music") {
|
||
|
|
$caption = $*text_meta_music;
|
||
|
|
} elseif ($k == "mood") {
|
||
|
|
$caption = $*text_meta_mood;
|
||
|
|
if (defined $e.mood_icon) {
|
||
|
|
$i = $e.mood_icon;
|
||
|
|
$val = $i->as_string("'$e.metadata{$k}'")+" "+$val;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
<div class="meta-item"><span class="meta-label">$caption:</span> $val</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
function Page::lay_print_entry_header(Entry e) {
|
||
|
|
var string subject = ($e.subject != "" ? $e.subject : $*text_nosubject);
|
||
|
|
"""
|
||
|
|
<div class="header">
|
||
|
|
<div class="title">
|
||
|
|
<h2 id="entry-$e.itemid"><a href="$e.permalink_url">$subject</a></h2>
|
||
|
|
""";
|
||
|
|
if ($e.security != "") {
|
||
|
|
print """<span class="security"><img src="$e.security_icon.url" alt="[$e.security]" /></span>""";
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
<div class="posted">"""; $this->lay_print_posted_by($e); """</div>""";
|
||
|
|
"""</div>""";
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
function Page::lay_print_entry_left(Entry e) : void {
|
||
|
|
var string userpic_class = ($e.userpic ? "userpic" : "userpic empty");
|
||
|
|
"""
|
||
|
|
<div class="$userpic_class">
|
||
|
|
""";
|
||
|
|
if ($e.userpic) {
|
||
|
|
print $e.userpic->as_string();
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
function Page::lay_print_entry_footer(Entry e) {
|
||
|
|
"""
|
||
|
|
<div class="links">
|
||
|
|
""";
|
||
|
|
$this->lay_print_comment_details( $e.comments );
|
||
|
|
$this->lay_print_entry_reply_link( $e.comments );
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
function Page::lay_print_entry(Entry e) {
|
||
|
|
"""
|
||
|
|
<div class="entry">
|
||
|
|
<div class="left">
|
||
|
|
""";
|
||
|
|
$this->lay_print_entry_left($e);
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
<div class="right">
|
||
|
|
""";
|
||
|
|
$this->lay_print_entry_header($e);
|
||
|
|
$this->lay_print_text($e);
|
||
|
|
$this->lay_print_entry_meta($e);
|
||
|
|
$this->lay_print_entry_footer($e);
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
function Page::print_entry(Entry e) {
|
||
|
|
$this->lay_print_entry($e);
|
||
|
|
}
|
||
|
|
|
||
|
|
function RecentPage::print_sticky_entry(StickyEntry s) {
|
||
|
|
$this->lay_print_entry($s);
|
||
|
|
}
|
||
|
|
|
||
|
|
###################################################
|
||
|
|
# # #
|
||
|
|
# ~6b. # Collapsed Entry #
|
||
|
|
# # #
|
||
|
|
###################################################
|
||
|
|
|
||
|
|
# MonthPage and FriendsPage by default show only a shortened version of an
|
||
|
|
# entry. I'm considering the same thing for RecentPage past a threshold --
|
||
|
|
# one or two full entries followed by a longer list of previously-posted
|
||
|
|
# titles.
|
||
|
|
#
|
||
|
|
# On FriendsPage these entries can be expanded in-place; on MonthPage
|
||
|
|
# the entry text isn't populated so they can only link to the full entry.
|
||
|
|
#
|
||
|
|
|
||
|
|
# Print "expand" link.
|
||
|
|
#
|
||
|
|
function Page::lay_print_collapsed_entry_expand(Entry e) : void {
|
||
|
|
var string expand_url = $this->lay_build_url({".id" => string($e.itemid)}) + "#entry-$e.itemid";
|
||
|
|
print """<span class="expand"><a href="$expand_url" title="Expand this entry.">+</a></span>""";
|
||
|
|
}
|
||
|
|
|
||
|
|
# Entry title.
|
||
|
|
#
|
||
|
|
function Page::lay_print_collapsed_entry_title(Entry e) : void {
|
||
|
|
var string subject = ($e.subject != "" ? $e.subject : $*text_nosubject);
|
||
|
|
print """<span class="title"><a href="$e.permalink_url" title="View this entry.">$subject</a></span>""";
|
||
|
|
}
|
||
|
|
|
||
|
|
# Entry security unless public.
|
||
|
|
#
|
||
|
|
function Page::lay_print_collapsed_entry_security(Entry e) : void {
|
||
|
|
if ($e.security != "") {
|
||
|
|
print """ <span class="security">""" + $e.security_icon->as_string() + "</span>";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Entry comment count / "comments disabled" message.
|
||
|
|
#
|
||
|
|
function Page::lay_print_collapsed_entry_comments(Entry e) : void {
|
||
|
|
var string count = "";
|
||
|
|
var string max = "";
|
||
|
|
var string screened = "";
|
||
|
|
if ($e.comments.count > 0) {
|
||
|
|
if ($e.comments.maxcomments) {
|
||
|
|
# default: "!"
|
||
|
|
$max = $*collapsed_entry_comments_max_flag;
|
||
|
|
}
|
||
|
|
if ($e.comments.screened) {
|
||
|
|
# default "*"
|
||
|
|
$screened = $*collapsed_entry_comments_screened_flag;
|
||
|
|
}
|
||
|
|
# Assuming max and screened comments, default output is "(5000!*)"
|
||
|
|
# Just screened comments is "(343*)" etc.
|
||
|
|
$count = lay_string_placeholders( $*collapsed_entry_comments_count, [string($e.comments.count), $max, $screened] );
|
||
|
|
} elseif (not $e.comments.enabled) {
|
||
|
|
$count = $*collapsed_entry_comments_disabled;
|
||
|
|
}
|
||
|
|
print """ <span class="comments">$count</span>""";
|
||
|
|
}
|
||
|
|
# Entry poster.
|
||
|
|
#
|
||
|
|
function Page::lay_print_collapsed_entry_poster(Entry e) : void {
|
||
|
|
if ( $.view == "read" or not $e.poster->equals($.journal as UserLite) ) {
|
||
|
|
print """ — <span class="poster">""" + $this->lay_get_poster($e) + "</span>";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Print the actual entry.
|
||
|
|
#
|
||
|
|
function Page::lay_print_collapsed_entry(Entry e) {
|
||
|
|
|
||
|
|
println """<div class="collapsed-entry">""";
|
||
|
|
|
||
|
|
$this->lay_print_collapsed_entry_expand($e);
|
||
|
|
$this->lay_print_collapsed_entry_title($e);
|
||
|
|
$this->lay_print_collapsed_entry_security($e);
|
||
|
|
$this->lay_print_collapsed_entry_comments($e);
|
||
|
|
$this->lay_print_collapsed_entry_poster($e);
|
||
|
|
|
||
|
|
println """</div>""";
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
###################################################
|
||
|
|
# # #
|
||
|
|
# ~7. # Page #
|
||
|
|
# # #
|
||
|
|
# # These methods do nothing, but are #
|
||
|
|
# # overridden in child layers. #
|
||
|
|
# # #
|
||
|
|
###################################################
|
||
|
|
|
||
|
|
# Show the full version of an entry, or the collapsed
|
||
|
|
# version?
|
||
|
|
function Page::lay_entry_is_expanded(Entry e) : bool {
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
# Some pages have extra content to print in the footer.
|
||
|
|
#
|
||
|
|
function Page::lay_print_extra_box() {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
# Lay back-and-foward navigation. Between pages of
|
||
|
|
# entries on RecentPage, between months on MonthPage, etc.
|
||
|
|
#
|
||
|
|
function Page::lay_back_forward() : void {}
|
||
|
|
|
||
|
|
# Returns a combination of page title and view title;
|
||
|
|
# only used in the `<title>` element of the HTML output.
|
||
|
|
|
||
|
|
function Page::title() : string {
|
||
|
|
var string title = $this.global_title;
|
||
|
|
var string view = $this->view_title();
|
||
|
|
|
||
|
|
return lay_string_placeholders( $*text_html_title, [$title, $view] );
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
# Prints an error page.
|
||
|
|
#
|
||
|
|
function Page::lay_print_errorpage(string message) {
|
||
|
|
"""
|
||
|
|
<div class="error">
|
||
|
|
<h2 class="error-header">$*text_errorpage_title</h2>
|
||
|
|
<p>$message</p>
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
# Print the current tab. Made separate so it can be overridden
|
||
|
|
# in FriendsPage.
|
||
|
|
#
|
||
|
|
function Page::lay_print_navigation_current_tab() : void {
|
||
|
|
println """<li id="tab-current"><span>""" + lang_viewname($.view) + "</span></li>";
|
||
|
|
}
|
||
|
|
function Page::lay_navigation() {
|
||
|
|
var string nav;
|
||
|
|
var string alt;
|
||
|
|
|
||
|
|
# Time to play "making up for S2's deficiencies"!
|
||
|
|
# No link is supplied to the TagsPage yet.
|
||
|
|
var string{} vu = $.view_url;
|
||
|
|
var string[] vo = $.views_order;
|
||
|
|
|
||
|
|
if ( $vu{"tags"} == "" ) {
|
||
|
|
$vu{"tags"} = $.base_url + "/tag/";
|
||
|
|
$vo[size $vo] = "tags";
|
||
|
|
}
|
||
|
|
|
||
|
|
"""
|
||
|
|
<div id="navi">
|
||
|
|
<ul>
|
||
|
|
""";
|
||
|
|
foreach var string v ($vo) {
|
||
|
|
if ($.view == $v) {
|
||
|
|
$this->lay_print_navigation_current_tab();
|
||
|
|
} else {
|
||
|
|
println """<li><a href="$vu{$v}"><span>""" + lang_viewname($v) + "</span></a></li>";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
</ul>
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
function Page::lay_print_extra_box_open(string title) : void {
|
||
|
|
var string alt = alternate("odd", "even");
|
||
|
|
"""
|
||
|
|
<div class="extra-box $alt">
|
||
|
|
<h2 class="title">$title</h3>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
function Page::lay_print_extra_box_close() : void {
|
||
|
|
print "</div>";
|
||
|
|
}
|
||
|
|
|
||
|
|
# Prints a linklist. More complicated than it'd normally be because the
|
||
|
|
# style splits a list with headings into multiple lists. Sub-lists are
|
||
|
|
# not supported because they're not implemented in the core yet and show
|
||
|
|
# no signs of ever being so.
|
||
|
|
#
|
||
|
|
function Page::print_linklist() {
|
||
|
|
if ( size $.linklist == 0 ) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
var bool open = false;
|
||
|
|
var UserLink l = $.linklist[0];
|
||
|
|
|
||
|
|
if (not $l.is_heading) {
|
||
|
|
$this->lay_print_extra_box_open( $*linklist_default_title );
|
||
|
|
"""
|
||
|
|
<ul class="linklist">
|
||
|
|
""";
|
||
|
|
$open = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
foreach var UserLink l ($.linklist) {
|
||
|
|
if ($l.is_heading) {
|
||
|
|
if ($open) {
|
||
|
|
"""
|
||
|
|
</ul>
|
||
|
|
""";
|
||
|
|
$this->lay_print_extra_box_close();
|
||
|
|
$open = false;
|
||
|
|
}
|
||
|
|
$this->lay_print_extra_box_open($l.title);
|
||
|
|
"""
|
||
|
|
<ul class="linklist">
|
||
|
|
""";
|
||
|
|
$open = true;
|
||
|
|
} else {
|
||
|
|
"""
|
||
|
|
<li><a href="$l.url">$l.title</a></li>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($open) {
|
||
|
|
"""
|
||
|
|
</ul>
|
||
|
|
""";
|
||
|
|
$this->lay_print_extra_box_close();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
# Print one week in a calendar month.
|
||
|
|
#
|
||
|
|
function Page::lay_print_week(YearWeek w) : void {
|
||
|
|
"""
|
||
|
|
<tr>
|
||
|
|
""";
|
||
|
|
if ($w.pre_empty > 0) {
|
||
|
|
foreach var int i (1..$w.pre_empty) {
|
||
|
|
"""
|
||
|
|
<td class="blank cell"> </td>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
foreach var YearDay d ($w.days) {
|
||
|
|
if ($d.num_entries > 0) {
|
||
|
|
"""
|
||
|
|
<td class="full cell">
|
||
|
|
<span class="day">$d.day</span>
|
||
|
|
<div class="count"><a href="$d.url">$d.num_entries</a></div>
|
||
|
|
</td>
|
||
|
|
""";
|
||
|
|
} else {
|
||
|
|
"""
|
||
|
|
<td class="empty cell">
|
||
|
|
<span class="day">$d.day</span>
|
||
|
|
<div class="count"> </div>
|
||
|
|
</td>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if ($w.post_empty > 0) {
|
||
|
|
foreach var int i (1..$w.post_empty) {
|
||
|
|
"""
|
||
|
|
<td class="blank-cell"> </td>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
</tr>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
# Print a calendar month.
|
||
|
|
#
|
||
|
|
function Page::lay_print_month(YearMonth m) {
|
||
|
|
"""
|
||
|
|
<table summary="Monthly calendar with links to each day's entries" class="month">
|
||
|
|
<tr>
|
||
|
|
""";
|
||
|
|
foreach var int d (weekdays()) {
|
||
|
|
"""<th class="weekday">$*lang_dayname_short[$d]</th>""";
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
</tr>
|
||
|
|
""";
|
||
|
|
foreach var YearWeek w ($m.weeks) {
|
||
|
|
$this->lay_print_week($w);
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
</table>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
function Page::lay_header() {
|
||
|
|
"""
|
||
|
|
<div id="header">
|
||
|
|
""";
|
||
|
|
|
||
|
|
var string subtitle;
|
||
|
|
if ($.global_subtitle != "") {
|
||
|
|
$subtitle = $this.global_subtitle + ". " + $this->view_title() + ".";
|
||
|
|
} else {
|
||
|
|
$subtitle = $this->view_title() + ".";
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
<h1>$.global_title</h1>
|
||
|
|
<p>$subtitle</p>
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
function Page::lay_print_mini_calendar_box() {
|
||
|
|
var YearMonth m = $this->get_latest_month();
|
||
|
|
if ( defined $m and $m.has_entries ) {
|
||
|
|
$this->lay_print_extra_box_open( $m->month_format("%%month%%") );
|
||
|
|
$this->lay_print_month($m);
|
||
|
|
$this->lay_print_extra_box_close();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function Page::lay_footer() {
|
||
|
|
|
||
|
|
"""
|
||
|
|
<div id="extra">
|
||
|
|
""";
|
||
|
|
$this->lay_print_extra_box();
|
||
|
|
$this->print_linklist();
|
||
|
|
$this->lay_print_mini_calendar_box();
|
||
|
|
lay_print_extra_boxes();
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div id="footer">
|
||
|
|
<p><span class="top-link"><a href="#header">$*top_link_text</a></span> <a href="https://www.dreamwidth.org/customize/advanced/layerbrowse.bml?id=zesty/layout">Zesty</a>. """; server_sig(); """</p>
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
function Page::print() {
|
||
|
|
|
||
|
|
"""
|
||
|
|
<!DOCTYPE html>
|
||
|
|
<html lang="en">
|
||
|
|
<head>
|
||
|
|
<title>"""+$this->title()+"""</title>
|
||
|
|
""";
|
||
|
|
$this->print_meta_tags();
|
||
|
|
$this->print_head();
|
||
|
|
"""
|
||
|
|
<link rel="stylesheet" type="text/css" href="$.stylesheet_url" />
|
||
|
|
""";
|
||
|
|
if ($*custom_favicon != "") {
|
||
|
|
"""<link rel="shortcut icon" href="$*custom_favicon" />""";
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
</head>
|
||
|
|
<body class="$.journal.username-$.view">
|
||
|
|
""";
|
||
|
|
$this->print_control_strip();
|
||
|
|
$this->lay_header();
|
||
|
|
$this->lay_navigation();
|
||
|
|
|
||
|
|
$this->print_body();
|
||
|
|
|
||
|
|
$this->lay_footer();
|
||
|
|
"""
|
||
|
|
</body>
|
||
|
|
</html>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
###################################################
|
||
|
|
# # #
|
||
|
|
# ~8. # RecentPage #
|
||
|
|
# # #
|
||
|
|
###################################################
|
||
|
|
|
||
|
|
|
||
|
|
function RecentPage::lay_build_url(string{} items) : string {
|
||
|
|
if ($.nav.skip != 0) {
|
||
|
|
$items{"skip"} = string($.nav.skip);
|
||
|
|
}
|
||
|
|
return $.base_url + lay_array_to_args($items);
|
||
|
|
}
|
||
|
|
|
||
|
|
function RecentPage::lay_back_forward() : void {
|
||
|
|
|
||
|
|
if ($.nav.backward_url == "" and $.nav.forward_url == "") {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
<div class="back-forward">
|
||
|
|
""";
|
||
|
|
if ($.nav.backward_url != "") {
|
||
|
|
var string previous = get_plural_phrase($.nav.backward_count, "text_skiplinks_back");
|
||
|
|
"""
|
||
|
|
<div class="back">
|
||
|
|
<a href="$.nav.backward_url" title="$previous">←</a>
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
if ($.nav.forward_url != "") {
|
||
|
|
var string next = get_plural_phrase($.nav.forward_count, "text_skiplinks_forward");
|
||
|
|
"""
|
||
|
|
<div class="forward">
|
||
|
|
<a href="$.nav.forward_url" title="$next">→</a>
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
function RecentPage::print_body() {
|
||
|
|
$this->lay_back_forward();
|
||
|
|
"""
|
||
|
|
<div id="entries">
|
||
|
|
""";
|
||
|
|
if (size $.entries == 0) {
|
||
|
|
$this->lay_print_errorpage($*text_noentries_recent);
|
||
|
|
} else {
|
||
|
|
foreach var Entry e ($.entries) {
|
||
|
|
$this->print_entry($e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
$this->lay_back_forward();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
###################################################
|
||
|
|
# # #
|
||
|
|
# ~9. # FriendsPage #
|
||
|
|
# # #
|
||
|
|
###################################################
|
||
|
|
|
||
|
|
|
||
|
|
function FriendsPage::lay_build_url(string{} items) : string {
|
||
|
|
var string url = $.base_url;
|
||
|
|
|
||
|
|
# Page might be "friendsfriends".
|
||
|
|
#
|
||
|
|
if ($.friends_mode != "") {
|
||
|
|
$url = $url + "/$.friends_mode";
|
||
|
|
} else {
|
||
|
|
$url = $url + "/read";
|
||
|
|
}
|
||
|
|
|
||
|
|
# Page might be a friends group.
|
||
|
|
#
|
||
|
|
if ($.filter_active) {
|
||
|
|
$url = $url + "/$.filter_name";
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($.nav.skip != 0) {
|
||
|
|
$items{"skip"} = string($.nav.skip);
|
||
|
|
}
|
||
|
|
return $url + lay_array_to_args($items);
|
||
|
|
}
|
||
|
|
|
||
|
|
# Is the default view mode for entries "expanded" or "collapsed"?
|
||
|
|
# Currently only actually used on the FriendsPage.
|
||
|
|
#
|
||
|
|
function FriendsPage::lay_get_current_view_mode() : string {
|
||
|
|
var string mode = $*default_view_mode;
|
||
|
|
if ($.args{"mode"} != "" and $mode != $.args{"mode"}) {
|
||
|
|
$mode = $.args{"mode"};
|
||
|
|
}
|
||
|
|
return $mode;
|
||
|
|
}
|
||
|
|
|
||
|
|
# Returns the opposite of the current view mode for entries.
|
||
|
|
#
|
||
|
|
function FriendsPage::lay_get_alternate_view_mode() : string {
|
||
|
|
var string current = $this->lay_get_current_view_mode();
|
||
|
|
if ( $current == "expanded" ) {
|
||
|
|
return "collapsed";
|
||
|
|
} else {
|
||
|
|
return "expanded";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function FriendsPage::lay_entry_is_expanded(Entry e) : bool {
|
||
|
|
var bool expanded = false;
|
||
|
|
|
||
|
|
# We expand entries if they match the `.id=$entry_id` argument, but
|
||
|
|
# there's a problem in that the item id isn't necessarily unique.
|
||
|
|
# Because LJ uses (internally) a composite key of user id and item id,
|
||
|
|
# two different users' posts on the same page could have the same item id.
|
||
|
|
#
|
||
|
|
# I mention it mostly out of interest, since I'm not going to do anything
|
||
|
|
# to stop it happening.
|
||
|
|
#
|
||
|
|
# It's vanishingly unlikely, S2 doesn't expose the user ID (and the
|
||
|
|
# username isn't necessarily unique *or* safe), and even if there's a
|
||
|
|
# clash, what's the damage? But it might still happen at some point.
|
||
|
|
#
|
||
|
|
# It's not quite as simple as the birthday paradox, because low item ids
|
||
|
|
# are exponentially more likely to appear than high ones, and people who
|
||
|
|
# joined the site at the same time and have similar posting habits are
|
||
|
|
# quite likely to stay in the same range of item ids.
|
||
|
|
#
|
||
|
|
# This comment was much too long. Sorry!
|
||
|
|
#
|
||
|
|
if ($.args{"id"} != "" and int($.args{"id"}) == $e.itemid) {
|
||
|
|
$expanded = true;
|
||
|
|
} elseif ($this->lay_get_current_view_mode() == "expanded") {
|
||
|
|
$expanded = true;
|
||
|
|
}
|
||
|
|
return $expanded;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
# The FriendsPage tab has an extra mode-switching button on it.
|
||
|
|
#
|
||
|
|
function FriendsPage::lay_print_navigation_current_tab() : void {
|
||
|
|
var string alt = $this->lay_build_url( {".mode" => $this->lay_get_alternate_view_mode()} );
|
||
|
|
println """<li id="tab-current"><span>""" + lang_viewname($.view) + """ <a href="$alt">+</a></span></li>""";
|
||
|
|
}
|
||
|
|
|
||
|
|
function FriendsPage::print_entry(Entry e) {
|
||
|
|
if ($e.new_day) {
|
||
|
|
print """<div class="new-day">""" + $e.time->date_format($*lang_fmt_date_long) + "</div>";
|
||
|
|
}
|
||
|
|
if ( $this->lay_entry_is_expanded($e) ) {
|
||
|
|
$this->lay_print_entry($e);
|
||
|
|
} else {
|
||
|
|
$this->lay_print_collapsed_entry($e);
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
###################################################
|
||
|
|
# # #
|
||
|
|
# ~10. # DayPage #
|
||
|
|
# # #
|
||
|
|
###################################################
|
||
|
|
|
||
|
|
function DayPage::lay_back_forward() : void {
|
||
|
|
|
||
|
|
if ($.prev_url == "" and $.next_url == "") {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
<div class="back-forward">
|
||
|
|
""";
|
||
|
|
if ($.prev_url != "") {
|
||
|
|
"""
|
||
|
|
<div class="back">
|
||
|
|
<a href="$.prev_url" title="$*text_day_prev">←</a>
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
if ($.next_url != "") {
|
||
|
|
"""
|
||
|
|
<div class="forward">
|
||
|
|
<a href="$.next_url" title="$*text_day_next">→</a>
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
function DayPage::print_body() {
|
||
|
|
|
||
|
|
if (not $.has_entries) {
|
||
|
|
$this->lay_print_errorpage($*text_noentries_day);
|
||
|
|
} else {
|
||
|
|
foreach var Entry e ($.entries) {
|
||
|
|
$this->print_entry($e);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
###################################################
|
||
|
|
# # #
|
||
|
|
# ~11. # MonthPage #
|
||
|
|
# # #
|
||
|
|
###################################################
|
||
|
|
|
||
|
|
# Can't expand MonthPage entries. Bah humbug.
|
||
|
|
#
|
||
|
|
function MonthPage::lay_print_collapsed_expand(Entry e) : void {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
function MonthPage::lay_back_forward() : void {
|
||
|
|
|
||
|
|
if ($.prev_url == "" and $.next_url == "") {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
<div class="back-forward">
|
||
|
|
""";
|
||
|
|
if ($.prev_url != "") {
|
||
|
|
"""
|
||
|
|
<div class="back">
|
||
|
|
<a href="$.prev_url" title="Previous day.">←</a>
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
if ($.next_url != "") {
|
||
|
|
"""
|
||
|
|
<div class="forward">
|
||
|
|
<a href="$.next_url" title="Next day.">→</a>
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
# Can't get entry text in this view, so no full entries possible.
|
||
|
|
#
|
||
|
|
function MonthPage::print_entry(Entry e) : void {
|
||
|
|
return $this->lay_print_collapsed_entry($e);
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
# Print a box containing information about other linkable months.
|
||
|
|
#
|
||
|
|
function MonthPage::lay_print_extra_box() : void {
|
||
|
|
if (size $.months == 0) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
"""
|
||
|
|
<div class="extra-box">
|
||
|
|
<h3 class="title">$.date.year</h3>
|
||
|
|
<ul>
|
||
|
|
""";
|
||
|
|
|
||
|
|
foreach var MonthEntryInfo m ($.months) {
|
||
|
|
if ($.date.year == $m.date.year) {
|
||
|
|
println """<li><a href="$m.url">"""+$m.date->date_format("%%month%%")+"</a></li>";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
"""
|
||
|
|
</ul>
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
function MonthPage::print_body {
|
||
|
|
var bool any = false;
|
||
|
|
$this->lay_back_forward();
|
||
|
|
"""
|
||
|
|
<div id="entries">
|
||
|
|
""";
|
||
|
|
foreach var MonthDay d ($.days) {
|
||
|
|
if ($d.has_entries) {
|
||
|
|
print """<div class="new-day">""" + $d.date->date_format($*lang_fmt_date_long) + "</div>";
|
||
|
|
foreach var Entry e ($d.entries) {
|
||
|
|
$this->print_entry($e);
|
||
|
|
}
|
||
|
|
$any = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
if ( not $any ) {
|
||
|
|
# default: "No entries were posted on the selected month."
|
||
|
|
return $this->lay_print_errorpage( $*error_monthpage_no_entries );
|
||
|
|
}
|
||
|
|
$this->lay_back_forward();
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
###################################################
|
||
|
|
# # #
|
||
|
|
# ~12. # EntryPage #
|
||
|
|
# # #
|
||
|
|
###################################################
|
||
|
|
|
||
|
|
# TODO: this is broken in the core.
|
||
|
|
# Waiting on http://rt.livejournal.org/Ticket/Display.html?id=1266 .
|
||
|
|
#
|
||
|
|
function EntryPage::lay_comment_poster_is_suspended(Comment c) : bool {
|
||
|
|
return $.viewing_thread and not $c.full and $c.depth == 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
function EntryPage::lay_print_comment_details(CommentInfo c) : void {
|
||
|
|
print $c->lay_get_details($.comment_pages.total, false);
|
||
|
|
}
|
||
|
|
|
||
|
|
# "Ideally layouts should never override this"... well how about you
|
||
|
|
# actually make it work on all views, then?
|
||
|
|
function EntryPage::view_title() : string {
|
||
|
|
var string subject = ($.entry.subject != "" ? $.entry.subject : $*text_nosubject);
|
||
|
|
if ( $.viewing_thread ) {
|
||
|
|
$subject = lay_string_placeholders( "%1 : comments", [$subject] );
|
||
|
|
}
|
||
|
|
return $subject;
|
||
|
|
}
|
||
|
|
|
||
|
|
function EntryPage::lay_back_forward() : void {
|
||
|
|
var Link prev = $.entry->get_link("nav_prev");
|
||
|
|
var Link next = $.entry->get_link("nav_next");
|
||
|
|
|
||
|
|
if ( isnull $prev and isnull $next ) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
<div class="back-forward">
|
||
|
|
""";
|
||
|
|
if ( defined $prev ) {
|
||
|
|
"""
|
||
|
|
<div class="back">
|
||
|
|
<a href="$prev.url" title="$prev.caption">←</a>
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
if ( defined $next ) {
|
||
|
|
"""
|
||
|
|
<div class="forward">
|
||
|
|
<a href="$next.url" title="$next.caption">→</a>
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
function EntryPage::lay_print_comment_linkbar(Comment c)
|
||
|
|
"Same as Page::lay_print_entry_linkbar except that it also prints
|
||
|
|
the multiform checkbox if the multiform is on. "
|
||
|
|
{
|
||
|
|
var string bar = $c->lay_get_linkbar();
|
||
|
|
|
||
|
|
if ( $bar == "" and not $.multiform_on ) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
print """<div class="tools" id="tools$c.talkid">$bar""";
|
||
|
|
|
||
|
|
if ($.multiform_on) {
|
||
|
|
$c->print_multiform_check();
|
||
|
|
}
|
||
|
|
|
||
|
|
print "</div>";
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
function EntryPage::lay_print_comment_links(Comment c) : void {
|
||
|
|
|
||
|
|
println """<div class="links">""";
|
||
|
|
|
||
|
|
if ( $.viewing_thread and $c.depth == 1 ) {
|
||
|
|
"""[<a href="$.entry.permalink_url">$*text_comment_parent_entry</a>] """;
|
||
|
|
}
|
||
|
|
|
||
|
|
"""[<a href="$c.permalink_url">$*text_comment_permalink</a>] """;
|
||
|
|
|
||
|
|
if ( $c.parent_url != "" ) {
|
||
|
|
"""[<a href="$c.parent_url">$*text_comment_parent</a>] """;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ( $c.frozen ) {
|
||
|
|
"""[$*text_comment_frozen]""";
|
||
|
|
} elseif ( $this->lay_comment_poster_is_suspended($c) ) {
|
||
|
|
"""[$*text_comment_poster_is_suspended]""";
|
||
|
|
} else {
|
||
|
|
"""["""; $c->print_reply_link({"linktext" => $*text_comment_reply}); """]""";
|
||
|
|
}
|
||
|
|
|
||
|
|
println """</div>""";
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
function EntryPage::print_comment(Comment c) : void {
|
||
|
|
|
||
|
|
var string class = "comment dwexpcomment " + alternate("odd", "even");
|
||
|
|
var string subject = ($c.subject == "") ? $*text_nosubject : $c.subject;
|
||
|
|
|
||
|
|
var string state = "state";
|
||
|
|
if ($c.frozen) {
|
||
|
|
$state = "frozen";
|
||
|
|
} elseif ($c.screened) {
|
||
|
|
$state = "screened";
|
||
|
|
}
|
||
|
|
|
||
|
|
println """<div class="nest">""";
|
||
|
|
|
||
|
|
# This "state" div is a dodgy hack for the JavaScript set_handler stuff.
|
||
|
|
# It'll be changed to "frozen", "screened" etc. if the quick-change buttons
|
||
|
|
# are used.
|
||
|
|
# No apologies. :P
|
||
|
|
"""
|
||
|
|
<div class="$state" id="state$c.talkid">
|
||
|
|
<div class="$class" id="$c.dom_id">
|
||
|
|
<div class="left">
|
||
|
|
""";
|
||
|
|
if ($c.userpic) {
|
||
|
|
"""<div class="userpic">""";
|
||
|
|
print $c.userpic->as_string();
|
||
|
|
"""</div>""";
|
||
|
|
} else {
|
||
|
|
"""<div class="userpic empty"> </div>""";
|
||
|
|
}
|
||
|
|
$this->lay_print_comment_linkbar($c);
|
||
|
|
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
<div class="right">
|
||
|
|
<div class="header">
|
||
|
|
<div class="title">
|
||
|
|
<h3 id="t$c.talkid"><a href="$c.permalink_url">$subject</a></h2>
|
||
|
|
""";
|
||
|
|
if (defined $c.subject_icon) {
|
||
|
|
print """<span class="icon">""" + $c.subject_icon->as_string() + "</span>";
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
<div class="posted">"""; $this->lay_print_posted_by($c); """</div>
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
$this->lay_print_text($c);
|
||
|
|
$this->lay_print_comment_links($c);
|
||
|
|
"""
|
||
|
|
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
$c->print_reply_container({"class" => "quickreply"});
|
||
|
|
"""
|
||
|
|
<div id="c-reply-$c.talkid"></div>
|
||
|
|
""";
|
||
|
|
|
||
|
|
$this->print_comments($c.replies);
|
||
|
|
|
||
|
|
"""</div>""";
|
||
|
|
}
|
||
|
|
|
||
|
|
function EntryPage::print_comment_partial(Comment c) {
|
||
|
|
|
||
|
|
var string poster = defined $c.poster ? $c.poster->as_string() : $*text_poster_anonymous;
|
||
|
|
var string subject = $c.subject != "" ? $c.subject : $*text_nosubject;
|
||
|
|
|
||
|
|
"""
|
||
|
|
<div class="nest">
|
||
|
|
<div class="collapsed-comment">
|
||
|
|
""";
|
||
|
|
if ( $c.deleted ) {
|
||
|
|
"""<span class="title">(deleted comment)</span>""";
|
||
|
|
} elseif ( $c.screened ) {
|
||
|
|
"""
|
||
|
|
<a class="title" href="$c.permalink_url">$subject</a> — <span class="poster">$poster</span> [screened]
|
||
|
|
""";
|
||
|
|
} else {
|
||
|
|
"""
|
||
|
|
<a class="title" href="$c.permalink_url">$subject</a> — <span class="poster">$poster</span>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
$this->print_comments($c.replies);
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
function EntryPage::print_comments(Comment[] comments) {
|
||
|
|
if (size $comments == 0) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
foreach var Comment c ($comments) {
|
||
|
|
if ($c.full) {
|
||
|
|
$this->print_comment($c);
|
||
|
|
}
|
||
|
|
# special case for suspended comments.
|
||
|
|
elseif ( $this->lay_comment_poster_is_suspended($c) ) {
|
||
|
|
$this->print_comment($c);
|
||
|
|
} else {
|
||
|
|
$this->print_comment_partial($c);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
function EntryPage::lay_print_entry_left(Entry e) : void {
|
||
|
|
"""
|
||
|
|
<div class="userpic
|
||
|
|
""";
|
||
|
|
if ($e.userpic) {
|
||
|
|
print " empty";
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
">
|
||
|
|
""";
|
||
|
|
if ($e.userpic) {
|
||
|
|
print $e.userpic->as_string();
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
$this->lay_print_entry_linkbar($.entry);
|
||
|
|
}
|
||
|
|
function EntryPage::lay_print_entry_footer(Entry e) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
function EntryPage::print_entry(Entry e) {
|
||
|
|
$this->lay_print_entry($e);
|
||
|
|
}
|
||
|
|
|
||
|
|
function EntryPage::lay_comment_pagination() : void {
|
||
|
|
|
||
|
|
# no comments
|
||
|
|
if ($.entry.comments.count == 0) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
var ItemRange range = $.comment_pages;
|
||
|
|
|
||
|
|
# only one page of comments
|
||
|
|
if ($range.all_subitems_displayed) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
"""
|
||
|
|
<div class="comment-pagination">
|
||
|
|
""";
|
||
|
|
|
||
|
|
if ( $range.url_last != "" ) {
|
||
|
|
"""<a href="$range.url_last">←</a>""";
|
||
|
|
}
|
||
|
|
foreach var int page (1 .. $range.total) {
|
||
|
|
if ($range.current != $page) {
|
||
|
|
""" <a href='""" + $range->url_of($page) + """'>$page</a> """;
|
||
|
|
} else {
|
||
|
|
""" $page """;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if ( $range.url_next != "" ) {
|
||
|
|
"""<a href="$range.url_next">→</a>""";
|
||
|
|
}
|
||
|
|
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
function EntryPage::lay_print_comments() : void {
|
||
|
|
|
||
|
|
if ( $.entry.comments.enabled and size $.comments > 0 ) {
|
||
|
|
|
||
|
|
# JavaScript voodoo.
|
||
|
|
#
|
||
|
|
#
|
||
|
|
set_handler("screen_comment_#", [
|
||
|
|
[ "set_class", "state#", "screened" ]
|
||
|
|
]);
|
||
|
|
set_handler("freeze_comment_#", [
|
||
|
|
[ "set_class", "state#", "frozen" ]
|
||
|
|
]);
|
||
|
|
set_handler("unscreen_comment_#", [
|
||
|
|
[ "set_class", "state#", "state" ]
|
||
|
|
]);
|
||
|
|
set_handler("unfreeze_comment_#", [
|
||
|
|
[ "set_class", "state#", "state" ]
|
||
|
|
]);
|
||
|
|
|
||
|
|
"""
|
||
|
|
<div id="comments">
|
||
|
|
""";
|
||
|
|
|
||
|
|
if ($.multiform_on) {
|
||
|
|
$this->print_multiform_start();
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->print_comments($.comments);
|
||
|
|
|
||
|
|
if ($.multiform_on) {
|
||
|
|
"""
|
||
|
|
<div id="multiform">
|
||
|
|
""";
|
||
|
|
$this->print_multiform_actionline();
|
||
|
|
$this->print_multiform_end();
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
function EntryPage::lay_print_entry_comments_bar() : void {
|
||
|
|
"""
|
||
|
|
<div class="entry-comments-bar">
|
||
|
|
<span class="comments-title">""";
|
||
|
|
$this->lay_print_comment_details( $.entry.comments );
|
||
|
|
$this->lay_print_entry_reply_link( $.entry.comments );
|
||
|
|
"""</span>
|
||
|
|
"""; $this->lay_comment_pagination(); """
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
function EntryPage::print_body() : void {
|
||
|
|
|
||
|
|
if ( $.viewing_thread ) {
|
||
|
|
return $this->lay_print_comments();
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->lay_back_forward();
|
||
|
|
"""
|
||
|
|
<div id="entries">
|
||
|
|
""";
|
||
|
|
$this->print_entry($.entry);
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
$this->lay_back_forward();
|
||
|
|
|
||
|
|
$this->lay_print_entry_comments_bar();
|
||
|
|
|
||
|
|
$this->lay_print_comments();
|
||
|
|
|
||
|
|
# Show comment pagination again if necessary.
|
||
|
|
if ( $.comment_pages.total > 1 ) {
|
||
|
|
$this->lay_print_entry_comments_bar();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
###################################################
|
||
|
|
# # #
|
||
|
|
# ~13. # ReplyPage #
|
||
|
|
# # #
|
||
|
|
###################################################
|
||
|
|
|
||
|
|
|
||
|
|
function ReplyPage::lay_print_comment(EntryLite e) {
|
||
|
|
|
||
|
|
var string subject = ($e.subject != "" ? $e.subject : $*text_nosubject);
|
||
|
|
|
||
|
|
"""
|
||
|
|
<div class="comment">
|
||
|
|
<div class="left">
|
||
|
|
<div class="userpic">
|
||
|
|
""";
|
||
|
|
if ($e.userpic) {
|
||
|
|
print $e.userpic->as_string();
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
<div class="right">
|
||
|
|
<div class="header">
|
||
|
|
<div class="title">
|
||
|
|
<h2><a href="$e.permalink_url">$subject</a></h2>
|
||
|
|
</div>
|
||
|
|
<div class="posted">"""; $this->lay_print_posted_by($e); """</div>
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
$this->lay_print_text($e);
|
||
|
|
"""
|
||
|
|
<div class="links">[<a href="$.entry.permalink_url">parent entry</a>] [<a href="$e.permalink_url">$*text_permalink</a>]</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
function ReplyPage::print_body() : void {
|
||
|
|
|
||
|
|
# replying to a comment, not an entry.
|
||
|
|
#
|
||
|
|
"""
|
||
|
|
<div id="entries">
|
||
|
|
""";
|
||
|
|
# replying to an entry?
|
||
|
|
if ( $this.replyto.depth == 0 ) {
|
||
|
|
$this->print_entry($.entry);
|
||
|
|
}
|
||
|
|
# no, it's a comment
|
||
|
|
else {
|
||
|
|
$this->lay_print_comment($.replyto);
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
<div id="reply">
|
||
|
|
<h2>Reply</h2>
|
||
|
|
""";
|
||
|
|
$.form->print();
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
###################################################
|
||
|
|
# # #
|
||
|
|
# ~14. # YearPage #
|
||
|
|
# # #
|
||
|
|
###################################################
|
||
|
|
|
||
|
|
# Prints a list of other linkable years.
|
||
|
|
#
|
||
|
|
function YearPage::lay_print_extra_box() {
|
||
|
|
var string year;
|
||
|
|
if (size $.years < 2) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
"""
|
||
|
|
<div class="extra-box">
|
||
|
|
<h3 class="title">Years</h3>
|
||
|
|
<ul>
|
||
|
|
""";
|
||
|
|
foreach var YearYear y ($.years) {
|
||
|
|
if ($y.displayed) {
|
||
|
|
$year = string($y.year);
|
||
|
|
} else {
|
||
|
|
$year = """<a href="$y.url">$y.year</a>""";
|
||
|
|
}
|
||
|
|
println """<li>$year</li>""";
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
</ul>
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
function YearPage::lay_back_forward() : void {
|
||
|
|
if (size $.years < 2) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
var YearYear next;
|
||
|
|
var YearYear last;
|
||
|
|
|
||
|
|
foreach var YearYear y ($.years) {
|
||
|
|
if ( $y.year == $.year - 1 ) {
|
||
|
|
$last = $y;
|
||
|
|
} elseif ( $y.year == $.year + 1 ) {
|
||
|
|
$next = $y;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
"""
|
||
|
|
<div class="back-forward">
|
||
|
|
""";
|
||
|
|
if ( defined $last ) {
|
||
|
|
"""
|
||
|
|
<div class="back">
|
||
|
|
<a href="$last.url" title="Previous year.">←</a>
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
if ( defined $next ) {
|
||
|
|
"""
|
||
|
|
<div class="forward">
|
||
|
|
<a href="$next.url" title="Next year.">→</a>
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
function YearPage::print_month(YearMonth m) {
|
||
|
|
"""
|
||
|
|
<div class="calendar-month">
|
||
|
|
<h2 class="title"><a href="$m.url">"""+$m->month_format("%%month%%")+"""</a></h2>
|
||
|
|
""";
|
||
|
|
$this->lay_print_month($m);
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
function YearPage::print_body {
|
||
|
|
if ( size $.months == 0 ) {
|
||
|
|
return $this->lay_print_errorpage( $*error_yearpage_no_entries );
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->lay_back_forward();
|
||
|
|
"""
|
||
|
|
<div id="calendar">
|
||
|
|
""";
|
||
|
|
foreach var YearMonth m ($.months) {
|
||
|
|
if ($m.has_entries) {
|
||
|
|
$this->print_month($m);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
"""
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
$this->lay_back_forward();
|
||
|
|
}
|
||
|
|
|
||
|
|
###################################################
|
||
|
|
# # #
|
||
|
|
# ~15. # MessagePage #
|
||
|
|
# # #
|
||
|
|
# # Just a stub. AFAICT it's not used in the #
|
||
|
|
# # core yet, so I can't test it. #
|
||
|
|
# # #
|
||
|
|
###################################################
|
||
|
|
|
||
|
|
function MessagePage::print_body() {
|
||
|
|
"""
|
||
|
|
<div id="message">
|
||
|
|
<p>"""; $this->print_message(); """</p>
|
||
|
|
</div>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
###################################################
|
||
|
|
# # #
|
||
|
|
# ~16. # TagsPage #
|
||
|
|
# # #
|
||
|
|
###################################################
|
||
|
|
|
||
|
|
# Weighted tag cloud / heatmap.
|
||
|
|
#
|
||
|
|
function TagsPage::print_body() {
|
||
|
|
# since there is no heading, make invisible one here for
|
||
|
|
# screenreaders
|
||
|
|
"""
|
||
|
|
<div id="tag-cloud" class="tags_cloud">
|
||
|
|
<h2 class="invisible">Visible tags</h2>
|
||
|
|
<ul>
|
||
|
|
""";
|
||
|
|
|
||
|
|
# font min and max as % values
|
||
|
|
var int fontmin = 80;
|
||
|
|
var int fontmax = 400;
|
||
|
|
var int fontspread = $fontmax - $fontmin;
|
||
|
|
|
||
|
|
var int fontstep = 0;
|
||
|
|
|
||
|
|
# set later
|
||
|
|
var int countspread;
|
||
|
|
var int fontsize;
|
||
|
|
var string font;
|
||
|
|
|
||
|
|
var int highest = 0;
|
||
|
|
var int lowest = 999999;
|
||
|
|
var int count;
|
||
|
|
|
||
|
|
foreach var TagDetail tag ($.tags) {
|
||
|
|
if ($tag.use_count > $highest) {
|
||
|
|
$highest = $tag.use_count;
|
||
|
|
}
|
||
|
|
if ($tag.use_count < $lowest) {
|
||
|
|
$lowest = $tag.use_count;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
$countspread = $highest - $lowest;
|
||
|
|
|
||
|
|
if ($countspread > 0) {
|
||
|
|
$fontstep = $fontspread/$countspread;
|
||
|
|
}
|
||
|
|
|
||
|
|
foreach var TagDetail tag ($.tags) {
|
||
|
|
if ($highest == $lowest) {
|
||
|
|
$font = string($fontmin) + "%";
|
||
|
|
} else {
|
||
|
|
$fontsize = $fontmin + (($tag.use_count - $lowest) * $fontstep);
|
||
|
|
$font = string($fontsize) + "%";
|
||
|
|
}
|
||
|
|
|
||
|
|
"""
|
||
|
|
<li>
|
||
|
|
<a rel="tag" class="used-$tag.use_count visible-to-$tag.visibility" href="$tag.url" style="font-size: $font;">$tag.name</a>
|
||
|
|
<span class ="invisible"> used $tag.use_count times</span></li>
|
||
|
|
""";
|
||
|
|
}
|
||
|
|
|
||
|
|
"""
|
||
|
|
</ul></div>
|
||
|
|
""";
|
||
|
|
}
|