bin/upgrading/s2layers/zesty/layout.s2
author fu
Fri Jan 27 17:59:59 2012 +0800
changeset 4240 5bab31c9f015
parent 4224 701719de9628
child 4302 4fc7eee083ff
permissions -rw-r--r--
http://bugs.dwscoalition.org/show_bug.cgi?id=4245

Call keywords in list context, so that we get a list instead of a comma-separated string. Add a bit of padding because we no longer have a physical comma.

Patch by fu.
mark@629
     1
# -*-s2-*-
mark@629
     2
layerinfo "type" = "layout";
mark@629
     3
layerinfo "name" = "Zesty";
mark@629
     4
layerinfo "lang" = "en";
mark@629
     5
layerinfo "author" = "Sam Angove";
mark@629
     6
layerinfo "author_email" = "net.rephrase@sam";
mark@629
     7
layerinfo "is_public" = 1;
mark@629
     8
layerinfo "source_viewable" = 1;
mark@629
     9
layerinfo "redist_uniq" = "zesty/layout";
mark@629
    10
mark@629
    11
###################################################
mark@629
    12
#                                                 #
mark@629
    13
#                   [S2] Zesty                    #
mark@629
    14
#                                                 #
mark@629
    15
#                Table of Contents                #
mark@629
    16
#                =================                #
mark@629
    17
#                                                 #
mark@629
    18
# ~i.   Changelog                                 #
mark@629
    19
# ~ii.  License                                   #
mark@629
    20
# ~iii. Notes                                     #
mark@629
    21
#                                                 #
mark@629
    22
# Customization/i18n Properties                   #
mark@629
    23
# -----------------------------                   #
mark@629
    24
# ~1.  Properties                                 #
mark@629
    25
#                                                 #
mark@629
    26
# Utility functions                               #
mark@629
    27
# -----------------                               #
mark@629
    28
# ~2.  Utility functions                          #
mark@629
    29
#                                                 #
mark@629
    30
# CSS                                             #
mark@629
    31
# ---                                             #
mark@629
    32
# ~3.  Stylesheet                                 #
mark@629
    33
#                                                 #
mark@629
    34
# Shared methods                                  #
mark@629
    35
# --------------                                  #
mark@629
    36
# Methods used on multiple views for getting or   #
mark@629
    37
# printing information about entries.             #
mark@629
    38
#                                                 #
mark@629
    39
# ~4. EntryLite                                   #
mark@629
    40
# ~5. CommentInfo                                 #
mark@629
    41
# ~6. Entry                                       #
mark@629
    42
#                                                 #
mark@629
    43
# Global view                                     #
mark@629
    44
# -----------                                     #
mark@629
    45
# Templates used on all views as well as methods  #
mark@629
    46
# overridden by specific views.                   #
mark@629
    47
#                                                 #
mark@629
    48
# ~7. Page                                        #
mark@629
    49
#                                                 #
mark@629
    50
# Regular views                                   #
mark@629
    51
# -------------                                   #
mark@629
    52
# These four views have substantially similar     #
mark@629
    53
# logic.                                          #
mark@629
    54
#                                                 #
mark@629
    55
# ~8.  RecentPage                                 #
mark@629
    56
# ~9.  FriendsPage                                #
mark@629
    57
# ~10. DayPage                                    #
mark@629
    58
# ~11. MonthPage                                  #
mark@629
    59
#                                                 #
mark@629
    60
# Entry views                                     #
mark@629
    61
# -----------                                     #
mark@629
    62
# These views require significant extra logic.    #
mark@629
    63
# They are not available to free users.           #
mark@629
    64
#                                                 #
mark@629
    65
# ~12. EntryPage                                  #
mark@629
    66
# ~13. ReplyPage                                  #
mark@629
    67
#                                                 #
mark@629
    68
# Miscellaneous views                             #
mark@629
    69
# -------------------                             #
mark@629
    70
# These views cannot print entries.               #
mark@629
    71
#                                                 #
mark@629
    72
# ~14. YearPage                                   #
mark@629
    73
# ~15. MessagePage                                #
mark@629
    74
# ~16. TagsPage                                   #
mark@629
    75
#                                                 #
mark@629
    76
###################################################
mark@629
    77
mark@629
    78
###################################################
mark@629
    79
#      #                                          #
mark@629
    80
# ~i.  # ~Changelog                               #
mark@629
    81
#      #                                          #
mark@629
    82
###################################################
mark@629
    83
mark@629
    84
# 2006-07-18 -- I can't remember, but I'm releasing it now. ;)
mark@629
    85
# 2006-07-10 -- English stripping
mark@629
    86
# 2006-07-09 -- general cleanup, fix footer
mark@629
    87
# 2006-07-03 -- initial build
mark@629
    88
#
mark@629
    89
mark@629
    90
###################################################
mark@629
    91
#      #                                          #
mark@629
    92
# ~ii. # ~License                                 #
mark@629
    93
#      #                                          #
mark@629
    94
###################################################
mark@629
    95
mark@629
    96
# "Zesty" LiveJournal S2 style
mark@629
    97
#
mark@629
    98
# Copyright (c) 2006 Sam Angove
mark@629
    99
#
mark@629
   100
# This program is free software; you can redistribute it and/or modify
mark@629
   101
# it under the terms of the GNU General Public License as published by
mark@629
   102
# the Free Software Foundation; either version 2 of the License, or
mark@629
   103
# (at your option) any later version.
mark@629
   104
#
mark@629
   105
# This program is distributed in the hope that it will be useful,
mark@629
   106
# but WITHOUT ANY WARRANTY; without even the implied warranty of
mark@629
   107
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
mark@629
   108
# GNU General Public License for more details.
mark@629
   109
#
mark@629
   110
# You should have received a copy of the GNU General Public License along
mark@629
   111
# with this program; if not, write to the Free Software Foundation, Inc.,
mark@629
   112
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
mark@629
   113
mark@629
   114
###################################################
mark@629
   115
#      #                                          #
mark@629
   116
# ~ii. # ~Notes                                   #
mark@629
   117
#      #                                          #
mark@629
   118
###################################################
mark@629
   119
mark@629
   120
# - The CSS is very messy. Haven't had time to clean it up. Sorry!
mark@629
   121
#
mark@629
   122
# - Most customization properties are for i18n purposes. Note that many of
mark@629
   123
#   them use the `lay_string_placeholders()` function; it's not wholly
mark@629
   124
#   satisfactory but it's more flexible than the core.
mark@629
   125
#
mark@629
   126
# - There are no props for colours, borders etc. It's a huge headache and
mark@629
   127
#   I can't be bothered.  Since this isn't a core style, no-one but a paid
mark@629
   128
#   user can use it anyway, and they'll be able to edit the CSS directly.
mark@629
   129
#
mark@629
   130
# - I have deliberately ignored OOP and used
mark@629
   131
#      `View::lay_print_obj(Obj o)` over `var Obj o; $o->print()`
mark@629
   132
#   wherever possible. It's usually futile to use the latter because
mark@629
   133
#   the method needs to be overridable in different views -- different
mark@629
   134
#   requirements for entry printing on MonthPage and EntryPage, for example.
mark@629
   135
#
mark@629
   136
#   Global functions have been avoided for the same reason.
mark@629
   137
mark@629
   138
mark@629
   139
###################################################
mark@629
   140
#      #                                          #
mark@629
   141
# !1.  # !Properties                              #
mark@629
   142
#      #                                          #
mark@629
   143
###################################################
mark@629
   144
mark@892
   145
propgroup presentation {
mark@892
   146
    property use num_items_recent;
mark@892
   147
    property use num_items_reading;
mark@892
   148
    property use use_journalstyle_entry_page;
afuna@932
   149
    property use tags_page_type;
fu@2347
   150
    property use use_shared_pic;
fu@2456
   151
    property use userlite_interaction_links;
fu@2456
   152
    property use entry_management_links;
fu@2456
   153
    property use comment_management_links;
mark@892
   154
}
mark@892
   155
mark@892
   156
set num_items_recent = 10;
mark@892
   157
set num_items_reading = 20;
mark@892
   158
mark@629
   159
propgroup Text {
mark@629
   160
    property use text_day_next;
mark@629
   161
    property use text_day_prev;
mark@629
   162
    property use text_skiplinks_back;
mark@629
   163
    property use text_skiplinks_forward;
mark@629
   164
mark@629
   165
    property use text_permalink;
mark@1651
   166
    property use text_stickyentry_subject;
mark@629
   167
    property use text_post_comment;
mark@629
   168
    property use text_post_comment_friends;
mark@629
   169
mark@629
   170
        set text_permalink = "permalink";
mark@1651
   171
        set text_stickyentry_subject = "Sticky: ";
mark@629
   172
        set text_post_comment = "reply";
mark@629
   173
        set text_post_comment_friends = "reply";
mark@629
   174
mark@629
   175
    property use text_nosubject;
mark@629
   176
    property use text_poster_anonymous;
mark@629
   177
mark@629
   178
        set text_nosubject = "(no subject)";
mark@629
   179
        set text_poster_anonymous = "(anonymous)";
mark@629
   180
mark@629
   181
    property use text_meta_mood;
mark@629
   182
    property use text_meta_music;
mark@629
   183
mark@629
   184
        set text_meta_mood = "Mood";
mark@629
   185
        set text_meta_music = "Music";
mark@629
   186
mark@629
   187
    property use text_view_archive;
mark@629
   188
    property use text_view_recent;
mark@629
   189
    property use text_view_friends;
mark@629
   190
    property use text_view_month;
mark@629
   191
    property use text_view_userinfo;
mark@629
   192
mark@629
   193
        set text_view_archive = "Calendar";
mark@629
   194
        set text_view_recent = "Recent";
mark@629
   195
        set text_view_friends = "Read";
mark@629
   196
        set text_view_month = "Monthly Archive";
mark@629
   197
        set text_view_userinfo = "Profile";
mark@629
   198
mark@629
   199
mark@629
   200
    # For these properties I use a format vaguely similar to printf/sprintf.
mark@629
   201
    # They're passed to a method which gives them an array of strings.
mark@629
   202
    # you can use printf-style %s to insert the strings one at a time, or
mark@629
   203
    # use %1, %2 .. %9 to select them by number.
mark@629
   204
    #
mark@629
   205
    # Example: this string "posted by %1 at %2 on %3" is passed an array
mark@629
   206
    # containing the entry poster, the time of posting and the date of
mark@629
   207
    # posting.
mark@629
   208
    #
mark@629
   209
    # %1 will always refer to the poster, so a reformulation might be
mark@629
   210
    # something like "at %2 on %3, %1 wrote:".
mark@629
   211
    #
mark@629
   212
    # It's perfectly okay to ignore some or all of the arguments. That is,
mark@629
   213
    # there's nothing wrong with something like "I said on %3".
mark@629
   214
mark@629
   215
    property string posted_by_at_on {
mark@629
   216
        noui = 1;
mark@629
   217
        des = "Posted by [1:poster] at [2:time] on [3:date] string.";
mark@629
   218
    }
mark@629
   219
        set posted_by_at_on = "posted by %1 at %2 on %3";
mark@629
   220
mark@629
   221
    property string posted_by_at_on_in {
mark@629
   222
        noui = 1;
mark@629
   223
        des = "Posted by [1:poster] at [2:time] on [3:date] under [4:tags] string.";
mark@629
   224
    }
mark@629
   225
        set posted_by_at_on_in = "posted by %1 at %2 on %3 under %4";
mark@629
   226
mark@629
   227
    property string posted_by_at_on_from {
mark@629
   228
        noui = 1;
mark@629
   229
        des = "Posted by [1:poster] at [2:time] on [3:date] from [4:ip address] string.";
mark@629
   230
    }
mark@629
   231
        set posted_by_at_on_from = "posted by %1 at %2 on %3 from %4";
mark@629
   232
mark@629
   233
    property string poster_in_journal {
mark@629
   234
        noui = 1;
mark@629
   235
        des = "[1:poster] in [2:journal] string";
mark@629
   236
    }
mark@629
   237
        set poster_in_journal = "%1 in %2";
mark@629
   238
mark@629
   239
    property string posted_time_format {
mark@629
   240
        noui = 1;
mark@629
   241
        des = "[time] format for from 'posted by [poster] at [time] ...'";
mark@629
   242
    }
mark@629
   243
        set posted_time_format = "%%hh%%:%%min%%%%a%%m";
mark@629
   244
fu@2381
   245
    property string posted_time_format_24 {
fu@2381
   246
        noui = 1;
fu@2381
   247
        des = "[time] format for from 'posted by [poster] at [time] ...'";
fu@2381
   248
    }
fu@2381
   249
        set posted_time_format_24 = "%%HH%%:%%min%%";
fu@2381
   250
mark@629
   251
    property string posted_date_format {
mark@629
   252
        noui = 1;
mark@629
   253
        des = "[date] format for 'posted by [poster] at [time] on [date] ...'";
mark@629
   254
    }
mark@629
   255
        set posted_date_format = "%%dd%%/%%mm%%/%%yyyy%%";
mark@629
   256
mark@629
   257
mark@629
   258
    # I want to have links like this:
mark@629
   259
    #
mark@629
   260
    #   There are <a href="...">2 comments</a> on this entry.
mark@629
   261
    #
mark@629
   262
    # The HTML can't be part of the property, because S2 "helpfully" escapes
mark@629
   263
    # it for me. This ugly hack is used instead, wrapping $*text_a_comment_link
mark@629
   264
    # inside $*text_a_comment.
mark@629
   265
    #
mark@629
   266
    # ('There is <a href="%1">%2 comment</a> on this entry.')
mark@629
   267
    property string text_a_comment_link { }
mark@629
   268
    property string text_a_comment { }
mark@629
   269
        set text_a_comment_link = "%1 comment";
mark@629
   270
        set text_a_comment = "There is %1 on this entry.";
mark@629
   271
mark@629
   272
    property string text_some_comments_link { }
mark@629
   273
    property string text_some_comments { }
mark@629
   274
        set text_some_comments_link = "%1 comments";
mark@629
   275
        set text_some_comments = "There are %1 on this entry.";
mark@629
   276
mark@629
   277
    property string text_some_comments_over_pages { }
mark@629
   278
        set text_some_comments_over_pages = "There are %1 over %2 pages.";
mark@629
   279
mark@629
   280
    property string text_no_comments {}
mark@629
   281
        set text_no_comments = "There are no comments on this entry.";
mark@629
   282
mark@629
   283
    property string text_comments_disabled {}
mark@629
   284
        set text_comments_disabled = "Comments are disabled.";
mark@629
   285
mark@629
   286
    property string text_errorpage_title {
mark@629
   287
        des = "Error page title.";
mark@629
   288
        noui = 1;
mark@629
   289
    }
afuna@879
   290
        set text_errorpage_title = "No content";
mark@629
   291
mark@629
   292
mark@629
   293
    # For some reason the core only provides a message for recent and day pages.
mark@629
   294
    #
mark@629
   295
    property string error_monthpage_no_entries {
mark@629
   296
        noui = 1;
mark@629
   297
        des = "Error message shown if no entries are available on a MonthPage";
mark@629
   298
    }
mark@629
   299
        set error_monthpage_no_entries = "No entries were posted on the selected month.";
mark@629
   300
mark@629
   301
    property string error_yearpage_no_entries {
mark@629
   302
        noui = 1;
mark@629
   303
        des = "Error message shown if no entries are available on a YearPage";
mark@629
   304
    }
mark@629
   305
        set error_yearpage_no_entries = "No entries were posted on the selected year.";
mark@629
   306
mark@629
   307
    property string text_html_title {
mark@629
   308
        des = "Title that goes in the HTML <title> element. Is given two parameters, global title and view title.";
mark@629
   309
    }
mark@629
   310
        set text_html_title = "%2 [%1]";
mark@629
   311
mark@629
   312
    property string collapsed_entry_comments_disabled {
mark@629
   313
        des = "String shown on a collapsed entry if comments are disabled.";
mark@629
   314
    }
mark@629
   315
        set collapsed_entry_comments_disabled = "(-)";
mark@629
   316
mark@629
   317
    property string collapsed_entry_comments_max_flag {
mark@629
   318
        des = "Passed into the comment-count string as %2 if an entry's maximum comments have been reached.";
mark@629
   319
    }
mark@629
   320
        set collapsed_entry_comments_max_flag = "!";
mark@629
   321
    property string collapsed_entry_comments_screened_flag {
mark@629
   322
        des = "Passed into the comment-count string as %3 if an entry has screened comments visible to the user.";
mark@629
   323
    }
mark@629
   324
        set collapsed_entry_comments_screened_flag = "*";
mark@629
   325
mark@629
   326
    property string collapsed_entry_comments_count {
mark@629
   327
        des = "Comment-count shown on a collapsed entry, not shown if there are no comments.";
mark@629
   328
        note = "'%1' will be replaced by the number of comments. If the maximum number of comments
mark@629
   329
        has been reached, %2 will contain the max flag. If there are screened comments visible to
mark@629
   330
        the user, %3 will contain the screened flag.";
mark@629
   331
    }
mark@629
   332
        set collapsed_entry_comments_count = "(%1%2%3)";
mark@629
   333
mark@629
   334
    property string linklist_default_title {
mark@629
   335
        des = "Linklist title.";
mark@629
   336
    }
mark@629
   337
        set linklist_default_title = "Links";
mark@629
   338
mark@629
   339
    property string reply_link_link_text {
mark@629
   340
        des = "Text for the reply link.";
mark@629
   341
    }
mark@629
   342
        set reply_link_link_text = "Reply";
mark@629
   343
mark@629
   344
    property string reply_link_text {
mark@629
   345
        des = "Non-linked reply link text. %1 is replaced with the link.";
mark@629
   346
    }
mark@629
   347
    set reply_link_text = "(%1.)";
mark@629
   348
mark@629
   349
    property string top_link_text {
mark@629
   350
        des = "Text of the link to return to the top of the page.";
mark@629
   351
    }
mark@629
   352
        set top_link_text = "Top";
mark@629
   353
mark@629
   354
    property use text_comment_frozen;
mark@629
   355
    property use text_comment_parent;
mark@629
   356
    property use text_comment_reply;
mark@629
   357
mark@629
   358
        set text_comment_frozen = "thread is frozen";
mark@629
   359
        set text_comment_parent = "parent";
mark@629
   360
        set text_comment_reply = "reply";
mark@629
   361
mark@629
   362
mark@629
   363
    property string text_comment_permalink {
mark@629
   364
        des = "Permalink to the comment.";
mark@629
   365
    }
mark@629
   366
        set text_comment_permalink = "link";
mark@629
   367
mark@629
   368
    property string text_comment_poster_is_suspended {
mark@629
   369
        des = "Show on comments posted by suspended users.";
mark@629
   370
        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.";
mark@629
   371
    }
mark@629
   372
        set text_comment_poster_is_suspended = "user is suspended";
mark@629
   373
mark@629
   374
    property string text_comment_parent_entry {
mark@629
   375
        des = "Text for linking to a comment's parent.";
mark@629
   376
    }
mark@629
   377
        set text_comment_parent_entry = "parent entry";
mark@629
   378
}
mark@629
   379
mark@629
   380
mark@629
   381
mark@629
   382
propgroup Miscellaneous {
mark@629
   383
mark@629
   384
    property string custom_favicon {
mark@629
   385
        des = "URL of custom favicon.";
mark@629
   386
        example = "http://example.com/favicon.ico";
mark@629
   387
        }
mark@629
   388
        set custom_favicon = "";
mark@892
   389
    
mark@629
   390
    property string default_view_mode {
mark@657
   391
        des = "Show entries expanded or collapsed by default. Currently this setting affects the reading page only.";
mark@629
   392
        values = "collapsed|Entries collapsed|expanded|Entries expanded";
mark@629
   393
        }
mark@657
   394
        set default_view_mode = "expanded";
mark@629
   395
}
mark@629
   396
mark@629
   397
mark@629
   398
#
mark@629
   399
# Yes, tags are enabled.
mark@629
   400
#
mark@629
   401
set tags_aware = true;
mark@629
   402
mark@629
   403
###################################################
mark@629
   404
#      #                                          #
mark@629
   405
# !2.  # Utility functions.                       #
mark@629
   406
#      #                                          #
mark@629
   407
###################################################
mark@629
   408
mark@629
   409
mark@629
   410
# Converts an associative array to an argument list:
mark@629
   411
#
mark@629
   412
#   var string var = {"id" => "5", "page" => "b"};
mark@629
   413
#   lay_array_to_args($var);
mark@629
   414
#
mark@629
   415
#       "?id=5&page=b"
mark@629
   416
#
mark@629
   417
function lay_array_to_args(string{} items) : string
mark@629
   418
"Converts an associative array to an argument list, i.e. {\"id\" => \"5\", \"page\" => \"b\"} => ?id=5&page=b"
mark@629
   419
{
mark@629
   420
    var string args;
mark@629
   421
    var bool q = false;
mark@629
   422
mark@629
   423
    foreach var string key ($items) {
mark@629
   424
        if ($key != "") {
mark@629
   425
            if (not $q) {
mark@629
   426
                $args = "?";
mark@629
   427
                $q = true;
mark@629
   428
            } else {
mark@629
   429
                $args = $args + "&amp;";
mark@629
   430
            }
mark@629
   431
            $args = $args + "$key=" + $items{"$key"};
mark@629
   432
        }
mark@629
   433
    }
mark@629
   434
    return $args;
mark@629
   435
}
mark@629
   436
mark@629
   437
# pushes a string on to the end of an array, assuming that it's
mark@629
   438
# indexed naturally from zero.
mark@629
   439
#
mark@629
   440
function lay_array_push(string[] input, string add) : string[]
mark@629
   441
"Pushes a new element on to the end of an array."
mark@629
   442
{
mark@629
   443
    $input[size $input] = $add;
mark@629
   444
    return $input;
mark@629
   445
}
mark@629
   446
mark@629
   447
# A bit like sprintf, this inserts an array of strings into a string.
mark@629
   448
# Knows %s, literal %%, and numbered placeholders %1 .. %9.
mark@629
   449
#
mark@629
   450
function lay_string_placeholders( string format, string[] args ) : string
mark@629
   451
"A bit like sprintf, this inserts an array of strings into a string.
mark@629
   452
Handles %s, literal %%, and numbered placeholders %1 .. %9."
mark@629
   453
{
mark@629
   454
    var string output = "";
mark@629
   455
mark@629
   456
    var bool state_found_placeholder = false;
mark@629
   457
    var int found_count = 0;
mark@629
   458
mark@629
   459
    foreach var string s ($format) {
mark@629
   460
        if ( $state_found_placeholder ) {
mark@629
   461
            if ( $s == "%" ) {
mark@629
   462
                $output = $output + $s;
mark@629
   463
            }
mark@629
   464
            # string placeholder
mark@629
   465
            elseif ( $s == "s" ) {
mark@629
   466
                $output = $output + $args[$found_count];
mark@629
   467
                $found_count++;
mark@629
   468
                $state_found_placeholder = false;
mark@629
   469
            }
mark@629
   470
            # numbered placeholder
mark@629
   471
            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" ) {
mark@629
   472
                $output = $output + $args[int($s) - 1];
mark@629
   473
                $state_found_placeholder = false;
mark@629
   474
            }
mark@629
   475
        } elseif ( $s == "%" ) {
mark@629
   476
            $state_found_placeholder = true;
mark@629
   477
        } else {
mark@629
   478
            $output = $output + $s;
mark@629
   479
        }
mark@629
   480
    }
mark@629
   481
    return $output;
mark@629
   482
}
mark@629
   483
mark@629
   484
mark@629
   485
# Returns the current url plus arguments. Needs to be overridden
mark@629
   486
# on most views where it's used.
mark@629
   487
#
mark@629
   488
function Page::lay_build_url(string{} items) : string {
mark@629
   489
    return $.base_url + lay_array_to_args($items);
mark@629
   490
}
mark@629
   491
mark@629
   492
# For paid user override in theme layers
mark@629
   493
function lay_print_extra_boxes() : void
mark@629
   494
    "Paid users can override this in theme layers to easily add content in the 'extra boxes' section of the footer."
mark@629
   495
    { }
mark@629
   496
mark@629
   497
###################################################
mark@629
   498
#      #                                          #
mark@629
   499
# !3.  # Stylesheet.                              #
mark@629
   500
#      #                                          #
mark@629
   501
###################################################
mark@629
   502
mark@629
   503
function print_stylesheet() { """
mark@629
   504
mark@629
   505
html, body {
mark@629
   506
    margin: 0;
mark@629
   507
    padding: 0;
mark@629
   508
    font-family: Verdana, sans-serif;
mark@629
   509
}
mark@629
   510
mark@629
   511
/* regular links */
mark@629
   512
mark@629
   513
a {
mark@629
   514
    color: #2452FF;
mark@629
   515
}
mark@629
   516
a:visited {
mark@629
   517
    color: #142D8B;
mark@629
   518
}
mark@629
   519
a:active, a:hover {
mark@629
   520
    color: #178FFF;
mark@629
   521
}
mark@629
   522
mark@629
   523
img {
mark@629
   524
    border: 0px;
mark@629
   525
}
mark@629
   526
mark@629
   527
mark@629
   528
/* the main header */
mark@629
   529
mark@629
   530
#header {
mark@629
   531
    background: #eee;
mark@629
   532
    padding: 20px 10px 20px 10px;
mark@629
   533
    margin: 0px;
mark@629
   534
}
mark@629
   535
#header h1 {
mark@629
   536
    font: normal 4em Georgia, serif;
mark@629
   537
    color: #333;
mark@629
   538
    margin: 0px;
mark@629
   539
    padding: 40px 0 0 0;
mark@629
   540
}
mark@629
   541
#header p {
mark@629
   542
    color: #999;
mark@629
   543
    font: 1.2em normal Verdana, sans-serif;
mark@629
   544
    margin-top: 5px;
mark@629
   545
}
mark@629
   546
mark@629
   547
/* the navigation menu */
mark@629
   548
mark@629
   549
/*
mark@629
   550
This had to be hacked up to work with IE and I haven't gotten around
mark@629
   551
to cleaning it up yet. Sorry!
mark@629
   552
*/
mark@629
   553
mark@629
   554
#navi {
mark@629
   555
    float:left;
mark@629
   556
    width:100%;
mark@629
   557
    background: #fff;
mark@629
   558
    line-height:normal;
mark@629
   559
    font: normal 0.6em Verdana, sans-serif;
mark@629
   560
    color: #666;
mark@629
   561
}
mark@629
   562
#navi ul {
mark@629
   563
    margin:0;
mark@629
   564
    padding:0px 10px 0 5px;
mark@629
   565
    list-style:none;
mark@629
   566
}
mark@629
   567
#navi li {
mark@629
   568
    display:block;
mark@629
   569
    float:left;
mark@629
   570
    margin: 0 0 0 0;
mark@629
   571
    padding:0;
mark@629
   572
    text-align: center;
mark@629
   573
    border-top: 1px solid #bbb;
mark@629
   574
}
mark@629
   575
mark@629
   576
#navi span {
mark@629
   577
    float:left;
mark@629
   578
    display:block;
mark@629
   579
    padding:4px 12px 5px 10px;
mark@629
   580
    margin: 0 1px 0 1px;
mark@629
   581
}
mark@629
   582
#navi a {
mark@629
   583
    display: block;
mark@629
   584
    color: #666;
mark@629
   585
    text-decoration: none;
mark@629
   586
    background: #ddd;
mark@629
   587
    float: left;
mark@629
   588
    padding: 0;
mark@629
   589
    margin-right: 1px;
mark@629
   590
    border-bottom: 1px solid white;
mark@629
   591
}
mark@629
   592
mark@629
   593
#navi a:hover,
mark@629
   594
#navi a:active {
mark@629
   595
    background: #888;
mark@629
   596
    color: #fff;
mark@629
   597
}
mark@629
   598
mark@629
   599
#navi li#tab-current {
mark@629
   600
    border-top: 1px solid #eee;
mark@629
   601
}
mark@629
   602
mark@629
   603
#navi li#tab-current a {
mark@629
   604
    display: inline;
mark@629
   605
    float: none;
mark@629
   606
    background: #eee;
mark@629
   607
    border: 0;
mark@629
   608
    margin: 0;
mark@629
   609
}
mark@629
   610
mark@629
   611
#navi li#tab-current span {
mark@629
   612
    background: #eee;
mark@629
   613
    border-bottom: 1px solid #eee;
mark@629
   614
    color: #555;
mark@629
   615
}
mark@629
   616
mark@629
   617
/* back-and-forward navigation */
mark@629
   618
mark@629
   619
.back-forward {
mark@629
   620
    width: 100%;
mark@629
   621
    float: left;
mark@629
   622
    clear: both;
mark@629
   623
}
mark@629
   624
.back-forward a, .back-forward a:visited {
mark@629
   625
    color: #999;
mark@629
   626
    text-decoration: none;
mark@629
   627
}
mark@629
   628
mark@629
   629
.back-forward a:active,
mark@629
   630
.back-forward a:hover {
mark@629
   631
    color: #333;
mark@629
   632
}
mark@629
   633
.back-forward .back,
mark@629
   634
.back-forward .forward {
mark@629
   635
    padding: 10px;
mark@629
   636
    font: normal 2em Verdana, sans-serif;
mark@629
   637
mark@629
   638
}
mark@629
   639
.back-forward .back {
mark@629
   640
    float: left;
mark@629
   641
    clear: left;
mark@629
   642
}
mark@629
   643
.back-forward .forward {
mark@629
   644
    float: right;
mark@629
   645
    clear: right;
mark@629
   646
}
mark@629
   647
mark@629
   648
mark@629
   649
/* global footer */
mark@629
   650
mark@629
   651
#footer {
mark@629
   652
    color: #999;
mark@629
   653
    font: 0.6em normal Verdana, sans-serif;
mark@629
   654
    margin: 0;
mark@629
   655
    text-align: right;
mark@629
   656
    padding: 10px 5px 5px 5px;
mark@629
   657
    background-color: #fff;
mark@629
   658
    clear: both;
mark@629
   659
}
mark@629
   660
mark@629
   661
.top-link {
mark@629
   662
    float: left;
mark@629
   663
}
mark@629
   664
mark@629
   665
/* extra boxes below main content */
mark@629
   666
mark@629
   667
.extra-box {
mark@629
   668
    float:left;
mark@629
   669
    width: 25%;
mark@629
   670
    margin: 20px;
mark@629
   671
    padding: 10px;
mark@629
   672
}
mark@629
   673
.extra-box > ul {
mark@629
   674
    list-style-type: square;
mark@629
   675
    margin: 0;
mark@629
   676
    padding: 2px 2px 2px 10px;
mark@629
   677
}
mark@629
   678
.extra-box .title {
mark@629
   679
    color: #3c0;
mark@629
   680
    font: normal 1.4em Verdana, sans-serif;
mark@629
   681
}
mark@629
   682
mark@629
   683
/* entries */
mark@629
   684
mark@629
   685
#entries {
mark@629
   686
    clear: both;
mark@629
   687
    margin: 10px;
mark@629
   688
    margin-left: 10px;
mark@629
   689
    padding: 10px;
mark@629
   690
}
mark@629
   691
.entry .left {
mark@629
   692
    text-align: center;
mark@629
   693
    float: left;
mark@629
   694
    width: 120px;
mark@629
   695
    padding-top: 10px;
mark@629
   696
}
mark@629
   697
.entry .right {
mark@629
   698
    margin-left: 150px;
mark@629
   699
}
mark@629
   700
mark@629
   701
mark@629
   702
/* ENTRY */
mark@629
   703
mark@629
   704
h2,
mark@629
   705
h3 {
mark@629
   706
    color: #3c0;
mark@629
   707
    font: normal 2em Verdana, sans-serif;
mark@629
   708
    letter-spacing: -0.1em;
mark@629
   709
    margin: 0;
mark@629
   710
    padding: 0;
mark@629
   711
    display: inline;
mark@629
   712
}
mark@629
   713
mark@629
   714
.title a {
mark@629
   715
    color: #3c0;
mark@629
   716
    text-decoration: none;
mark@629
   717
}
mark@629
   718
.title a:visited {
mark@629
   719
    color: #2b0;
mark@629
   720
}
mark@629
   721
.title a:hover,
mark@629
   722
.title a:active {
mark@629
   723
    color: #4d1;
mark@629
   724
}
mark@629
   725
mark@629
   726
/* shared entry and comments */
mark@629
   727
kareila@2543
   728
.comment-title h4 {
kareila@2543
   729
    font-size: inherit;
kareila@2543
   730
    font-weight: inherit;
fu@2563
   731
    margin: 0;
fu@2563
   732
    padding: 0;
kareila@2543
   733
}
kareila@2543
   734
mark@629
   735
.tools {
mark@629
   736
    text-align: center;
mark@629
   737
    padding: 10px;
mark@629
   738
    border: 1px solid #cde;
mark@629
   739
    background: #def;
mark@629
   740
    clear: both;
mark@629
   741
}
mark@629
   742
mark@629
   743
.frozen .tools {
mark@629
   744
    border: 1px solid #dee;
mark@629
   745
    background: #eff;
mark@629
   746
}
mark@629
   747
.screened .tools {
mark@629
   748
    border: 1px dashed #999;
mark@629
   749
    background: #fff;
mark@629
   750
}
mark@629
   751
.text {
mark@629
   752
    font-size: 90%;
mark@629
   753
}
mark@629
   754
.userpic {
mark@629
   755
    margin-bottom: 5px;
mark@629
   756
}
mark@629
   757
.userpic.empty {
mark@629
   758
    height: 100px;
mark@629
   759
    margin: 0 10px 5px 10px;
mark@629
   760
    border: 1px solid #eee;
mark@629
   761
}
mark@629
   762
mark@629
   763
mark@629
   764
/* Entries */
mark@629
   765
mark@629
   766
.entry {
mark@629
   767
    line-height: 1.3em;
mark@629
   768
    letter-spacing: 0.01em;
mark@629
   769
    margin: 10px 0 40px 0;
mark@629
   770
}
mark@629
   771
.entry .header {
mark@629
   772
    color: #999;
mark@629
   773
    padding: 0px 10px 10px 0;
mark@629
   774
    margin-bottom: 10px;
mark@629
   775
}
mark@629
   776
mark@629
   777
.entry .posted {
mark@629
   778
    margin-left: 5px;
mark@629
   779
}
mark@629
   780
mark@629
   781
.entry .datetime {
mark@629
   782
    margin-left: 20px;
mark@629
   783
}
mark@629
   784
.entry .security {
mark@629
   785
    margin: 0.5em;
mark@629
   786
}
mark@629
   787
mark@629
   788
.entry .meta {
mark@629
   789
    float: left;
mark@629
   790
    clear: both;
mark@629
   791
    padding: 5px;
mark@629
   792
    margin: 10px;
mark@629
   793
    font-size: 80%;
mark@629
   794
    color: #333;
mark@629
   795
    background-color: #def;
mark@629
   796
    border: 1px solid #cde;
mark@629
   797
}
mark@629
   798
mark@629
   799
.entry .links {
mark@629
   800
    color: #999;
mark@629
   801
    clear: both;
mark@629
   802
}
mark@629
   803
mark@629
   804
.entry .meta-label {
mark@629
   805
    font-weight: bold;
mark@629
   806
}
mark@629
   807
mark@629
   808
mark@629
   809
mark@629
   810
.new-day {
mark@629
   811
    margin: 2px 0 2px 150px;
mark@629
   812
    font: normal 1.4em Verdana, sans-serif;
mark@629
   813
    color: #666;
mark@629
   814
}
mark@629
   815
mark@629
   816
mark@629
   817
/* collapsed entries */
mark@629
   818
mark@629
   819
.collapsed-entry {
mark@629
   820
    margin-left: 130px;
mark@629
   821
mark@629
   822
}
mark@629
   823
.collapsed-entry .poster {
mark@629
   824
    font-weight: bold;
mark@629
   825
    font-size: 0.8em;
mark@629
   826
}
mark@629
   827
.expand {
mark@629
   828
    font: normal 1.4em Verdana, sans-serif;
mark@629
   829
}
mark@629
   830
.expand a,
mark@629
   831
.expand a:visited {
mark@629
   832
    color: #ccc;
mark@629
   833
    text-decoration: none;
mark@629
   834
}
mark@629
   835
.expand a:hover,
mark@629
   836
.expand a:active {
mark@629
   837
    color: #333;
mark@629
   838
}
mark@629
   839
.collapsed-entry .title {
mark@629
   840
    font: normal 1.2em Verdana, sans-serif;
mark@629
   841
    letter-spacing: -0.1em;
mark@629
   842
    margin: 0;
mark@629
   843
    padding: 0;
mark@629
   844
    display: inline;
mark@629
   845
}
mark@629
   846
mark@629
   847
mark@629
   848
mark@629
   849
/* Comments */
mark@629
   850
mark@629
   851
#comments {
mark@629
   852
    clear: both;
mark@629
   853
    margin: 10px;
mark@629
   854
    margin-left: 10px;
mark@629
   855
    padding: 10px;
mark@629
   856
}
mark@629
   857
mark@629
   858
.nest {
mark@629
   859
    margin-left: 20px;
mark@629
   860
}
mark@629
   861
mark@629
   862
mark@629
   863
.comment {
mark@629
   864
    line-height: 1.3em;
mark@629
   865
    letter-spacing: 0.01em;
mark@629
   866
    margin: 0;
mark@629
   867
}
mark@629
   868
mark@629
   869
.comment .left {
mark@629
   870
    text-align: center;
mark@629
   871
    float: left;
mark@629
   872
    padding: 5px;
mark@629
   873
    width: 120px;
mark@629
   874
    margin-top: 15px;
mark@629
   875
}
mark@629
   876
mark@629
   877
.comment .right {
mark@629
   878
    padding: 10px;
mark@629
   879
    margin-left: 130px;
mark@629
   880
    background: #fff;
mark@629
   881
    border-bottom: 1px solid #eee;
mark@629
   882
}
mark@629
   883
mark@629
   884
.comment h2 {
mark@629
   885
    color: #3c0;
mark@629
   886
    font: normal 1.3em Verdana, sans-serif;
mark@629
   887
    letter-spacing: -0.1em;
mark@629
   888
    margin: 0;
mark@629
   889
    padding: 0;
mark@629
   890
    display: inline;
mark@629
   891
}
mark@629
   892
mark@629
   893
.comment.odd {
mark@629
   894
    background: #fff;
mark@629
   895
}
mark@629
   896
.comment.even {
mark@629
   897
    background: #fff;
mark@629
   898
}
mark@629
   899
.comment .header {
mark@629
   900
    color: #999;
mark@629
   901
    padding: 10px 10px 10px 0;
mark@629
   902
    margin-bottom: 10px;
mark@629
   903
}
mark@629
   904
.comment .posted {
mark@629
   905
    margin-left: 5px;
mark@629
   906
}
mark@629
   907
.comment .datetime {
mark@629
   908
    margin-left: 20px;
mark@629
   909
}
mark@629
   910
.comment .icon {
mark@629
   911
    margin: 0.5em;
mark@629
   912
}
mark@629
   913
mark@629
   914
.comment .meta {
mark@629
   915
    float: left;
mark@629
   916
    padding: 5px;
mark@629
   917
    margin: 10px;
mark@629
   918
    font-size: 80%;
mark@629
   919
    color: #333;
mark@629
   920
    background-color: #def;
mark@629
   921
    border: 1px solid #cde;
mark@629
   922
}
mark@629
   923
mark@629
   924
.comment .links {
mark@629
   925
    color: #999;
mark@629
   926
    clear: both;
mark@629
   927
}
mark@629
   928
mark@629
   929
/* Collapsed comments */
mark@629
   930
mark@629
   931
.collapsed-comment {
mark@629
   932
    margin: 5px;
mark@629
   933
}
mark@629
   934
.collapsed-comment .title {
mark@629
   935
    font: normal 1.2em Verdana, sans-serif;
mark@629
   936
    letter-spacing: -0.1em;
mark@629
   937
    text-decoration: none;
mark@629
   938
    color: #3c0;
mark@629
   939
}
mark@629
   940
.collapsed-comment .poster {
mark@629
   941
    font-size: 0.8em;
mark@629
   942
}
mark@629
   943
.comment-pagination {
mark@629
   944
    clear: both;
mark@629
   945
    padding: 10px;
mark@629
   946
}
mark@629
   947
mark@629
   948
mark@629
   949
mark@629
   950
.entry-comments-bar {
mark@629
   951
    background: #eee;
mark@629
   952
    clear: both;
mark@629
   953
    padding: 10px;
mark@629
   954
}
mark@629
   955
.entry-comments-bar .comments-title {
mark@629
   956
    font: normal 1.5em Georgia, serif;
mark@629
   957
    color: #333;
mark@629
   958
    padding: 5px;
mark@629
   959
    letter-spacing: 0;
mark@629
   960
    display: block;
mark@629
   961
}
mark@629
   962
mark@629
   963
mark@629
   964
#multiform {
mark@629
   965
    font-size: 0.8em;
mark@629
   966
    margin: 10px;
mark@629
   967
    padding: 10px;
mark@629
   968
    border: 1px solid #cde;
mark@629
   969
    background: #def;
mark@629
   970
}
mark@629
   971
mark@629
   972
mark@629
   973
/* YearPage calendar */
mark@629
   974
mark@629
   975
#calendar {
mark@629
   976
    margin: 10px;
mark@629
   977
    padding: 5px;
mark@629
   978
}
mark@629
   979
mark@629
   980
#calendar .month {
mark@629
   981
    margin: 10px;
mark@629
   982
    float: left;
mark@629
   983
}
mark@629
   984
mark@629
   985
#calendar .header a {
mark@629
   986
    color: #3c0;
mark@629
   987
    text-decoration: none;
mark@629
   988
}
mark@629
   989
mark@629
   990
.month th.weekday {
mark@629
   991
    color: #333;
mark@629
   992
}
mark@629
   993
mark@629
   994
.month .cell {
mark@629
   995
    height: 3em;
mark@629
   996
    width: 3em;
mark@629
   997
}
mark@629
   998
.month .cell.full {
mark@629
   999
    background: #def;
mark@629
  1000
    border: 1px solid #cde;
mark@629
  1001
}
mark@629
  1002
.month .cell.empty {
mark@629
  1003
    border: 1px solid #eee;
mark@629
  1004
}
mark@629
  1005
mark@629
  1006
.month .day {
mark@629
  1007
    text-align: left;
mark@629
  1008
    color: #999;
mark@629
  1009
    font-size: 0.8em;
mark@629
  1010
}
mark@629
  1011
.month .cell.empty .day {
mark@629
  1012
    color: #ddd;
mark@629
  1013
}
mark@629
  1014
.month .count {
mark@629
  1015
    text-align: center;
mark@629
  1016
}
mark@629
  1017
mark@629
  1018
.extra-box .month {
mark@629
  1019
    font-size: 0.5em;
mark@629
  1020
}
mark@629
  1021
mark@629
  1022
/* Comment quickreply */
mark@629
  1023
mark@629
  1024
.quickreply {
mark@629
  1025
    padding: 5px;
mark@629
  1026
}
mark@629
  1027
.quickreply table {
mark@629
  1028
    border: 0px !important;
mark@629
  1029
mark@629
  1030
}
mark@629
  1031
.quickreply span.de {
mark@629
  1032
    display: block;
mark@629
  1033
    float: left;
mark@629
  1034
    font-size: 0.7em;
mark@629
  1035
    background: #def;
mark@629
  1036
    padding: 5px;
mark@629
  1037
    margin: 5px;
mark@629
  1038
    border: 1px solid #cde;
mark@629
  1039
}
mark@629
  1040
.quickreply td[align="right"] {
mark@629
  1041
    font-size: 0.8em;
mark@629
  1042
}
mark@629
  1043
mark@629
  1044
mark@629
  1045
/* TagsPage tag cloud */
mark@629
  1046
mark@629
  1047
#tag-cloud {
mark@629
  1048
    margin: 10px;
mark@629
  1049
    padding: 5px;
mark@629
  1050
}
mark@629
  1051
mark@629
  1052
#tag-cloud a {
mark@629
  1053
    color: #3c0;
mark@629
  1054
    text-decoration: none;
mark@629
  1055
}
mark@629
  1056
fu@2605
  1057
.module-tags_cloud li, .tags_cloud li {
fu@2605
  1058
    display: inline;
fu@2605
  1059
    list-style-type: none;
fu@2605
  1060
}
mark@629
  1061
mark@629
  1062
fu@4217
  1063
/* IconsPage */
fu@4217
  1064
fu@4217
  1065
.icons-container {
fu@4217
  1066
    margin: 10px;
fu@4217
  1067
    padding: 10px;
fu@4217
  1068
    }
fu@4217
  1069
fu@4217
  1070
.sorting-options ul {
fu@4217
  1071
    padding-left: 0;
fu@4217
  1072
    }
fu@4217
  1073
fu@4217
  1074
.sorting-options ul li {
fu@4217
  1075
    display: inline;
fu@4217
  1076
    }
fu@4217
  1077
fu@4217
  1078
.icons-container .icon {
fu@4217
  1079
    margin: 1em 0;
fu@4217
  1080
    }
fu@4217
  1081
fu@4217
  1082
.icon-image {
fu@4217
  1083
    float: left;
fu@4217
  1084
    clear: left;
fu@4217
  1085
    margin-bottom: .25em;
fu@4217
  1086
    min-width: 100px;
fu@4217
  1087
    padding-right: 1em;
fu@4217
  1088
    }
fu@4217
  1089
fu@4217
  1090
.icon-info {
fu@4217
  1091
    min-height: 100px;
fu@4217
  1092
    }
fu@4217
  1093
fu@4217
  1094
.icon-info span {
fu@4217
  1095
    font-weight: bold;
fu@4217
  1096
    }
fu@4217
  1097
fu@4217
  1098
.icon-info .default {
fu@4217
  1099
    text-decoration: underline;
fu@4217
  1100
    }
fu@4217
  1101
fu@4217
  1102
.icon-info .keywords ul {
fu@4217
  1103
    display: inline;
fu@4217
  1104
    padding-left: 0;
fu@4217
  1105
    }
fu@4217
  1106
fu@4217
  1107
.icon-info .keywords ul li {
fu@4217
  1108
    display: inline;
fu@4217
  1109
    list-style: none;
fu@4240
  1110
    padding: 0 .25em 0 0;
fu@4217
  1111
    }
fu@4217
  1112
mark@629
  1113
/* ReplyPage reply box */
mark@629
  1114
mark@629
  1115
#reply {
mark@629
  1116
    margin: 10px 10px 10px 165px;
mark@629
  1117
    padding: 5px;
mark@629
  1118
}
mark@629
  1119
mark@629
  1120
#postform {
mark@629
  1121
    background: #def;
mark@629
  1122
    border: 1px solid #cde;
mark@629
  1123
    padding: 5px;
mark@629
  1124
    margin-top: 10px;
mark@629
  1125
    font-size: 0.8em;
mark@629
  1126
}
mark@629
  1127
mark@629
  1128
mark@629
  1129
"""; }
mark@629
  1130
mark@629
  1131
mark@629
  1132
mark@629
  1133
###################################################
mark@629
  1134
#      #                                          #
mark@629
  1135
#  ~4. # EntryLite                                #
mark@629
  1136
#      #                                          #
mark@629
  1137
###################################################
mark@629
  1138
mark@629
  1139
# Shared methods used on/for both entries and comments.
mark@629
  1140
#
mark@629
  1141
#
mark@629
  1142
mark@629
  1143
mark@629
  1144
# Gets the entry or comment's link icons (freeze, add to memories etc.),
mark@629
  1145
# with the exception of the 'nav_prev' and 'nav_next' which are handled by
mark@629
  1146
# Page::lay_back_forward().
mark@629
  1147
#
mark@629
  1148
function EntryLite::lay_get_linkbar() : string {
mark@629
  1149
    var string o;
mark@629
  1150
    var Link link;
mark@629
  1151
    foreach var string k ($.link_keyseq) {
mark@629
  1152
        if ( $k != "nav_prev" and $k != "nav_next" ) {
mark@629
  1153
            $link = $this->get_link($k);
mark@629
  1154
            if ( defined $link ) {
mark@629
  1155
                $o = $o + $link->as_string();
mark@629
  1156
            }
mark@629
  1157
        }
mark@629
  1158
    }
mark@629
  1159
    return $o;
mark@629
  1160
}
mark@629
  1161
mark@629
  1162
# Returns a comma-separated string of tags.
mark@629
  1163
#
mark@629
  1164
function EntryLite::lay_get_tags() : string {
mark@629
  1165
    var string tags = "";
mark@629
  1166
    if ($.tags) {
mark@629
  1167
        foreach var int i (0 .. (size $.tags - 1)) {
mark@629
  1168
            var Tag t = $.tags[$i];
mark@629
  1169
mark@629
  1170
            $tags = $tags + """<a rel="tag" href="$t.url">$t.name</a>""";
mark@629
  1171
mark@629
  1172
            if ( $i < size $.tags - 1 ) {
mark@629
  1173
                $tags = $tags + ", ";
mark@629
  1174
            }
mark@629
  1175
        }
mark@629
  1176
    }
mark@629
  1177
    return $tags;
mark@629
  1178
}
mark@629
  1179
mark@629
  1180
# Return a string representing the poster of this entry or comment.
mark@629
  1181
#
mark@629
  1182
function Page::lay_get_poster(EntryLite e) : string {
mark@629
  1183
    if ( not defined $e.poster ) {
mark@629
  1184
        return $*text_poster_anonymous;
afuna@788
  1185
    } elseif ( not $e.poster->equals($e.journal) and $.view == "read" ) {
mark@629
  1186
mark@629
  1187
        # default: "%1 in %2"
mark@629
  1188
        return lay_string_placeholders( $*poster_in_journal, [$e.poster->as_string(), $e.journal->as_string()] );
mark@629
  1189
    } else {
mark@629
  1190
        return $e.poster->as_string();
mark@629
  1191
    }
mark@629
  1192
}
mark@629
  1193
mark@629
  1194
mark@629
  1195
mark@629
  1196
# Print a string containing any or all of the poster, date, time, tags
mark@629
  1197
# and ip address of this entry or comment.
mark@629
  1198
#
mark@629
  1199
function Page::lay_print_posted_by(EntryLite e) : void {
mark@629
  1200
    var string format;
mark@629
  1201
    var string[] args;
mark@629
  1202
    var string tags;
fu@2381
  1203
    var string timeformat;
fu@2381
  1204
fu@2381
  1205
    if ($this.timeformat24) {
fu@2381
  1206
        $timeformat = $*posted_time_format_24;
fu@2381
  1207
    } else {
fu@2381
  1208
        $timeformat = $*posted_time_format;
fu@2381
  1209
    }
mark@629
  1210
mark@629
  1211
    # default: "posted by %1 at %2 on %3";
mark@629
  1212
    $format = $*posted_by_at_on;
mark@629
  1213
mark@629
  1214
    $args = [
mark@629
  1215
          $this->lay_get_poster($e),
fu@2381
  1216
          $e.time->date_format( $timeformat ),
mark@629
  1217
          $e.time->date_format( $*posted_date_format )
mark@629
  1218
          ];
mark@629
  1219
mark@629
  1220
    $tags = $e->lay_get_tags();
mark@629
  1221
    if ( $tags != "" ) {
mark@629
  1222
mark@629
  1223
        # default: "posted by %1 at %2 on %3 under %4";
mark@629
  1224
        $format = $*posted_by_at_on_in;
mark@629
  1225
        lay_array_push($args, $tags);
mark@629
  1226
mark@629
  1227
    } elseif ($e.metadata{"poster_ip"}) {
mark@629
  1228
mark@629
  1229
        # default: "posted by %1 at %2 on %3 from %4";
mark@629
  1230
        $format = $*posted_by_at_on_from;
mark@629
  1231
        lay_array_push($args, $e.metadata{"poster_ip"});
mark@629
  1232
    }
mark@629
  1233
mark@629
  1234
    print lay_string_placeholders( $format, $args );
mark@629
  1235
}
mark@629
  1236
mark@629
  1237
# Prints an entry or comment's text.
mark@629
  1238
#
mark@629
  1239
function Page::lay_print_text(EntryLite e) : void
mark@629
  1240
"Prints an entry or comment's text."
mark@629
  1241
{
mark@629
  1242
    println """<div class="text">""";
mark@629
  1243
mark@629
  1244
    $e->print_text();
mark@629
  1245
mark@629
  1246
    println "</div>";
mark@629
  1247
}
mark@629
  1248
mark@629
  1249
mark@629
  1250
###################################################
mark@629
  1251
#      #                                          #
mark@629
  1252
#  ~5. # CommentInfo                              #
mark@629
  1253
#      #                                          #
mark@629
  1254
###################################################
mark@629
  1255
mark@629
  1256
# Get details of an entry's comments.
mark@629
  1257
# show_read_link is included so EntryPage needn't show a link to itself.
mark@629
  1258
#
mark@629
  1259
function CommentInfo::lay_get_details(int pages, bool show_read_link) : string {
mark@629
  1260
    var string link;
mark@629
  1261
    if ($.count > 0) {
mark@629
  1262
mark@629
  1263
        if ( lang_map_plural($.count) ) {
mark@629
  1264
            # "%1 comments"
mark@629
  1265
            $link = lay_string_placeholders($*text_some_comments_link, [string($.count)]);
mark@629
  1266
mark@629
  1267
            if ( $show_read_link ) {
mark@629
  1268
                $link = """<a href="$.read_url">$link</a>""";
mark@629
  1269
            }
mark@629
  1270
mark@629
  1271
            if ( $pages > 1 ) {
mark@629
  1272
                $link = lay_string_placeholders($*text_some_comments_over_pages, [$link, string($pages)]);
mark@629
  1273
            } else {
mark@629
  1274
                $link = lay_string_placeholders($*text_some_comments, [$link]);
mark@629
  1275
            }
mark@629
  1276
        } else {
mark@629
  1277
            # "%1 comment"
mark@629
  1278
            $link = lay_string_placeholders($*text_a_comment_link, [string($.count)]);
mark@629
  1279
            if ( $show_read_link ) {
mark@629
  1280
                $link = """<a href="$.read_url">$link</a>""";
mark@629
  1281
            }
mark@629
  1282
            $link = lay_string_placeholders($*text_a_comment, [$link]);
mark@629
  1283
        }
mark@629
  1284
mark@629
  1285
    } else {
mark@629
  1286
mark@629
  1287
        # default: "There are no comments on this entry."
mark@629
  1288
        $link = $*text_no_comments;
mark@629
  1289
    }
mark@629
  1290
mark@629
  1291
    if (not $.enabled) {
mark@629
  1292
mark@629
  1293
        # default: "Comments are disabled."
mark@629
  1294
        $link = $link + " " + $*text_comments_disabled;
mark@629
  1295
    }
mark@629
  1296
    return $link;
mark@629
  1297
}
mark@629
  1298
mark@629
  1299
function Page::lay_print_comment_details(CommentInfo c) : void {
mark@629
  1300
    print $c->lay_get_details(0, true);
mark@629
  1301
}
mark@629
  1302
mark@629
  1303
# Prints a link to an entry's ReplyPage.
mark@629
  1304
#
mark@629
  1305
function Page::lay_print_entry_reply_link(CommentInfo c) : void {
mark@629
  1306
    if ($c.show_postlink) {
mark@629
  1307
        var string link = """<a href="$c.post_url">$*reply_link_link_text</a>""";
mark@629
  1308
        print " " + lay_string_placeholders( $*reply_link_text, [$link] );
mark@629
  1309
    }
mark@629
  1310
}
mark@629
  1311
mark@629
  1312
mark@629
  1313
###################################################
mark@629
  1314
#      #                                          #
mark@629
  1315
#  ~6. # Entry                                    #
mark@629
  1316
#      #                                          #
mark@629
  1317
###################################################
mark@629
  1318
mark@629
  1319
function Page::lay_print_entry_linkbar(Entry e) {
mark@629
  1320
mark@629
  1321
    var string bar = $e->lay_get_linkbar();
mark@629
  1322
    if ( $bar == "" ) {
mark@629
  1323
        return;
mark@629
  1324
    }
mark@629
  1325
    println """<div class="tools">$bar</div>""";
mark@629
  1326
}
mark@629
  1327
mark@629
  1328
function Page::lay_print_entry_meta(Entry e) : void {
mark@629
  1329
    var string o = "";
mark@629
  1330
    var string caption;
mark@629
  1331
    var string val;
mark@629
  1332
    var Image i;
mark@629
  1333
mark@629
  1334
    if (size $e.metadata == 0) {
mark@629
  1335
        return;
mark@629
  1336
    }
mark@629
  1337
mark@629
  1338
    """
mark@629
  1339
    <div class="meta">
mark@629
  1340
    """;
mark@629
  1341
mark@629
  1342
    foreach var string k ($e.metadata) {
mark@629
  1343
        $caption = $k;
mark@629
  1344
        $val = $e.metadata{$k};
mark@629
  1345
        if ($k == "music") {
mark@629
  1346
            $caption = $*text_meta_music;
mark@629
  1347
        } elseif ($k == "mood") {
mark@629
  1348
            $caption = $*text_meta_mood;
mark@629
  1349
            if (defined $e.mood_icon) {
mark@629
  1350
                $i = $e.mood_icon;
mark@629
  1351
                $val = $i->as_string("'$e.metadata{$k}'")+" "+$val;
mark@629
  1352
            }
mark@629
  1353
        }
mark@629
  1354
        """
mark@629
  1355
        <div class="meta-item"><span class="meta-label">$caption:</span> $val</div>
mark@629
  1356
        """;
mark@629
  1357
    }
mark@629
  1358
    """
mark@629
  1359
    </div>
mark@629
  1360
    """;
mark@629
  1361
}
mark@629
  1362
mark@629
  1363
mark@629
  1364
function Page::lay_print_entry_header(Entry e) {
mark@629
  1365
    var string subject = ($e.subject != "" ? $e.subject : $*text_nosubject);
mark@629
  1366
    """
mark@629
  1367
    <div class="header">
mark@629
  1368
    <div class="title">
mark@629
  1369
        <h2 id="entry-$e.itemid"><a href="$e.permalink_url">$subject</a></h2>
mark@629
  1370
        """;
mark@629
  1371
        if ($e.security != "") {
mark@629
  1372
            print """<span class="security"><img src="$e.security_icon.url" alt="[$e.security]" /></span>""";
mark@629
  1373
        }
mark@629
  1374
        """
mark@629
  1375
    </div>
mark@629
  1376
    <div class="posted">"""; $this->lay_print_posted_by($e); """</div>""";
mark@629
  1377
    """</div>""";
mark@629
  1378
}
mark@629
  1379
mark@629
  1380
mark@629
  1381
function Page::lay_print_entry_left(Entry e) : void {
mark@629
  1382
    """
mark@629
  1383
    <div class="userpic">
mark@629
  1384
    """;
mark@629
  1385
    if ($e.userpic) {
mark@629
  1386
        print $e.userpic->as_string();
mark@629
  1387
    }
mark@629
  1388
    """
mark@629
  1389
    </div>
mark@629
  1390
    """;
mark@629
  1391
}
mark@629
  1392
mark@629
  1393
function Page::lay_print_entry_footer(Entry e) {
mark@629
  1394
    """
mark@629
  1395
    <div class="links">
mark@629
  1396
    """;
mark@629
  1397
    $this->lay_print_comment_details( $e.comments );
mark@629
  1398
    $this->lay_print_entry_reply_link( $e.comments );
mark@629
  1399
    """
mark@629
  1400
    </div>
mark@629
  1401
    """;
mark@629
  1402
}
mark@629
  1403
mark@629
  1404
mark@629
  1405
function Page::lay_print_entry(Entry e) {
mark@629
  1406
    """
mark@629
  1407
    <div class="entry">
mark@629
  1408
        <div class="left">
mark@629
  1409
        """;
mark@629
  1410
            $this->lay_print_entry_left($e);
mark@629
  1411
        """
mark@629
  1412
        </div>
mark@629
  1413
        <div class="right">
mark@629
  1414
        """;
mark@629
  1415
            $this->lay_print_entry_header($e);
mark@629
  1416
            $this->lay_print_text($e);
mark@629
  1417
            $this->lay_print_entry_meta($e);
mark@629
  1418
            $this->lay_print_entry_footer($e);
mark@629
  1419
        """
mark@629
  1420
        </div>
mark@629
  1421
    </div>
mark@629
  1422
    """;
mark@629
  1423
}
mark@629
  1424
mark@629
  1425
function Page::print_entry(Entry e) {
mark@629
  1426
    $this->lay_print_entry($e);
mark@629
  1427
}
mark@629
  1428
mark@1651
  1429
function RecentPage::print_sticky_entry(StickyEntry s) {
mark@1651
  1430
    $this->lay_print_entry($s);
mark@1651
  1431
}
mark@1651
  1432
mark@629
  1433
###################################################
mark@629
  1434
#      #                                          #
mark@629
  1435
# ~6b. # Collapsed Entry                          #
mark@629
  1436
#      #                                          #
mark@629
  1437
###################################################
mark@629
  1438
mark@629
  1439
# MonthPage and FriendsPage by default show only a shortened version of an
mark@629
  1440
# entry. I'm considering the same thing for RecentPage past a threshold --
mark@629
  1441
# one or two full entries followed by a longer list of previously-posted
mark@629
  1442
# titles.
mark@629
  1443
#
mark@629
  1444
# On FriendsPage these entries can be expanded in-place; on MonthPage
mark@629
  1445
# the entry text isn't populated so they can only link to the full entry.
mark@629
  1446
#
mark@629
  1447
mark@629
  1448
# Print "expand" link.
mark@629
  1449
#
mark@629
  1450
function Page::lay_print_collapsed_entry_expand(Entry e) : void {
mark@629
  1451
    var string expand_url = $this->lay_build_url({".id" => string($e.itemid)}) + "#entry-$e.itemid";
mark@629
  1452
    print """<span class="expand"><a href="$expand_url" title="Expand this entry.">+</a></span>""";
mark@629
  1453
}
mark@629
  1454
mark@629
  1455
# Entry title.
mark@629
  1456
#
mark@629
  1457
function Page::lay_print_collapsed_entry_title(Entry e) : void {
mark@629
  1458
    var string subject = ($e.subject != "" ? $e.subject : $*text_nosubject);
mark@629
  1459
    print """<span class="title"><a href="$e.permalink_url" title="View this entry.">$subject</a></span>""";
mark@629
  1460
}
mark@629
  1461
mark@629
  1462
# Entry security unless public.
mark@629
  1463
#
mark@629
  1464
function Page::lay_print_collapsed_entry_security(Entry e) : void {
mark@629
  1465
    if ($e.security != "") {
mark@629
  1466
        print """ <span class="security">""" + $e.security_icon->as_string() + "</span>";
mark@629
  1467
    }
mark@629
  1468
}
mark@629
  1469
mark@629
  1470
# Entry comment count / "comments disabled" message.
mark@629
  1471
#
mark@629
  1472
function Page::lay_print_collapsed_entry_comments(Entry e) : void {
mark@629
  1473
    var string count = "";
mark@629
  1474
    var string max = "";
mark@629
  1475
    var string screened = "";
mark@629
  1476
    if ($e.comments.count > 0) {
mark@629
  1477
        if ($e.comments.maxcomments) {
mark@629
  1478
            # default: "!"
mark@629
  1479
            $max = $*collapsed_entry_comments_max_flag;
mark@629
  1480
        }
mark@629
  1481
        if ($e.comments.screened) {
mark@629
  1482
            # default "*"
mark@629
  1483
            $screened = $*collapsed_entry_comments_screened_flag;
mark@629
  1484
        }
mark@629
  1485
        # Assuming max and screened comments, default output is "(5000!*)"
mark@629
  1486
        # Just screened comments is "(343*)" etc.
mark@629
  1487
        $count = lay_string_placeholders( $*collapsed_entry_comments_count, [string($e.comments.count), $max, $screened] );
mark@629
  1488
    } elseif (not $e.comments.enabled) {
mark@629
  1489
        $count = $*collapsed_entry_comments_disabled;
mark@629
  1490
    }
mark@629
  1491
    print """ <span class="comments">$count</span>""";
mark@629
  1492
}
mark@629
  1493
# Entry poster.
mark@629
  1494
#
mark@629
  1495
function Page::lay_print_collapsed_entry_poster(Entry e) : void {
afuna@788
  1496
    if ( $.view == "read" or not $e.poster->equals($.journal as UserLite) ) {
mark@629
  1497
        print """ &mdash; <span class="poster">""" + $this->lay_get_poster($e) + "</span>";
mark@629
  1498
    }
mark@629
  1499
}
mark@629
  1500
mark@629
  1501
# Print the actual entry.
mark@629
  1502
#
mark@629
  1503
function Page::lay_print_collapsed_entry(Entry e) {
mark@629
  1504
mark@629
  1505
    println """<div class="collapsed-entry">""";
mark@629
  1506
mark@629
  1507
    $this->lay_print_collapsed_entry_expand($e);
mark@629
  1508
    $this->lay_print_collapsed_entry_title($e);
mark@629
  1509
    $this->lay_print_collapsed_entry_security($e);
mark@629
  1510
    $this->lay_print_collapsed_entry_comments($e);
mark@629
  1511
    $this->lay_print_collapsed_entry_poster($e);
mark@629
  1512
mark@629
  1513
    println """</div>""";
mark@629
  1514
}
mark@629
  1515
mark@629
  1516
mark@629
  1517
mark@629
  1518
###################################################
mark@629
  1519
#      #                                          #
mark@629
  1520
# ~7.  #  Page                                    #
mark@629
  1521
#      #                                          #
mark@629
  1522
#      # These methods do nothing, but are        #
mark@629
  1523
#      # overridden in child layers.              #
mark@629
  1524
#      #                                          #
mark@629
  1525
###################################################
mark@629
  1526
mark@629
  1527
# Show the full version of an entry, or the collapsed
mark@629
  1528
# version?
mark@629
  1529
function Page::lay_entry_is_expanded(Entry e) : bool {
mark@629
  1530
    return true;
mark@629
  1531
}
mark@629
  1532
mark@629
  1533
# Some pages have extra content to print in the footer.
mark@629
  1534
#
mark@629
  1535
function Page::lay_print_extra_box() {
mark@629
  1536
    return;
mark@629
  1537
}
mark@629
  1538
mark@629
  1539
# Lay back-and-foward navigation. Between pages of
mark@629
  1540
# entries on RecentPage, between months on MonthPage, etc.
mark@629
  1541
#
mark@629
  1542
function Page::lay_back_forward() : void {}
mark@629
  1543
mark@629
  1544
# Returns a combination of page title and view title;
mark@629
  1545
# only used in the `<title>` element of the HTML output.
mark@629
  1546
mark@629
  1547
function Page::title() : string {
mark@629
  1548
    var string title = $this.global_title;
mark@629
  1549
    var string view = $this->view_title();
mark@629
  1550
mark@629
  1551
    return lay_string_placeholders( $*text_html_title, [$title, $view] );
mark@629
  1552
}
mark@629
  1553
mark@629
  1554
mark@629
  1555
# Prints an error page.
mark@629
  1556
#
mark@629
  1557
function Page::lay_print_errorpage(string message) {
mark@629
  1558
    """
mark@629
  1559
    <div class="error">
mark@629
  1560
    <h2 class="error-header">$*text_errorpage_title</h2>
mark@629
  1561
    <p>$message</p>
mark@629
  1562
    </div>
mark@629
  1563
    """;
mark@629
  1564
}
mark@629
  1565
mark@629
  1566
# Print the current tab. Made separate so it can be overridden
mark@629
  1567
# in FriendsPage.
mark@629
  1568
#
mark@629
  1569
function Page::lay_print_navigation_current_tab() : void {
mark@629
  1570
    println """<li id="tab-current"><span>""" + lang_viewname($.view) + "</span></li>";
mark@629
  1571
}
mark@629
  1572
function Page::lay_navigation() {
mark@629
  1573
    var string nav;
mark@629
  1574
    var string alt;
mark@629
  1575
mark@629
  1576
    # Time to play "making up for S2's deficiencies"!
mark@629
  1577
    # No link is supplied to the TagsPage yet.
mark@629
  1578
    var string{} vu = $.view_url;
mark@629
  1579
    var string[] vo = $.views_order;
mark@629
  1580
mark@629
  1581
    if ( $vu{"tags"} == "" ) {
mark@629
  1582
        $vu{"tags"} = $.base_url + "/tag/";
mark@629
  1583
        $vo[size $vo] = "tags";
mark@629
  1584
    }
mark@629
  1585
mark@629
  1586
    """
mark@629
  1587
    <div id="navi">
mark@629
  1588
    <ul>
mark@629
  1589
    """;
mark@629
  1590
    foreach var string v ($vo) {
mark@629
  1591
        if ($.view == $v) {
mark@629
  1592
            $this->lay_print_navigation_current_tab();
mark@629
  1593
        } else {
mark@629
  1594
            println """<li><a href="$vu{$v}"><span>""" + lang_viewname($v) + "</span></a></li>";
mark@629
  1595
        }
mark@629
  1596
    }
mark@629
  1597
    """
mark@629
  1598
    </ul>
mark@629
  1599
    </div>
mark@629
  1600
    """;
mark@629
  1601
}
mark@629
  1602
mark@629
  1603
function Page::lay_print_extra_box_open(string title) : void {
mark@629
  1604
    var string alt = alternate("odd", "even");
mark@629
  1605
    """
mark@629
  1606
    <div class="extra-box $alt">
mark@629
  1607
    <h2 class="title">$title</h3>
mark@629
  1608
    """;
mark@629
  1609
}
mark@629
  1610
mark@629
  1611
function Page::lay_print_extra_box_close() : void {
mark@629
  1612
    print "</div>";
mark@629
  1613
}
mark@629
  1614
mark@629
  1615
# Prints a linklist. More complicated than it'd normally be because the
mark@629
  1616
# style splits a list with headings into multiple lists. Sub-lists are
mark@629
  1617
# not supported because they're not implemented in the core yet and show
mark@629
  1618
# no signs of ever being so.
mark@629
  1619
#
mark@629
  1620
function Page::print_linklist() {
mark@629
  1621
    if ( size $.linklist == 0 ) {
mark@629
  1622
        return;
mark@629
  1623
    }
mark@629
  1624
    var bool open = false;
mark@629
  1625
    var UserLink l = $.linklist[0];
mark@629
  1626
mark@629
  1627
    if (not $l.is_heading) {
mark@629
  1628
        $this->lay_print_extra_box_open( $*linklist_default_title );
mark@629
  1629
        """
mark@629
  1630
        <ul class="linklist">
mark@629
  1631
        """;
mark@629
  1632
        $open = true;
mark@629
  1633
    }
mark@629
  1634
mark@629
  1635
    foreach var UserLink l ($.linklist) {
mark@629
  1636
        if ($l.is_heading) {
mark@629
  1637
            if ($open) {
mark@629
  1638
                """
mark@629
  1639
                </ul>
mark@629
  1640
                """;
mark@629
  1641
                $this->lay_print_extra_box_close();
mark@629
  1642
                $open = false;
mark@629
  1643
            }
mark@629
  1644
            $this->lay_print_extra_box_open($l.title);
mark@629
  1645
            """
mark@629
  1646
            <ul class="linklist">
mark@629
  1647
            """;
mark@629
  1648
            $open = true;
mark@629
  1649
        } else {
mark@629
  1650
            """
mark@629
  1651
            <li><a href="$l.url">$l.title</a></li>
mark@629
  1652
            """;
mark@629
  1653
        }
mark@629
  1654
    }
mark@629
  1655
mark@629
  1656
    if ($open) {
mark@629
  1657
        """
mark@629
  1658
        </ul>
mark@629
  1659
        """;
mark@629
  1660
        $this->lay_print_extra_box_close();
mark@629
  1661
    }
mark@629
  1662
}
mark@629
  1663
mark@629
  1664
mark@629
  1665
mark@629
  1666
# Print one week in a calendar month.
mark@629
  1667
#
mark@629
  1668
function Page::lay_print_week(YearWeek w) : void {
mark@629
  1669
    """
mark@629
  1670
    <tr>
mark@629
  1671
    """;
mark@629
  1672
    if ($w.pre_empty > 0) {
mark@629
  1673
        foreach var int i (1..$w.pre_empty) {
mark@629
  1674
            """
mark@629
  1675
            <td class="blank cell">&nbsp;</td>
mark@629
  1676
            """;
mark@629
  1677
        }
mark@629
  1678
    }
mark@629
  1679
    foreach var YearDay d ($w.days) {
mark@629
  1680
        if ($d.num_entries > 0) {
mark@629
  1681
            """
mark@629
  1682
            <td class="full cell">
mark@629
  1683
                <span class="day">$d.day</span>
mark@629
  1684
                <div class="count"><a href="$d.url">$d.num_entries</a></div>
mark@629
  1685
            </td>
mark@629
  1686
            """;
mark@629
  1687
        } else {
mark@629
  1688
            """
mark@629
  1689
            <td class="empty cell">
mark@629
  1690
                <span class="day">$d.day</span>
mark@629
  1691
                <div class="count">&nbsp;</div>
mark@629
  1692
            </td>
mark@629
  1693
            """;
mark@629
  1694
        }
mark@629
  1695
    }
mark@629
  1696
    if ($w.post_empty > 0) {
mark@629
  1697
        foreach var int i (1..$w.post_empty) {
mark@629
  1698
            """
mark@629
  1699
            <td class="blank-cell">&nbsp;</td>
mark@629
  1700
            """;
mark@629
  1701
        }
mark@629
  1702
    }
mark@629
  1703
    """
mark@629
  1704
    </tr>
mark@629
  1705
    """;
mark@629
  1706
}
mark@629
  1707
mark@629
  1708
# Print a calendar month.
mark@629
  1709
#
mark@629
  1710
function Page::lay_print_month(YearMonth m) {
mark@629
  1711
    """
fu@3114
  1712
    <table summary="Monthly calendar with links to each day's entries" class="month">
mark@629
  1713
    <tr>
mark@629
  1714
    """;
mark@629
  1715
    foreach var int d (weekdays()) {
mark@629
  1716
        """<th class="weekday">$*lang_dayname_short[$d]</th>""";
mark@629
  1717
    }
mark@629
  1718
    """
mark@629
  1719
    </tr>
mark@629
  1720
    """;
mark@629
  1721
    foreach var YearWeek w ($m.weeks) {
mark@629
  1722
        $this->lay_print_week($w);
mark@629
  1723
    }
mark@629
  1724
    """
mark@629
  1725
    </table>
mark@629
  1726
    """;
mark@629
  1727
}
mark@629
  1728
mark@629
  1729
mark@629
  1730
mark@629
  1731
function Page::lay_header() {
mark@629
  1732
    """
mark@629
  1733
    <div id="header">
mark@629
  1734
    """;
mark@629
  1735
mark@629
  1736
    var string subtitle;
mark@629
  1737
    if ($.global_subtitle != "") {
mark@629
  1738
        $subtitle = $this.global_subtitle + ". " + $this->view_title() + ".";
mark@629
  1739
    } else {
mark@629
  1740
        $subtitle = $this->view_title() + ".";
mark@629
  1741
    }
mark@629
  1742
    """
mark@629
  1743
    <h1>$.global_title</h1>
mark@629
  1744
    <p>$subtitle</p>
mark@629
  1745
    </div>
mark@629
  1746
    """;
mark@629
  1747
}
mark@629
  1748
mark@629
  1749
mark@629
  1750
function Page::lay_print_mini_calendar_box() {
mark@629
  1751
    var YearMonth m = $this->get_latest_month();
mark@629
  1752
    if ( defined $m and $m.has_entries ) {
mark@629
  1753
        $this->lay_print_extra_box_open( $m->month_format("%%month%%") );
mark@629
  1754
        $this->lay_print_month($m);
mark@629
  1755
        $this->lay_print_extra_box_close();
mark@629
  1756
    }
mark@629
  1757
}
mark@629
  1758
mark@629
  1759
function Page::lay_footer() {
mark@629
  1760
mark@629
  1761
    """
mark@629
  1762
    <div id="extra">
mark@629
  1763
        """;
mark@629
  1764
        $this->lay_print_extra_box();
mark@629
  1765
        $this->print_linklist();
mark@629
  1766
        $this->lay_print_mini_calendar_box();
mark@629
  1767
        lay_print_extra_boxes();
mark@629
  1768
        """
mark@629
  1769
    </div>
mark@629
  1770
mark@629
  1771
    <div id="footer">
janinedog@849
  1772
        <p><span class="top-link"><a href="#header">$*top_link_text</a></span> <a href="http://www.dreamwidth.org/customize/advanced/layerbrowse.bml?id=zesty/layout">Zesty</a>. """; server_sig(); """</p>
mark@629
  1773
    </div>
mark@629
  1774
    """;
mark@629
  1775
}
mark@629
  1776
mark@629
  1777
mark@629
  1778
function Page::print() {
mark@629
  1779
mark@629
  1780
"""
mark@629
  1781
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
mark@629
  1782
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-loose.dtd">
mark@629
  1783
       <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
mark@629
  1784
<head>
mark@629
  1785
<title>"""+$this->title()+"""</title>
mark@629
  1786
""";
mark@629
  1787
    $this->print_head();
mark@629
  1788
"""
mark@629
  1789
<link rel="stylesheet" type="text/css" href="$.stylesheet_url" />
mark@629
  1790
""";
mark@629
  1791
    if ($*custom_favicon != "") {
mark@629
  1792
        """<link rel="shortcut icon" href="$*custom_favicon" />""";
mark@629
  1793
    }
mark@629
  1794
"""
mark@629
  1795
</head>
mark@629
  1796
<body class="$.journal.username-$.view">
mark@629
  1797
    """;
afuna@745
  1798
    $this->print_control_strip();
mark@629
  1799
    $this->lay_header();
mark@629
  1800
    $this->lay_navigation();
mark@629
  1801
mark@629
  1802
    $this->print_body();
mark@629
  1803
mark@629
  1804
    $this->lay_footer();
mark@629
  1805
    """
mark@629
  1806
</body>
mark@629
  1807
</html>
mark@629
  1808
""";
mark@629
  1809
}
mark@629
  1810
mark@629
  1811
mark@629
  1812
###################################################
mark@629
  1813
#      #                                          #
mark@629
  1814
# ~8.  # RecentPage                               #
mark@629
  1815
#      #                                          #
mark@629
  1816
###################################################
mark@629
  1817
mark@629
  1818
mark@629
  1819
function RecentPage::lay_build_url(string{} items) : string {
mark@629
  1820
    if ($.nav.skip != 0) {
mark@629
  1821
        $items{"skip"} = string($.nav.skip);
mark@629
  1822
    }
mark@629
  1823
    return $.base_url + lay_array_to_args($items);
mark@629
  1824
}
mark@629
  1825
mark@629
  1826
function RecentPage::lay_back_forward() : void {
mark@629
  1827
mark@629
  1828
    if ($.nav.backward_url == "" and $.nav.forward_url == "") {
mark@629
  1829
        return;
mark@629
  1830
    }
mark@629
  1831
    """
mark@629
  1832
    <div class="back-forward">
mark@629
  1833
    """;
mark@629
  1834
    if ($.nav.backward_url != "") {
mark@629
  1835
        var string previous = get_plural_phrase($.nav.backward_count, "text_skiplinks_back");
mark@629
  1836
        """
mark@629
  1837
        <div class="back">
mark@629
  1838
            <a href="$.nav.backward_url" title="$previous">&larr;</a>
mark@629
  1839
        </div>
mark@629
  1840
        """;
mark@629
  1841
    }
mark@629
  1842
    if ($.nav.forward_url != "") {
mark@629
  1843
        var string next = get_plural_phrase($.nav.forward_count, "text_skiplinks_forward");
mark@629
  1844
        """
mark@629
  1845
        <div class="forward">
mark@629
  1846
            <a href="$.nav.forward_url" title="$next">&rarr;</a>
mark@629
  1847
        </div>
mark@629
  1848
        """;
mark@629
  1849
    }
mark@629
  1850
    """
mark@629
  1851
    </div>
mark@629
  1852
    """;
mark@629
  1853
}
mark@629
  1854
mark@629
  1855
mark@629
  1856
function RecentPage::print_body() {
mark@629
  1857
    $this->lay_back_forward();
mark@629
  1858
    """
mark@629
  1859
    <div id="entries">
mark@629
  1860
    """;
mark@629
  1861
    if (size $.entries == 0) {
mark@629
  1862
        $this->lay_print_errorpage($*text_noentries_recent);
mark@629
  1863
    } else {
mark@629
  1864
        foreach var Entry e ($.entries) {
mark@629
  1865
            $this->print_entry($e);
mark@629
  1866
        }
mark@629
  1867
    }
mark@629
  1868
    """
mark@629
  1869
    </div>
mark@629
  1870
    """;
mark@629
  1871
    $this->lay_back_forward();
mark@629
  1872
}
mark@629
  1873
mark@629
  1874
mark@629
  1875
###################################################
mark@629
  1876
#      #                                          #
mark@629
  1877
# ~9.  #  FriendsPage                             #
mark@629
  1878
#      #                                          #
mark@629
  1879
###################################################
mark@629
  1880
mark@629
  1881
mark@629
  1882
function FriendsPage::lay_build_url(string{} items) : string {
mark@629
  1883
    var string url = $.base_url;
mark@629
  1884
mark@629
  1885
    # Page might be "friendsfriends".
mark@629
  1886
    #
mark@629
  1887
    if ($.friends_mode != "") {
mark@629
  1888
        $url = $url + "/$.friends_mode";
mark@629
  1889
    } else {
mark@645
  1890
        $url = $url + "/read";
mark@629
  1891
    }
mark@629
  1892
mark@629
  1893
    # Page might be a friends group.
mark@629
  1894
    #
mark@629
  1895
    if ($.filter_active) {
mark@629
  1896
        $url = $url + "/$.filter_name";
mark@629
  1897
    }
mark@629
  1898
mark@629
  1899
    if ($.nav.skip != 0) {
mark@629
  1900
        $items{"skip"} = string($.nav.skip);
mark@629
  1901
    }
mark@629
  1902
    return $url + lay_array_to_args($items);
mark@629
  1903
}
mark@629
  1904
mark@629
  1905
# Is the default view mode for entries "expanded" or "collapsed"?
mark@629
  1906
# Currently only actually used on the FriendsPage.
mark@629
  1907
#
mark@629
  1908
function FriendsPage::lay_get_current_view_mode() : string {
mark@629
  1909
    var string mode = $*default_view_mode;
mark@629
  1910
    if ($.args{"mode"} != "" and $mode != $.args{"mode"}) {
mark@629
  1911
        $mode = $.args{"mode"};
mark@629
  1912
    }
mark@629
  1913
    return $mode;
mark@629
  1914
}
mark@629
  1915
mark@629
  1916
# Returns the opposite of the current view mode for entries.
mark@629
  1917
#
mark@629
  1918
function FriendsPage::lay_get_alternate_view_mode() : string {
mark@629
  1919
    var string current = $this->lay_get_current_view_mode();
mark@629
  1920
    if ( $current == "expanded" ) {
mark@629
  1921
        return "collapsed";
mark@629
  1922
    } else {
mark@629
  1923
        return "expanded";
mark@629
  1924
    }
mark@629
  1925
}
mark@629
  1926
mark@629
  1927
function FriendsPage::lay_entry_is_expanded(Entry e) : bool {
mark@629
  1928
    var bool expanded = false;
mark@629
  1929
mark@629
  1930
    # We expand entries if they match the `.id=$entry_id` argument, but
mark@629
  1931
    # there's a problem in that the item id isn't necessarily unique.
mark@629
  1932
    # Because LJ uses (internally) a composite key of user id and item id,
mark@629
  1933
    # two different users' posts on the same page could have the same item id.
mark@629
  1934
    #
mark@629
  1935
    # I mention it mostly out of interest, since I'm not going to do anything
mark@629
  1936
    # to stop it happening.
mark@629
  1937
    #
mark@629
  1938
    # It's vanishingly unlikely, S2 doesn't expose the user ID (and the
mark@629
  1939
    # username isn't necessarily unique *or* safe), and even if there's a
mark@629
  1940
    # clash, what's the damage? But it might still happen at some point.
mark@629
  1941
    #
mark@629
  1942
    # It's not quite as simple as the birthday paradox, because low item ids
mark@629
  1943
    # are exponentially more likely to appear than high ones, and people who
mark@629
  1944
    # joined the site at the same time and have similar posting habits are
mark@629
  1945
    # quite likely to stay in the same range of item ids.
mark@629
  1946
    #
mark@629
  1947
    # This comment was much too long. Sorry!
mark@629
  1948
    #
mark@629
  1949
    if ($.args{"id"} != "" and int($.args{"id"}) == $e.itemid) {
mark@629
  1950
        $expanded = true;
mark@629
  1951
    } elseif ($this->lay_get_current_view_mode() == "expanded") {
mark@629
  1952
        $expanded = true;
mark@629
  1953
    }
mark@629
  1954
    return $expanded;
mark@629
  1955
}
mark@629
  1956
mark@629
  1957
mark@629
  1958
mark@629
  1959
mark@629
  1960
mark@629
  1961
# The FriendsPage tab has an extra mode-switching button on it.
mark@629
  1962
#
mark@629
  1963
function FriendsPage::lay_print_navigation_current_tab() : void {
mark@629
  1964
    var string alt = $this->lay_build_url( {".mode" => $this->lay_get_alternate_view_mode()} );
mark@629
  1965
    println """<li id="tab-current"><span>""" + lang_viewname($.view) + """ <a href="$alt">+</a></span></li>""";
mark@629
  1966
}
mark@629
  1967
mark@629
  1968
function FriendsPage::print_entry(Entry e) {
mark@629
  1969
    if ($e.new_day) {
mark@629
  1970
        print """<div class="new-day">""" + $e.time->date_format($*lang_fmt_date_long) + "</div>";
mark@629
  1971
    }
mark@629
  1972
    if ( $this->lay_entry_is_expanded($e) ) {
mark@629
  1973
        $this->lay_print_entry($e);
mark@629
  1974
    } else {
mark@629
  1975
        $this->lay_print_collapsed_entry($e);
mark@629
  1976
    }
mark@629
  1977
mark@629
  1978
}
mark@629
  1979
mark@629
  1980
mark@629
  1981
###################################################
mark@629
  1982
#      #                                          #
mark@629
  1983
# ~10. #  DayPage                                 #
mark@629
  1984
#      #                                          #
mark@629
  1985
###################################################
mark@629
  1986
mark@629
  1987
function DayPage::lay_back_forward() : void {
mark@629
  1988
mark@629
  1989
    if ($.prev_url == "" and $.next_url == "") {
mark@629
  1990
        return;
mark@629
  1991
    }
mark@629
  1992
    """
mark@629
  1993
    <div class="back-forward">
mark@629
  1994
    """;
mark@629
  1995
    if ($.prev_url != "") {
mark@629
  1996
        """
mark@629
  1997
        <div class="back">
mark@629
  1998
            <a href="$.prev_url" title="$*text_day_prev">&larr;</a>
mark@629
  1999
        </div>
mark@629
  2000
        """;
mark@629
  2001
    }
mark@629
  2002
    if ($.next_url != "") {
mark@629
  2003
        """
mark@629
  2004
        <div class="forward">
mark@629
  2005
            <a href="$.next_url" title="$*text_day_next">&rarr;</a>
mark@629
  2006
        </div>
mark@629
  2007
        """;
mark@629
  2008
    }
mark@629
  2009
    """
mark@629
  2010
    </div>
mark@629
  2011
    """;
mark@629
  2012
}
mark@629
  2013
mark@629
  2014
mark@629
  2015
function DayPage::print_body() {
mark@629
  2016
mark@629
  2017
    if (not $.has_entries) {
mark@629
  2018
        $this->lay_print_errorpage($*text_noentries_day);
mark@629
  2019
    } else {
mark@629
  2020
        foreach var Entry e ($.entries) {
mark@629
  2021
            $this->print_entry($e);
mark@629
  2022
        }
mark@629
  2023
    }
mark@629
  2024
mark@629
  2025
}
mark@629
  2026
mark@629
  2027
mark@629
  2028
###################################################
mark@629
  2029
#      #                                          #
mark@629
  2030
# ~11. #  MonthPage                               #
mark@629
  2031
#      #                                          #
mark@629
  2032
###################################################
mark@629
  2033
mark@629
  2034
# Can't expand MonthPage entries. Bah humbug.
mark@629
  2035
#
mark@629
  2036
function MonthPage::lay_print_collapsed_expand(Entry e) : void {
mark@629
  2037
    return;
mark@629
  2038
}
mark@629
  2039
mark@629
  2040
function MonthPage::lay_back_forward() : void {
mark@629
  2041
mark@629
  2042
    if ($.prev_url == "" and $.next_url == "") {
mark@629
  2043
        return;
mark@629
  2044
    }
mark@629
  2045
    """
mark@629
  2046
    <div class="back-forward">
mark@629
  2047
    """;
mark@629
  2048
    if ($.prev_url != "") {
mark@629
  2049
        """
mark@629
  2050
        <div class="back">
mark@629
  2051
            <a href="$.prev_url" title="Previous day.">&larr;</a>
mark@629
  2052
        </div>
mark@629
  2053
        """;
mark@629
  2054
    }
mark@629
  2055
    if ($.next_url != "") {
mark@629
  2056
        """
mark@629
  2057
        <div class="forward">
mark@629
  2058
            <a href="$.next_url" title="Next day.">&rarr;</a>
mark@629
  2059
        </div>
mark@629
  2060
        """;
mark@629
  2061
    }
mark@629
  2062
    """
mark@629
  2063
    </div>
mark@629
  2064
    """;
mark@629
  2065
}
mark@629
  2066
mark@629
  2067
# Can't get entry text in this view, so no full entries possible.
mark@629
  2068
#
mark@629
  2069
function MonthPage::print_entry(Entry e) : void {
mark@629
  2070
    return $this->lay_print_collapsed_entry($e);
mark@629
  2071
}
mark@629
  2072
mark@629
  2073
mark@629
  2074
mark@629
  2075
# Print a box containing information about other linkable months.
mark@629
  2076
#
mark@629
  2077
function MonthPage::lay_print_extra_box() : void {
mark@629
  2078
    if (size $.months == 0) {
mark@629
  2079
        return;
mark@629
  2080
    }
mark@629
  2081
mark@629
  2082
    """
mark@629
  2083
    <div class="extra-box">
mark@629
  2084
        <h3 class="title">$.date.year</h3>
mark@629
  2085
        <ul>
mark@629
  2086
    """;
mark@629
  2087
mark@629
  2088
    foreach var MonthEntryInfo m ($.months) {
mark@629
  2089
        if ($.date.year == $m.date.year) {
mark@629
  2090
            println """<li><a href="$m.url">"""+$m.date->date_format("%%month%%")+"</a></li>";
mark@629
  2091
        }
mark@629
  2092
    }
mark@629
  2093
mark@629
  2094
    """
mark@629
  2095
        </ul>
mark@629
  2096
    </div>
mark@629
  2097
    """;
mark@629
  2098
}
mark@629
  2099
mark@629
  2100
mark@629
  2101
mark@629
  2102
function MonthPage::print_body {
mark@629
  2103
    var bool any = false;
mark@629
  2104
    $this->lay_back_forward();
mark@629
  2105
    """
mark@629
  2106
    <div id="entries">
mark@629
  2107
    """;
mark@629
  2108
    foreach var MonthDay d ($.days) {
mark@629
  2109
        if ($d.has_entries) {
mark@629
  2110
            print """<div class="new-day">""" + $d.date->date_format($*lang_fmt_date_long) + "</div>";
mark@629
  2111
            foreach var Entry e ($d.entries) {
mark@629
  2112
                $this->print_entry($e);
mark@629
  2113
            }
mark@629
  2114
            $any = true;
mark@629
  2115
        }
mark@629
  2116
    }
mark@629
  2117
    """
mark@629
  2118
    </div>
mark@629
  2119
    """;
mark@629
  2120
    if ( not $any ) {
mark@629
  2121
        # default: "No entries were posted on the selected month."
mark@629
  2122
        return $this->lay_print_errorpage( $*error_monthpage_no_entries );
mark@629
  2123
    }
mark@629
  2124
    $this->lay_back_forward();
mark@629
  2125
}
mark@629
  2126
mark@629
  2127
mark@629
  2128
mark@629
  2129
###################################################
mark@629
  2130
#      #                                          #
mark@629
  2131
# ~12. # EntryPage                                #
mark@629
  2132
#      #                                          #
mark@629
  2133
###################################################
mark@629
  2134
mark@629
  2135
# TODO: this is broken in the core.
mark@629
  2136
# Waiting on http://rt.livejournal.org/Ticket/Display.html?id=1266 .
mark@629
  2137
#
mark@629
  2138
function EntryPage::lay_comment_poster_is_suspended(Comment c) : bool {
mark@629
  2139
    return $.viewing_thread and not $c.full and $c.depth == 1;
mark@629
  2140
}
mark@629
  2141
mark@629
  2142
function EntryPage::lay_print_comment_details(CommentInfo c) : void {
mark@629
  2143
    print $c->lay_get_details($.comment_pages.total, false);
mark@629
  2144
}
mark@629
  2145
mark@629
  2146
# "Ideally layouts should never override this"... well how about you
mark@629
  2147
# actually make it work on all views, then?
mark@629
  2148
function EntryPage::view_title() : string {
mark@629
  2149
    var string subject = ($.entry.subject != "" ? $.entry.subject : $*text_nosubject);
mark@629
  2150
    if ( $.viewing_thread ) {
mark@629
  2151
        $subject = lay_string_placeholders( "%1 : comments", [$subject] );
mark@629
  2152
    }
mark@629
  2153
    return $subject;
mark@629
  2154
}
mark@629
  2155
mark@629
  2156
function EntryPage::lay_back_forward() : void {
mark@629
  2157
    var Link prev = $.entry->get_link("nav_prev");
mark@629
  2158
    var Link next = $.entry->get_link("nav_next");
mark@629
  2159
mark@629
  2160
    if ( isnull $prev and isnull $next ) {
mark@629
  2161
        return;
mark@629
  2162
    }
mark@629
  2163
    """
mark@629
  2164
    <div class="back-forward">
mark@629
  2165
    """;
mark@629
  2166
    if ( defined $prev ) {
mark@629
  2167
        """
mark@629
  2168
        <div class="back">
mark@629
  2169
            <a href="$prev.url" title="$prev.caption">&larr;</a>
mark@629
  2170
        </div>
mark@629
  2171
        """;
mark@629
  2172
    }
mark@629
  2173
    if ( defined $next ) {
mark@629
  2174
        """
mark@629
  2175
        <div class="forward">
mark@629
  2176
            <a href="$next.url" title="$next.caption">&rarr;</a>
mark@629
  2177
        </div>
mark@629
  2178
        """;
mark@629
  2179
    }
mark@629
  2180
    """
mark@629
  2181
    </div>
mark@629
  2182
    """;
mark@629
  2183
mark@629
  2184
}
mark@629
  2185
mark@629
  2186
mark@629
  2187
function EntryPage::lay_print_comment_linkbar(Comment c)
mark@629
  2188
"Same as Page::lay_print_entry_linkbar except that it also prints
mark@629
  2189
the multiform checkbox if the multiform is on. "
mark@629
  2190
{
mark@629
  2191
    var string bar = $c->lay_get_linkbar();
mark@629
  2192
mark@629
  2193
    if ( $bar == "" and not $.multiform_on ) {
mark@629
  2194
        return;
mark@629
  2195
    }
mark@629
  2196
mark@629
  2197
    print """<div class="tools" id="tools$c.talkid">$bar""";
mark@629
  2198
mark@629
  2199
    if ($.multiform_on) {
mark@629
  2200
        $c->print_multiform_check();
mark@629
  2201
    }
mark@629
  2202
mark@629
  2203
    print "</div>";
mark@629
  2204
mark@629
  2205
}
mark@629
  2206
mark@629
  2207
function EntryPage::lay_print_comment_links(Comment c) : void {
mark@629
  2208
mark@629
  2209
    println """<div class="links">""";
mark@629
  2210
mark@629
  2211
    if ( $.viewing_thread and $c.depth == 1 ) {
mark@629
  2212
        """[<a href="$.entry.permalink_url">$*text_comment_parent_entry</a>] """;
mark@629
  2213
    }
mark@629
  2214
mark@629
  2215
    """[<a href="$c.permalink_url">$*text_comment_permalink</a>] """;
mark@629
  2216
mark@629
  2217
    if ( $c.parent_url != "" ) {
mark@629
  2218
        """[<a href="$c.parent_url">$*text_comment_parent</a>] """;
mark@629
  2219
    }
mark@629
  2220
mark@629
  2221
    if ( $c.frozen ) {
mark@629
  2222
        """[$*text_comment_frozen]""";
mark@629
  2223
    } elseif ( $this->lay_comment_poster_is_suspended($c) ) {
mark@629
  2224
        """[$*text_comment_poster_is_suspended]""";
mark@629
  2225
    } else {
mark@629
  2226
        """["""; $c->print_reply_link({"linktext" => $*text_comment_reply}); """]""";
mark@629
  2227
    }
mark@629
  2228
mark@629
  2229
    println """</div>""";
mark@629
  2230
mark@629
  2231
}
mark@629
  2232
mark@629
  2233
function EntryPage::print_comment(Comment c) : void {
mark@629
  2234
mark@629
  2235
    var string class = "comment " + alternate("odd", "even");
mark@629
  2236
    var string subject = ($c.subject == "") ? $*text_nosubject : $c.subject;
mark@629
  2237
mark@629
  2238
    var string state = "state";
mark@629
  2239
    if ($c.frozen) {
mark@629
  2240
        $state = "frozen";
mark@629
  2241
    } elseif ($c.screened) {
mark@629
  2242
        $state = "screened";
mark@629
  2243
    }
mark@629
  2244
mark@629
  2245
    println """<div class="nest">""";
mark@629
  2246
mark@629
  2247
    # This "state" div is a dodgy hack for the JavaScript set_handler stuff.
mark@629
  2248
    # It'll be changed to "frozen", "screened" etc. if the quick-change buttons
mark@629
  2249
    # are used.
mark@629
  2250
    # No apologies. :P
mark@629
  2251
    """
mark@629
  2252
    <div class="$state" id="state$c.talkid">
mark@629
  2253
        <div class="$class" id="$c.dom_id">
mark@629
  2254
            <div class="left">
mark@629
  2255
            """;
mark@629
  2256
            if ($c.userpic) {
mark@629
  2257
                """<div class="userpic">""";
mark@629
  2258
                print $c.userpic->as_string();
mark@629
  2259
                """</div>""";
mark@629
  2260
            } else {
mark@629
  2261
                """<div class="userpic empty">&nbsp;</div>""";
mark@629
  2262
            }
mark@629
  2263
            $this->lay_print_comment_linkbar($c);
mark@629
  2264
mark@629
  2265
            """
mark@629
  2266
            </div>
mark@629
  2267
            <div class="right">
mark@629
  2268
                <div class="header">
mark@629
  2269
                    <div class="title">
mark@629
  2270
                        <h3 id="t$c.talkid"><a href="$c.permalink_url">$subject</a></h2>
mark@629
  2271
                        """;
mark@629
  2272
                        if (defined $c.subject_icon) {
mark@629
  2273
                            print """<span class="icon">""" + $c.subject_icon->as_string() + "</span>";
mark@629
  2274
                        }
mark@629
  2275
                        """
mark@629
  2276
                    </div>
mark@629
  2277
                    <div class="posted">"""; $this->lay_print_posted_by($c); """</div>
mark@629
  2278
                </div>
mark@629
  2279
                """;
mark@629
  2280
                $this->lay_print_text($c);
mark@629
  2281
                $this->lay_print_comment_links($c);
mark@629
  2282
                """
mark@629
  2283
mark@629
  2284
            </div>
mark@629
  2285
        </div>
mark@629
  2286
    </div>
mark@629
  2287
    """;
mark@629
  2288
    $c->print_reply_container({"class" => "quickreply"});
mark@629
  2289
    """
mark@629
  2290
    <div id="c-reply-$c.talkid"></div>
mark@629
  2291
    """;
mark@629
  2292
mark@629
  2293
    $this->print_comments($c.replies);
mark@629
  2294
mark@629
  2295
    """</div>""";
mark@629
  2296
}
mark@629
  2297
mark@629
  2298
function EntryPage::print_comment_partial(Comment c) {
mark@629
  2299
mark@629
  2300
    var string poster = defined $c.poster ? $c.poster->as_string() : $*text_poster_anonymous;
mark@629
  2301
    var string subject = $c.subject != "" ? $c.subject : $*text_nosubject;
mark@629
  2302
mark@629
  2303
    """
mark@629
  2304
    <div class="nest">
mark@629
  2305
    <div class="collapsed-comment">
mark@629
  2306
    """;
mark@629
  2307
    if ( $c.deleted ) {
mark@629
  2308
        """<span class="title">(deleted comment)</span>""";
mark@629
  2309
    } elseif ( $c.screened ) {
mark@629
  2310
        """
mark@629
  2311
        <a class="title" href="$c.permalink_url">$subject</a> &mdash; <span class="poster">$poster</span> [screened]
mark@629
  2312
        """;
mark@629
  2313
    } else {
mark@629
  2314
        """
mark@629
  2315
        <a class="title" href="$c.permalink_url">$subject</a> &mdash; <span class="poster">$poster</span>
mark@629
  2316
        """;
mark@629
  2317
    }
mark@629
  2318
mark@629
  2319
mark@629
  2320
mark@629
  2321
    $this->print_comments($c.replies);
mark@629
  2322
    """
mark@629
  2323
    </div>
mark@629
  2324
    </div>
mark@629
  2325
    """;
mark@629
  2326
}
mark@629
  2327
mark@629
  2328
mark@629
  2329
function EntryPage::print_comments(Comment[] comments) {
mark@629
  2330
    if (size $comments == 0) {
mark@629
  2331
        return;
mark@629
  2332
    }
mark@629
  2333
mark@629
  2334
    foreach var Comment c ($comments) {
mark@629
  2335
        if ($c.full) {
mark@629
  2336
            $this->print_comment($c);
mark@629
  2337
        }
mark@629
  2338
        # special case for suspended comments.
mark@629
  2339
        elseif ( $this->lay_comment_poster_is_suspended($c) ) {
mark@629
  2340
            $this->print_comment($c);
mark@629
  2341
        } else {
mark@629
  2342
            $this->print_comment_partial($c);
mark@629
  2343
        }
mark@629
  2344
    }
mark@629
  2345
}
mark@629
  2346
mark@629
  2347
mark@629
  2348
mark@629
  2349
function EntryPage::lay_print_entry_left(Entry e) : void {
mark@629
  2350
    """
mark@629
  2351
    <div class="userpic">
mark@629
  2352
    """;
mark@629
  2353
    if ($e.userpic) {
mark@629
  2354
        print $e.userpic->as_string();
mark@629
  2355
    }
mark@629
  2356
    """
mark@629
  2357
    </div>
mark@629
  2358
    """;
mark@629
  2359
    $this->lay_print_entry_linkbar($.entry);
mark@629
  2360
}
mark@629
  2361
function EntryPage::lay_print_entry_footer(Entry e) {
mark@629
  2362
    return;
mark@629
  2363
}
mark@629
  2364
mark@629
  2365
function EntryPage::print_entry(Entry e) {
mark@629
  2366
    $this->lay_print_entry($e);
mark@629
  2367
}
mark@629
  2368
mark@629
  2369
function EntryPage::lay_comment_pagination() : void {
mark@629
  2370
mark@629
  2371
    # no comments
mark@629
  2372
    if ($.entry.comments.count == 0) {
mark@629
  2373
        return;
mark@629
  2374
    }
mark@629
  2375
mark@629
  2376
    var ItemRange range = $.comment_pages;
mark@629
  2377
mark@629
  2378
    # only one page of comments
mark@629
  2379
    if ($range.all_subitems_displayed) {
mark@629
  2380
        return;
mark@629
  2381
    }
mark@629
  2382
mark@629
  2383
    """
mark@629
  2384
    <div class="comment-pagination">
mark@629
  2385
    """;
mark@629
  2386
mark@629
  2387
    if ( $range.url_last != "" ) {
mark@629
  2388
        """<a href="$range.url_last">&larr;</a>""";
mark@629
  2389
    }
mark@629
  2390
    foreach var int page (1 .. $range.total) {
mark@629
  2391
        if ($range.current != $page) {
mark@629
  2392
            """ <a href='""" + $range->url_of($page) + """'>$page</a> """;
mark@629
  2393
        } else {
mark@629
  2394
            """ $page """;
mark@629
  2395
        }
mark@629
  2396
    }
mark@629
  2397
    if ( $range.url_next != "" ) {
mark@629
  2398
        """<a href="$range.url_next">&rarr;</a>""";
mark@629
  2399
    }
mark@629
  2400
mark@629
  2401
    """
mark@629
  2402
    </div>
mark@629
  2403
    """;
mark@629
  2404
}
mark@629
  2405
mark@629
  2406
function EntryPage::lay_print_comments() : void {
mark@629
  2407
mark@629
  2408
    if ( $.entry.comments.enabled and size $.comments > 0 ) {
mark@629
  2409
mark@629
  2410
        # JavaScript voodoo.
mark@629
  2411
        #
mark@629
  2412
        #
mark@629
  2413
        set_handler("screen_comment_#", [
mark@629
  2414
            [ "set_class", "state#", "screened" ]
mark@629
  2415
        ]);
mark@629
  2416
        set_handler("freeze_comment_#", [
mark@629
  2417
            [ "set_class", "state#", "frozen" ]
mark@629
  2418
        ]);
mark@629
  2419
        set_handler("unscreen_comment_#", [
mark@629
  2420
            [ "set_class", "state#", "state" ]
mark@629
  2421
        ]);
mark@629
  2422
        set_handler("unfreeze_comment_#", [
mark@629
  2423
            [ "set_class", "state#", "state" ]
mark@629
  2424
        ]);
mark@629
  2425
mark@629
  2426
        """
mark@629
  2427
        <div id="comments">
mark@629
  2428
        """;
mark@629
  2429
mark@629
  2430
        if ($.multiform_on) {
mark@629
  2431
            $this->print_multiform_start();
mark@629
  2432
        }
mark@629
  2433
mark@629
  2434
        $this->print_comments($.comments);
mark@629
  2435
mark@629
  2436
        if ($.multiform_on) {
mark@629
  2437
            """
mark@629
  2438
            <div id="multiform">
mark@629
  2439
            """;
mark@629
  2440
            $this->print_multiform_actionline();
mark@629
  2441
            $this->print_multiform_end();
mark@629
  2442
            """
mark@629
  2443
            </div>
mark@629
  2444
            """;
mark@629
  2445
        }
mark@629
  2446
mark@629
  2447
        """
mark@629
  2448
        </div>
mark@629
  2449
        """;
mark@629
  2450
    }
mark@629
  2451
mark@629
  2452
}
mark@629
  2453
mark@629
  2454
function EntryPage::lay_print_entry_comments_bar() : void {
mark@629
  2455
    """
mark@629
  2456
    <div class="entry-comments-bar">
mark@629
  2457
        <span class="comments-title">""";
mark@629
  2458
        $this->lay_print_comment_details( $.entry.comments );
mark@629
  2459
        $this->lay_print_entry_reply_link( $.entry.comments );
mark@629
  2460
        """</span>
mark@629
  2461
    """; $this->lay_comment_pagination(); """
mark@629
  2462
    </div>
mark@629
  2463
    """;
mark@629
  2464
}
mark@629
  2465
mark@629
  2466
function EntryPage::print_body() : void {
mark@629
  2467
mark@629
  2468
    if ( $.viewing_thread ) {
mark@629
  2469
        return $this->lay_print_comments();
mark@629
  2470
    }
mark@629
  2471
mark@629
  2472
    $this->lay_back_forward();
mark@629
  2473
    """
mark@629
  2474
    <div id="entries">
mark@629
  2475
        """;
mark@629
  2476
        $this->print_entry($.entry);
mark@629
  2477
        """
mark@629
  2478
    </div>
mark@629
  2479
    """;
mark@629
  2480
    $this->lay_back_forward();
mark@629
  2481
mark@629
  2482
    $this->lay_print_entry_comments_bar();
mark@629
  2483
mark@629
  2484
    $this->lay_print_comments();
mark@629
  2485
mark@629
  2486
    # Show comment pagination again if necessary.
mark@629
  2487
    if ( $.comment_pages.total > 1 ) {
mark@629
  2488
        $this->lay_print_entry_comments_bar();
mark@629
  2489
    }
mark@629
  2490
}
mark@629
  2491
mark@629
  2492
mark@629
  2493
mark@629
  2494
mark@629
  2495
mark@629
  2496
mark@629
  2497
###################################################
mark@629
  2498
#      #                                          #
mark@629
  2499
# ~13. # ReplyPage                                #
mark@629
  2500
#      #                                          #
mark@629
  2501
###################################################
mark@629
  2502
mark@629
  2503
mark@629
  2504
function ReplyPage::lay_print_comment(EntryLite e) {
mark@629
  2505
mark@629
  2506
    var string subject = ($e.subject != "" ? $e.subject : $*text_nosubject);
mark@629
  2507
mark@629
  2508
    """
mark@629
  2509
    <div class="comment">
mark@629
  2510
        <div class="left">
mark@629
  2511
        <div class="userpic">
mark@629
  2512
        """;
mark@629
  2513
        if ($e.userpic) {
mark@629
  2514
            print $e.userpic->as_string();
mark@629
  2515
        }
mark@629
  2516
        """
mark@629
  2517
        </div>
mark@629
  2518
        </div>
mark@629
  2519
        <div class="right">
mark@629
  2520
            <div class="header">
mark@629
  2521
                <div class="title">
mark@629
  2522
                    <h2><a href="$e.permalink_url">$subject</a></h2>
mark@629
  2523
                </div>
mark@629
  2524
                <div class="posted">"""; $this->lay_print_posted_by($e); """</div>
mark@629
  2525
            </div>
mark@629
  2526
            """;
mark@629
  2527
            $this->lay_print_text($e);
mark@629
  2528
            """
mark@629
  2529
            <div class="links">[<a href="$.entry.permalink_url">parent entry</a>] [<a href="$e.permalink_url">$*text_permalink</a>]</div>
mark@629
  2530
        </div>
mark@629
  2531
    </div>
mark@629
  2532
    """;
mark@629
  2533
}
mark@629
  2534
mark@629
  2535
function ReplyPage::print_body() : void {
mark@629
  2536
mark@629
  2537
    # replying to a comment, not an entry.
mark@629
  2538
    #
mark@629
  2539
    """
mark@629
  2540
    <div id="entries">
mark@629
  2541
    """;
mark@629
  2542
    # replying to an entry?
mark@629
  2543
    if ( $this.replyto.depth == 0 ) {
mark@629
  2544
        $this->print_entry($.entry);
mark@629
  2545
    }
mark@629
  2546
    # no, it's a comment
mark@629
  2547
    else {
mark@629
  2548
        $this->lay_print_comment($.replyto);
mark@629
  2549
    }
mark@629
  2550
    """
mark@629
  2551
    </div>
mark@629
  2552
    <div id="reply">
mark@629
  2553
    <h2>Reply</h2>
mark@629
  2554
    """;
mark@629
  2555
    $.form->print();
mark@629
  2556
    """
mark@629
  2557
    </div>
mark@629
  2558
    """;
mark@629
  2559
}
mark@629
  2560
mark@629
  2561
mark@629
  2562
###################################################
mark@629
  2563
#      #                                          #
mark@629
  2564
# ~14. # YearPage                                 #
mark@629
  2565
#      #                                          #
mark@629
  2566
###################################################
mark@629
  2567
mark@629
  2568
# Prints a list of other linkable years.
mark@629
  2569
#
mark@629
  2570
function YearPage::lay_print_extra_box() {
mark@629
  2571
    var string year;
mark@629
  2572
    if (size $.years < 2) {
mark@629
  2573
        return;
mark@629
  2574
    }
mark@629
  2575
mark@629
  2576
    """
mark@629
  2577
    <div class="extra-box">
mark@629
  2578
        <h3 class="title">Years</h3>
mark@629
  2579
        <ul>
mark@629
  2580
        """;
mark@629
  2581
        foreach var YearYear y ($.years) {
mark@629
  2582
            if ($y.displayed) {
mark@629
  2583
                $year = string($y.year);
mark@629
  2584
            } else {
mark@629
  2585
                $year = """<a href="$y.url">$y.year</a>""";
mark@629
  2586
            }
mark@629
  2587
            println """<li>$year</li>""";
mark@629
  2588
        }
mark@629
  2589
        """
mark@629
  2590
        </ul>
mark@629
  2591
    </div>
mark@629
  2592
    """;
mark@629
  2593
}
mark@629
  2594
mark@629
  2595
function YearPage::lay_back_forward() : void {
mark@629
  2596
    if (size $.years < 2) {
mark@629
  2597
        return;
mark@629
  2598
    }
mark@629
  2599
mark@629
  2600
    var YearYear next;
mark@629
  2601
    var YearYear last;
mark@629
  2602
mark@629
  2603
    foreach var YearYear y ($.years) {
mark@629
  2604
        if ( $y.year == $.year - 1 ) {
mark@629
  2605
            $last = $y;
mark@629
  2606
        } elseif ( $y.year == $.year + 1 ) {
mark@629
  2607
            $next = $y;
mark@629
  2608
        }
mark@629
  2609
    }
mark@629
  2610
mark@629
  2611
    """
mark@629
  2612
    <div class="back-forward">
mark@629
  2613
    """;
mark@629
  2614
    if ( defined $last ) {
mark@629
  2615
        """
mark@629
  2616
        <div class="back">
mark@629
  2617
            <a href="$last.url" title="Previous year.">&larr;</a>
mark@629
  2618
        </div>
mark@629
  2619
        """;
mark@629
  2620
    }
mark@629
  2621
    if ( defined $next ) {
mark@629
  2622
        """
mark@629
  2623
        <div class="forward">
mark@629
  2624
            <a href="$next.url" title="Next year.">&rarr;</a>
mark@629
  2625
        </div>
mark@629
  2626
        """;
mark@629
  2627
    }
mark@629
  2628
    """
mark@629
  2629
    </div>
mark@629
  2630
    """;
mark@629
  2631
mark@629
  2632
}
mark@629
  2633
mark@629
  2634
mark@629
  2635
function YearPage::print_month(YearMonth m) {
mark@629
  2636
    """
mark@629
  2637
    <div class="calendar-month">
mark@629
  2638
        <h2 class="title"><a href="$m.url">"""+$m->month_format("%%month%%")+"""</a></h2>
mark@629
  2639
    """;
mark@629
  2640
    $this->lay_print_month($m);
mark@629
  2641
    """
mark@629
  2642
    </div>
mark@629
  2643
    """;
mark@629
  2644
}
mark@629
  2645
mark@629
  2646
mark@629
  2647
function YearPage::print_body {
mark@629
  2648
    if ( size $.months == 0 ) {
mark@629
  2649
        return $this->lay_print_errorpage( $*error_yearpage_no_entries );
mark@629
  2650
    }
mark@629
  2651
mark@629
  2652
    $this->lay_back_forward();
mark@629
  2653
    """
mark@629
  2654
    <div id="calendar">
mark@629
  2655
    """;
mark@629
  2656
    foreach var YearMonth m ($.months) {
mark@629
  2657
        if ($m.has_entries) {
mark@629
  2658
            $this->print_month($m);
mark@629
  2659
        }
mark@629
  2660
    }
mark@629
  2661
    """
mark@629
  2662
    </div>
mark@629
  2663
    """;
mark@629
  2664
    $this->lay_back_forward();
mark@629
  2665
}
mark@629
  2666
mark@629
  2667
###################################################
mark@629
  2668
#      #                                          #
mark@629
  2669
# ~15. # MessagePage                              #
mark@629
  2670
#      #                                          #
mark@629
  2671
#      # Just a stub. AFAICT it's not used in the #
mark@629
  2672
#      # core yet, so I can't test it.            #
mark@629
  2673
#      #                                          #
mark@629
  2674
###################################################
mark@629
  2675
mark@629
  2676
function MessagePage::print_body() {
mark@629
  2677
    """
mark@629
  2678
    <div id="message">
mark@629
  2679
    <p>"""; $this->print_message(); """</p>
mark@629
  2680
    </div>
mark@629
  2681
    """;
mark@629
  2682
}
mark@629
  2683
mark@629
  2684
###################################################
mark@629
  2685
#      #                                          #
mark@629
  2686
# ~16. # TagsPage                                 #
mark@629
  2687
#      #                                          #
mark@629
  2688
###################################################
mark@629
  2689
mark@629
  2690
# Weighted tag cloud / heatmap.
mark@629
  2691
#
mark@629
  2692
function TagsPage::print_body() {
fu@2605
  2693
    # since there is no heading, make invisible one here for
fu@2605
  2694
    # screenreaders
mark@629
  2695
    """
fu@2605
  2696
    <div id="tag-cloud" class="tags_cloud">
fu@2605
  2697
    <h2 class="invisible">Visible tags</h2>
fu@2605
  2698
    <ul>
mark@629
  2699
    """;
mark@629
  2700
mark@629
  2701
    # font min and max as % values
mark@629
  2702
    var int fontmin = 80;
mark@629
  2703
    var int fontmax = 400;
mark@629
  2704
    var int fontspread = $fontmax - $fontmin;
mark@629
  2705
mark@629
  2706
    var int fontstep = 0;
mark@629
  2707
mark@629
  2708
    # set later
mark@629
  2709
    var int countspread;
mark@629
  2710
    var int fontsize;
mark@629
  2711
    var string font;
mark@629
  2712
mark@629
  2713
    var int highest = 0;
mark@629
  2714
    var int lowest = 999999;
mark@629
  2715
    var int count;
fu@2605
  2716
    
mark@629
  2717
    foreach var TagDetail tag ($.tags) {
mark@629
  2718
        if ($tag.use_count > $highest) {
mark@629
  2719
            $highest = $tag.use_count;
mark@629
  2720
        }
mark@629
  2721
        if ($tag.use_count < $lowest) {
mark@629
  2722
            $lowest = $tag.use_count;
mark@629
  2723
        }
mark@629
  2724
    }
mark@629
  2725
mark@629
  2726
    $countspread = $highest - $lowest;
mark@629
  2727
mark@629
  2728
    if ($countspread > 0) {
mark@629
  2729
        $fontstep = $fontspread/$countspread;
mark@629
  2730
    }
mark@629
  2731
mark@629
  2732
    foreach var TagDetail tag ($.tags) {
mark@629
  2733
        if ($highest == $lowest) {
mark@629
  2734
            $font = string($fontmin) + "%";
mark@629
  2735
        } else {
mark@629
  2736
            $fontsize = $fontmin + (($tag.use_count - $lowest) * $fontstep);
mark@629
  2737
            $font = string($fontsize) + "%";
mark@629
  2738
        }
mark@629
  2739
mark@629
  2740
        """
fu@2605
  2741
        <li>
fu@2605
  2742
        <a rel="tag" class="used-$tag.use_count visible-to-$tag.visibility" href="$tag.url" style="font-size: $font;">$tag.name</a>
fu@2605
  2743
        <span class ="invisible"> used $tag.use_count times</span></li>
mark@629
  2744
        """;
mark@629
  2745
    }
mark@629
  2746
mark@629
  2747
    """
fu@2605
  2748
    </ul></div>
mark@629
  2749
    """;
mark@629
  2750
}