6 use vars
qw(@themecoltypes);
8 # this used to be in a table, but that was kinda useless
10 [ 'page_back', 'Page background' ],
11 [ 'page_text', 'Page text' ],
12 [ 'page_link', 'Page link' ],
13 [ 'page_vlink', 'Page visited link' ],
14 [ 'page_alink', 'Page active link' ],
15 [ 'page_text_em', 'Page emphasized text' ],
16 [ 'page_text_title', 'Page title' ],
17 [ 'weak_back', 'Weak accent' ],
18 [ 'weak_text', 'Text on weak accent' ],
19 [ 'strong_back', 'Strong accent' ],
20 [ 'strong_text', 'Text on strong accent' ],
21 [ 'stronger_back', 'Stronger accent' ],
22 [ 'stronger_text', 'Text on stronger accent' ],
25 %LJ::S1w2::viewcreator = (
26 lastn => \&LJ::S1w2::create_view_lastn,
27 friends => \&LJ::S1w2::create_view_friends,
28 calendar => \&LJ::S1w2::create_view_calendar,
29 day => \&LJ::S1w2::create_view_day,
35 # safe in styles as sole attributes, without any cleaning. for
36 # example: <a href="%%urlread%%"> is okay, # if we're in
37 # LASTN_TALK_READLINK, because the system generates # %%urlread%%.
38 # by default, if we don't declare things trusted here, # we'll
39 # double-check all attributes at the end for potential XSS #
43 # is a URL. implies /a/.
47 # is a number. implies /a/.
50 # tainted! User controls via other some other variable.
53 # some system string... probably safe. but maybe possible to coerce it
54 # alongside something else.
58 'yy' => 'd', 'yyyy' => 'd',
59 'm' => 'd', 'mm' => 'd',
60 'd' => 'd', 'dd' => 'd',
62 '12h' => 'd', '12hh' => 'd',
63 '24h' => 'd', '24hh' => 'd',
66 'messagecount' => 'd',
72 'messagecount' => 'd',
84 yy => 'd', yyyy => 'd', m => 'd', mm => 'd',
101 'CALENDAR_DAY_EVENT' => {
105 'CALENDAR_DAY_NOEVENT' => {
107 'CALENDAR_EMPTY_DAYS' => {
110 'CALENDAR_MONTH' => {
116 'urlmonthview' => 'u',
118 'CALENDAR_NEW_YEAR' => {
133 'CALENDAR_WEBSITE' => {
139 'emptydays_beg' => 't',
140 'emptydays_end' => 't',
142 'CALENDAR_YEAR_DISPLAYED' => {
146 'CALENDAR_YEAR_LINK' => {
151 'CALENDAR_YEAR_LINKS' => {
154 'CALENDAR_SKYSCRAPER_AD' => {
157 'CALENDAR_5LINKUNIT_AD' => {
162 'DAY_DATE_FORMAT' => $commonprop->{'dateformat'},
163 'DAY_EVENT' => $commonprop->{'event'},
164 'DAY_EVENT_PRIVATE' => $commonprop->{'event'},
165 'DAY_EVENT_PROTECTED' => $commonprop->{'event'},
167 'prevday_url' => 'u',
168 'nextday_url' => 'u',
169 'yy' => 'd', 'yyyy' => 'd',
170 'm' => 'd', 'mm' => 'd',
171 'd' => 'd', 'dd' => 'd',
173 'urlcalendar' => 'u',
176 'DAY_TALK_LINKS' => $commonprop->{'talklinks'},
177 'DAY_TALK_READLINK' => $commonprop->{'talkreadlink'},
178 'DAY_SKYSCRAPER_AD' => {
181 'DAY_5LINKUNIT_AD' => {
186 'FRIENDS_DATE_FORMAT' => $commonprop->{'dateformat'},
187 'FRIENDS_EVENT' => $commonprop->{'event'},
188 'FRIENDS_EVENT_PRIVATE' => $commonprop->{'event'},
189 'FRIENDS_EVENT_PROTECTED' => $commonprop->{'event'},
190 'FRIENDS_FRIENDPIC' => $commonprop->{'pic'},
191 'FRIENDS_NEW_DAY' => $commonprop->{'newday'},
192 'FRIENDS_RANGE_HISTORY' => {
196 'FRIENDS_RANGE_MOSTRECENT' => {
199 'FRIENDS_SKIP_BACKWARD' => $commonprop->{'skip'},
200 'FRIENDS_SKIP_FORWARD' => $commonprop->{'skip'},
201 'FRIENDS_TALK_LINKS' => $commonprop->{'talklinks'},
202 'FRIENDS_TALK_READLINK' => $commonprop->{'talkreadlink'},
203 'FRIENDS_SKYSCRAPER_AD' => {
206 'FRIENDS_5LINKUNIT_AD' => {
211 'LASTN_ALTPOSTER' => {
216 'LASTN_ALTPOSTER_PIC' => $commonprop->{'pic'},
221 'LASTN_CURRENTS' => {
224 'LASTN_DATEFORMAT' => $commonprop->{'dateformat'},
225 'LASTN_EVENT' => $commonprop->{'event'},
226 'LASTN_EVENT_PRIVATE' => $commonprop->{'event'},
227 'LASTN_EVENT_PROTECTED' => $commonprop->{'event'},
228 'LASTN_NEW_DAY' => $commonprop->{'newday'},
231 'urlcalendar' => 'u',
232 'skyscraper_ad' => 't',
234 'LASTN_RANGE_HISTORY' => {
238 'LASTN_RANGE_MOSTRECENT' => {
241 'LASTN_SKIP_BACKWARD' => $commonprop->{'skip'},
242 'LASTN_SKIP_FORWARD' => $commonprop->{'skip'},
243 'LASTN_TALK_LINKS' => $commonprop->{'talklinks'},
244 'LASTN_TALK_READLINK' => $commonprop->{'talkreadlink'},
250 'LASTN_SKYSCRAPER_AD' => {
253 'LASTN_5LINKUNIT_AD' => {
258 sub current_mood_str {
259 my ($pic, $moodname) = @_;
264 $ret .= qq{<img src="$pic->{url}" align="absmiddle" width="$pic->{width}" height="$pic->{height}" vspace="1" alt="" /> };
272 my ($item, $vars, $prefix, $eventnum, $s2p) = @_;
276 my %date_format = %{LJ::S1w2::date_s2_to_s1($item->{time})};
279 $event{'eventnum'} = $eventnum;
280 $event{'itemid'} = $item->{itemid};
281 $event{'datetime'} = LJ::fill_var_props($vars, "${prefix}_DATE_FORMAT", \%date_format);
282 if ($item->{subject}) {
283 $event{'subject'} = LJ::fill_var_props($vars, "${prefix}_SUBJECT", {
284 "subject" => $item->{subject},
288 $event{'event'} = $item->{text};
289 $event{'user'} = $item->{journal}{username};
291 # Special case for friends view: userpic for friend
292 if ($vars->{"${prefix}_FRIENDPIC"} && $item->{userpic} && $item->{userpic}{url}) {
293 $event{friendpic} = LJ::fill_var_props($vars, "${prefix}_FRIENDPIC", {
294 "width" => $item->{userpic}{width},
295 "height" => $item->{userpic}{height},
296 "src" => $item->{userpic}{url},
300 # Special case for friends view: per-friend configured colors
301 if ($s2p && $s2p->{friends}) {
302 $event{fgcolor} = $s2p->{friends}{$item->{journal}{username}}{fgcolor}{as_string};
303 $event{bgcolor} = $s2p->{friends}{$item->{journal}{username}}{bgcolor}{as_string};
306 if ($item->{comments}{enabled}) {
307 my $itemargs = "journal=".$item->{journal}{username}."&ditemid=".$item->{itemid};
309 $event{'talklinks'} = LJ::fill_var_props($vars, "${prefix}_TALK_LINKS", {
310 'itemid' => $item->{itemid},
311 'itemargs' => $itemargs,
312 'urlpost' => $item->{comments}{post_url},
313 'urlread' => $item->{comments}{read_url},
314 'messagecount' => $item->{comments}{count},
315 'readlink' => $item->{comments}{show_readlink} ? LJ::fill_var_props($vars, "${prefix}_TALK_READLINK", {
316 'urlread' => $item->{comments}{read_url},
317 'messagecount' => $item->{comments}{count} == -1 ? "?" : $item->{comments}{count},
318 'mc-plural-s' => $item->{comments}{count} == 1 ? "" : "s",
319 'mc-plural-es' => $item->{comments}{count} == 1 ? "" : "es",
320 'mc-plural-ies' => $item->{comments}{count} == 1 ? "y" : "ies",
325 LJ::prepare_currents({
332 if ($item->{poster}{_u}{userid} != $item->{journal}{_u}{userid}) {
335 $altposter{'poster'} = $item->{poster}{username};
336 $altposter{'owner'} = $item->{journal}{username};
337 $altposter{'fgcolor'} = $event{'fgcolor'}; # Only set for friends view
338 $altposter{'bgcolor'} = $event{'bgcolor'}; # Only set for friends view
340 if ($item->{userpic} && $item->{userpic}->{url} && $vars->{"${prefix}_ALTPOSTER_PIC"}) {
341 $altposter{'pic'} = LJ::fill_var_props($vars, "${prefix}_ALTPOSTER_PIC", {
342 "src" => $item->{userpic}{url},
343 "width" => $item->{userpic}{width},
344 "height" => $item->{userpic}{height},
347 $event{'altposter'} = LJ::fill_var_props($vars, "${prefix}_ALTPOSTER", \%altposter);
350 my $var = "${prefix}_EVENT";
351 if ($item->{security} eq "private" &&
352 $vars->{"${prefix}_EVENT_PRIVATE"}) { $var = "${prefix}_EVENT_PRIVATE"; }
353 if ($item->{security} eq "protected" &&
354 $vars->{"${prefix}_EVENT_PROTECTED"}) { $var = "${prefix}_EVENT_PROTECTED"; }
356 return LJ::fill_var_props($vars, $var, \%event);
362 # name: LJ::S1w2::prepare_currents
363 # des: do all the current music/mood/weather/whatever stuff. only used by ljviews.pl.
365 # des-args: hashref with keys: 'entry' (an S2 Entry object), 'vars' hashref with
366 # keys being S1 variables and 'prefix' string which is LASTN, DAY, etc.
372 my $datakey = $args->{'datakey'} || $args->{'itemid'}; # new || old
374 my $entry = $args->{entry};
378 if (my $val = $entry->{metadata}{music}) {
379 $currents{'Music'} = $val;
382 $currents{'Mood'} = LJ::current_mood_str($entry->{mood_icon}, $entry->{metadata}{mood});
383 delete $currents{'Mood'} unless $currents{'Mood'};
386 if ($args->{'vars'}->{$args->{'prefix'}.'_CURRENTS'})
388 ### PREFIX_CURRENTS is defined, so use the correct style vars
390 my $fvp = { 'currents' => "" };
391 foreach (sort keys %currents) {
392 $fvp->{'currents'} .= LJ::fill_var_props($args->{'vars'}, $args->{'prefix'}.'_CURRENT', {
394 'value' => $currents{$_},
397 $args->{'event'}->{'currents'} =
398 LJ::fill_var_props($args->{'vars'}, $args->{'prefix'}.'_CURRENTS', $fvp);
401 ### PREFIX_CURRENTS is not defined, so just add to %%events%%
402 $args->{'event'}->{'event'} .= "<br /> ";
403 foreach (sort keys %currents) {
404 $args->{'event'}->{'event'} .= "<br /><b>Current $_</b>: " . $currents{$_} . "\n";
412 # name: LJ::S1w2::date_s2_to_s1
413 # des: Convert an S2 Date or DateTime object into an S1 date hash.
415 # des-s2date: the S2 date object to convert.
420 my $dayofweek = S2::Builtin::LJ::Date__day_of_week([], $s2d);
421 my $am = $s2d->{hour} < 12 ? 'am' : 'pm';
422 my $h12h = $s2d->{hour} > 12 ? $s2d->{hour} - 12 : $s2d->{hour};
423 $h12h ||= 12; # Fix up hour 0
425 'dayshort' => LJ::Lang::day_short($dayofweek),
426 'daylong' => LJ::Lang::day_long($dayofweek),
427 'monshort' => LJ::Lang::month_short($s2d->{month}),
428 'monlong' => LJ::Lang::month_long($s2d->{month}),
429 'yy' => substr($s2d->{year}, -2),
430 'yyyy' => $s2d->{year},
431 'm' => $s2d->{month},
432 'mm' => sprintf("%02i", $s2d->{month}),
434 'dd' => sprintf("%02i", $s2d->{day}),
435 'dth' => $s2d->{day}.LJ::Lang::day_ord($s2d->{day}),
436 'ap' => substr($am,1),
437 'AP' => substr(uc($am),1),
440 'min' => sprintf("%02i", $s2d->{min}),
442 '12hh' => sprintf("%02i", $h12h),
443 '24h' => $s2d->{hour},
444 '24hh' => sprintf("%02i", $s2d->{hour}),
448 sub prepare_adverts_and_control_strip {
449 my ($vars, $prefix, $page, $u) = @_;
451 my $show_ad = LJ::run_hook('should_show_ad', {
455 my $show_control_strip = LJ::run_hook('show_control_strip', {
459 # FIXME: Do I need to add the ad and control stuff to <head> here,
460 # or has the S2 backend done it for me already?
462 # Note: unlike the rest of this, we're not using the S2 API to do the ads or control strip,
463 # but instead just hitting the respective APIs directly.
464 if ($LJ::USE_ADS && $show_ad) {
465 $page->{'skyscraper_ad'} = LJ::fill_var_props($vars, "${prefix}_SKYSCRAPER_AD",
466 { "ad" => LJ::ads( type => "journal",
467 orient => 'Journal-Badge',
468 pubtext => $LJ::REQ_GLOBAL{'text_of_first_public_post'},
469 user => $u->{user}) .
470 LJ::ads( type => "journal",
471 orient => 'Journal-Skyscraper',
472 pubtext => $LJ::REQ_GLOBAL{'text_of_first_public_post'},
473 user => $u->{user}), });
474 $page->{'open_skyscraper_ad'} = $vars->{"${prefix}_OPEN_SKYSCRAPER_AD"};
475 $page->{'close_skyscraper_ad'} = $vars->{"${prefix}_CLOSE_SKYSCRAPER_AD"};
477 if ($LJ::USE_CONTROL_STRIP && $show_control_strip) {
478 my $control_strip = LJ::control_strip(user => $u->{user});
479 $page->{'control_strip'} = $control_strip;
487 use lib "$ENV{LJHOME}/cgi-bin";
492 require "cleanhtml.pl";
494 # the creator for the 'lastn' view:
495 sub create_view_lastn
497 my ($ret, $u, $vars, $remote, $opts) = @_;
499 # Fake S2 context. Bit of a hack.
501 $s2ctx->[S2::PROPS] = {
502 "page_recent_items" => ($vars->{'LASTN_OPT_ITEMS'}+0) || 20,
504 $opts->{ctx} = $s2ctx;
506 my $s2p = LJ::S2::RecentPage($u, $remote, $opts);
509 $lastn_page{'name'} = $s2p->{journal}{name};
510 $lastn_page{'name-\'s'} = ($lastn_page{'name'} =~ /s$/i) ? "'" : "'s";
511 $lastn_page{'username'} = $s2p->{journal}{username};
512 $lastn_page{'title'} = LJ::ehtml($u->{'journaltitle'} ||
513 $lastn_page{'name'} . $lastn_page{'name-\'s'} . " Journal");
514 $lastn_page{'numitems'} = ($vars->{'LASTN_OPT_ITEMS'}) || 20;
516 $lastn_page{'urlfriends'} = $s2p->{view_url}{friends};
517 $lastn_page{'urlcalendar'} = $s2p->{view_url}{archive};
519 if ($s2p->{journal}{website_url}) {
520 $lastn_page{'website'} =
521 LJ::fill_var_props($vars, 'LASTN_WEBSITE', {
522 "url" => $s2p->{journal}{website_url},
523 "name" => $s2p->{journal}{website_name} || "My Website",
527 $lastn_page{'events'} = "";
528 $lastn_page{'head'} = $s2p->{head_content};
529 $lastn_page{'head'} .= LJ::res_includes();
530 $lastn_page{'head'} .= $vars->{'GLOBAL_HEAD'} . "\n" . $vars->{'LASTN_HEAD'};
532 my $events = \$lastn_page{'events'};
534 if ($s2p->{journal}{default_pic}{url}) {
535 my $pic = $s2p->{journal}{default_pic};
536 $lastn_page{'userpic'} =
537 LJ::fill_var_props($vars, 'LASTN_USERPIC', {
538 "src" => $pic->{url},
539 "width" => $pic->{width},
540 "height" => $pic->{height},
546 foreach my $item (@{$s2p->{entries}}) {
547 if ($item->{new_day}) {
548 my %date_format = %{LJ::S1w2::date_s2_to_s1($item->{time})};
550 foreach (qw(dayshort daylong monshort monlong m mm yy yyyy d dd dth)) {
551 $new_day{$_} = $date_format{$_};
554 $$events .= LJ
::fill_var_props
($vars, "LASTN_END_DAY", {});
556 $$events .= LJ
::fill_var_props
($vars, "LASTN_NEW_DAY", \
%new_day);
561 $$events .= LJ
::S1w2
::prepare_event
($item, $vars, 'LASTN', $eventnum++);
564 $$events .= LJ
::fill_var_props
($vars, 'LASTN_END_DAY', {});
566 if ($s2p->{nav
}{skip
}) {
567 $lastn_page{'range'} =
568 LJ
::fill_var_props
($vars, 'LASTN_RANGE_HISTORY', {
569 "numitems" => $s2p->{nav
}{count
},
570 "skip" => $s2p->{nav
}{skip
},
573 $lastn_page{'range'} =
574 LJ
::fill_var_props
($vars, 'LASTN_RANGE_MOSTRECENT', {
575 "numitems" => $s2p->{nav
}{count
},
579 #### make the skip links
580 my ($skip_f, $skip_b) = (0, 0);
583 if ($s2p->{nav
}{forward_url
}) {
586 $skiplinks{'skipforward'} =
587 LJ
::fill_var_props
($vars, 'LASTN_SKIP_FORWARD', {
588 "numitems" => $s2p->{nav
}{forward_count
},
589 "url" => $s2p->{nav
}{forward_url
},
593 my $maxskip = $LJ::MAX_SCROLLBACK_LASTN
- $vars->{'LASTN_OPT_ITEMS'};
595 if ($s2p->{nav
}{backward_url
}) {
598 $skiplinks{'skipbackward'} =
599 LJ
::fill_var_props
($vars, 'LASTN_SKIP_BACKWARD', {
600 "numitems" => $s2p->{nav
}{backward_count
},
601 "url" => $s2p->{nav
}{backward_url
},
605 ### if they're both on, show a spacer
606 if ($skip_b && $skip_f) {
607 $skiplinks{'skipspacer'} = $vars->{'LASTN_SKIP_SPACER'};
610 ### if either are on, put skiplinks into lastn_page
611 if ($skip_b || $skip_f) {
612 $lastn_page{'skiplinks'} =
613 LJ
::fill_var_props
($vars, 'LASTN_SKIP_LINKS', \
%skiplinks);
616 LJ
::S1w2
::prepare_adverts_and_control_strip
($vars, "LASTN", \
%lastn_page, $u);
618 $$ret = LJ
::fill_var_props
($vars, 'LASTN_PAGE', \
%lastn_page);
623 # the creator for the 'friends' view:
624 sub create_view_friends
626 my ($ret, $u, $vars, $remote, $opts) = @_;
631 # Fake S2 context. Bit of a hack.
633 $s2ctx->[S2
::PROPS
] = {
634 "page_recent_items" => ($vars->{'FRIENDS_OPT_ITEMS'}+0) || 20,
636 $opts->{ctx
} = $s2ctx;
638 my $s2p = LJ
::S2
::FriendsPage
($u, $remote, $opts);
639 return $s2p if ref $s2p ne 'HASH';
641 my %friends_page = ();
642 $friends_page{'name'} = $s2p->{journal
}{name
};
643 $friends_page{'name-\'s'} = ($friends_page{'name'} =~ /s$/i) ?
"'" : "'s";
644 $friends_page{'username'} = $s2p->{journal
}{username
};
645 $friends_page{'title'} = LJ
::ehtml
($u->{'friendspagetitle'} ||
646 $friends_page{'name'} . $friends_page{'name-\'s'} . " Friends");
647 $friends_page{'numitems'} = ($vars->{'FRIENDS_OPT_ITEMS'}+0) || 20;
649 $friends_page{'urllastn'} = $s2p->{view_url
}{recent
};
650 $friends_page{'urlcalendar'} = $s2p->{view_url
}{archive
};
652 if ($s2p->{journal
}{website_url
}) {
653 $friends_page{'website'} =
654 LJ
::fill_var_props
($vars, 'FRIENDS_WEBSITE', {
655 "url" => $s2p->{journal
}{website_url
},
656 "name" => $s2p->{journal
}{website_name
} || "My Website",
660 $friends_page{'events'} = "";
661 $friends_page{'head'} = $s2p->{head_content
};
662 $friends_page{'head'} .= LJ
::res_includes
();
663 $friends_page{'head'} .= $vars->{'GLOBAL_HEAD'} . "\n" . $vars->{'LASTN_HEAD'};
665 if ($s2p->{nav
}{skip
}) {
666 $friends_page{'range'} =
667 LJ
::fill_var_props
($vars, 'FRIENDS_RANGE_HISTORY', {
668 "numitems" => $s2p->{nav
}{count
},
669 "skip" => $s2p->{nav
}{skip
},
672 $friends_page{'range'} =
673 LJ
::fill_var_props
($vars, 'FRIENDS_RANGE_MOSTRECENT', {
674 "numitems" => $s2p->{nav
}{count
},
678 #### make the skip links
679 my ($skip_f, $skip_b) = (0, 0);
682 if ($s2p->{nav
}{forward_url
}) {
685 $skiplinks{'skipforward'} =
686 LJ
::fill_var_props
($vars, 'FRIENDS_SKIP_FORWARD', {
687 "numitems" => $s2p->{nav
}{forward_count
},
688 "url" => $s2p->{nav
}{forward_url
},
692 if ($s2p->{nav
}{backward_url
}) {
695 $skiplinks{'skipbackward'} =
696 LJ
::fill_var_props
($vars, 'FRIENDS_SKIP_BACKWARD', {
697 "numitems" => $s2p->{nav
}{backward_count
},
698 "url" => $s2p->{nav
}{backward_url
},
702 ### if they're both on, show a spacer
703 if ($skip_b && $skip_f) {
704 $skiplinks{'skipspacer'} = $vars->{'FRIENDS_SKIP_SPACER'};
707 ### if either are on, put skiplinks into lastn_page
708 if ($skip_b || $skip_f) {
709 $friends_page{'skiplinks'} =
710 LJ
::fill_var_props
($vars, 'FRIENDS_SKIP_LINKS', \
%skiplinks);
713 unless (%{$s2p->{friends
}}) {
714 $friends_page{'events'} = LJ
::fill_var_props
($vars, 'FRIENDS_NOFRIENDS', {
715 "name" => $friends_page{'name'},
716 "name-\'s" => $friends_page{'name-\'s'},
717 "username" => $friends_page{'username'},
720 $$ret .= LJ
::fill_var_props
($vars, 'FRIENDS_PAGE', \
%friends_page);
724 my %friends_events = ();
725 my $events = \
$friends_events{'events'};
730 foreach my $item (@
{$s2p->{entries
}}) {
731 if ($item->{new_day
}) {
732 my %date_format = %{LJ
::S1w2
::date_s2_to_s1
($item->{time})};
734 foreach (qw(dayshort daylong monshort monlong m mm yy yyyy d dd dth)) {
735 $new_day{$_} = $date_format{$_};
738 $$events .= LJ
::fill_var_props
($vars, "FRIENDS_END_DAY", {});
740 $$events .= LJ
::fill_var_props
($vars, "FRIENDS_NEW_DAY", \
%new_day);
745 $$events .= LJ
::S1w2
::prepare_event
($item, $vars, 'FRIENDS', $eventnum++, $s2p);
748 $$events .= LJ
::fill_var_props
($vars, 'FRIENDS_END_DAY', {});
749 $friends_page{'events'} = LJ
::fill_var_props
($vars, 'FRIENDS_EVENTS', \
%friends_events);
751 LJ
::S1w2
::prepare_adverts_and_control_strip
($vars, "FRIENDS", \
%friends_page, $u);
753 $$ret .= LJ
::fill_var_props
($vars, 'FRIENDS_PAGE', \
%friends_page);
758 # the creator for the 'calendar' view:
759 sub create_view_calendar
761 my ($ret, $u, $vars, $remote, $opts) = @_;
763 # Fake S2 context. Bit of a hack.
765 $s2ctx->[S2
::PROPS
] = {
766 "page_recent_items" => $vars->{'LASTN_OPT_ITEMS'}+0,
768 $opts->{ctx
} = $s2ctx;
770 my $s2p = LJ
::S2
::YearPage
($u, $remote, $opts);
772 my $user = $u->{'user'};
774 my %calendar_page = ();
775 $calendar_page{'name'} = $s2p->{journal
}{name
};
776 $calendar_page{'name-\'s'} = ($calendar_page{'name'} =~ /s$/i) ?
"'" : "'s";
777 $calendar_page{'username'} = $user;
778 $calendar_page{'title'} = LJ
::ehtml
($u->{'journaltitle'} ||
779 $calendar_page{'name'} . $calendar_page{'name-\'s'} . " Journal");
781 $calendar_page{'urlfriends'} = $s2p->{view_url
}{friends
};
782 $calendar_page{'urllastn'} = $s2p->{view_url
}{recent
};
784 $calendar_page{'head'} = $s2p->{head_content
};
785 $calendar_page{'head'} .= LJ
::res_includes
();
786 $calendar_page{'head'} .= $vars->{'GLOBAL_HEAD'} . "\n" . $vars->{'CALENDAR_HEAD'};
788 if ($s2p->{journal
}{website_url
}) {
789 $calendar_page{'website'} = LJ
::fill_var_props
($vars, 'CALENDAR_WEBSITE', {
790 "url" => $s2p->{journal
}{website_url
},
791 "name" => $s2p->{journal
}{website_name
} || "My Website",
795 $calendar_page{'months'} = "";
796 my $months = \
$calendar_page{'months'};
798 if (scalar(@
{$s2p->{years
}}) > 1) {
800 foreach my $year ($vars->{CALENDAR_SORT_MODE
} eq 'reverse' ?
reverse @
{$s2p->{years
}} : @
{$s2p->{years
}}) {
801 my $yy = sprintf("%02d", $year->{year
} % 100);
802 my $url = $year->{url
};
803 unless ($year->{displayed
}) {
804 $yearlinks .= LJ
::fill_var_props
($vars, 'CALENDAR_YEAR_LINK', {
805 "url" => $url, "yyyy" => $year->{year
}, "yy" => $yy });
807 $yearlinks .= LJ
::fill_var_props
($vars, 'CALENDAR_YEAR_DISPLAYED', {
808 "yyyy" => $year->{year
}, "yy" => $yy });
811 $calendar_page{'yearlinks'} = LJ
::fill_var_props
($vars, 'CALENDAR_YEAR_LINKS', { "years" => $yearlinks });
814 $$months .= LJ
::fill_var_props
($vars, 'CALENDAR_NEW_YEAR', {
815 'yyyy' => $s2p->{year
},
816 'yy' => substr($s2p->{year
}, 2, 2),
819 foreach my $month ($vars->{CALENDAR_SORT_MODE
} eq 'reverse' ?
reverse @
{$s2p->{months
}} : @
{$s2p->{months
}}) {
820 next unless $month->{has_entries
};
822 my %calendar_month = ();
823 $calendar_month{'monlong'} = LJ
::Lang
::month_long
($month->{month
});
824 $calendar_month{'monshort'} = LJ
::Lang
::month_short
($month->{month
});
825 $calendar_month{'yyyy'} = $month->{year
};
826 $calendar_month{'yy'} = substr($calendar_month{'yyyy'}, 2, 2);
827 $calendar_month{'weeks'} = "";
828 $calendar_month{'urlmonthview'} = $month->{url
};
829 my $weeks = \
$calendar_month{'weeks'};
831 foreach my $week (@
{$month->{weeks
}}) {
832 my %calendar_week = ();
834 $calendar_week{emptydays_beg
} = LJ
::fill_var_props
($vars, 'CALENDAR_EMPTY_DAYS', { "numempty" => $week->{pre_empty
} }) if $week->{pre_empty
};
835 $calendar_week{emptydays_end
} = LJ
::fill_var_props
($vars, 'CALENDAR_EMPTY_DAYS', { "numempty" => $week->{post_empty
} }) if $week->{post_empty
};
836 $calendar_week{days
} = "";
837 my $days = \
$calendar_week{days
};
839 foreach my $day (@
{$week->{days
}}) {
840 my %calendar_day = ();
842 $calendar_day{d
} = $day->{date
}{day
};
843 $calendar_day{eventcount
} = $day->{num_entries
};
844 $calendar_day{dayevent
} = LJ
::fill_var_props
($vars, 'CALENDAR_DAY_EVENT', {
845 eventcount
=> $day->{num_entries
},
846 dayurl
=> $day->{url
},
847 }) if $day->{num_entries
};
848 $calendar_day{daynoevent
} = LJ
::fill_var_props
($vars, 'CALENDAR_DAY_NOEVENT', {}) unless $day->{num_entries
};
850 $$days .= LJ
::fill_var_props
($vars, 'CALENDAR_DAY', \
%calendar_day);
853 $$weeks .= LJ
::fill_var_props
($vars, 'CALENDAR_WEEK', \
%calendar_week);
855 $$months .= LJ
::fill_var_props
($vars, 'CALENDAR_MONTH', \
%calendar_month);
858 LJ
::S1w2
::prepare_adverts_and_control_strip
($vars, "CALENDAR", \
%calendar_page, $u);
860 $$ret .= LJ
::fill_var_props
($vars, 'CALENDAR_PAGE', \
%calendar_page);
865 # the creator for the 'day' view:
868 my ($ret, $u, $vars, $remote, $opts) = @_;
871 # Fake S2 context. Bit of a hack.
873 $s2ctx->[S2
::PROPS
] = {
874 "page_recent_items" => $vars->{'LASTN_OPT_ITEMS'}+0,
876 $opts->{ctx
} = $s2ctx;
878 my $s2p = LJ
::S2
::DayPage
($u, $remote, $opts);
880 my $user = $u->{'user'};
883 $day_page{'name'} = $s2p->{journal
}{name
};
884 $day_page{'name-\'s'} = ($day_page{'name'} =~ /s$/i) ?
"'" : "'s";
885 $day_page{'username'} = $user;
886 $day_page{'title'} = LJ
::ehtml
($u->{'journaltitle'} ||
887 $day_page{'name'} . $day_page{'name-\'s'} . " Journal");
889 $day_page{'urlfriends'} = $s2p->{view_url
}{friends
};
890 $day_page{'urllastn'} = $s2p->{view_url
}{recent
};
891 $day_page{'urlcalendar'} = $s2p->{view_url
}{archive
};
893 $day_page{'head'} = $s2p->{head_content
};
894 $day_page{'head'} .= LJ
::res_includes
();
895 $day_page{'head'} .= $vars->{'GLOBAL_HEAD'} . "\n" . $vars->{'DAY_HEAD'};
897 if ($s2p->{journal
}{website_url
}) {
898 $day_page{'website'} = LJ
::fill_var_props
($vars, 'DAY_WEBSITE', {
899 "url" => $s2p->{journal
}{website_url
},
900 "name" => $s2p->{journal
}{website_name
} || "My Website",
904 my $date = LJ
::S1w2
::date_s2_to_s1
($s2p->{date
});
905 map { $day_page{$_} = $date->{$_} } qw(dayshort daylong monshort monlong yy yyyy m mm d dd dth);
907 $day_page{'prevday_url'} = $s2p->{prev_url
};
908 $day_page{'nextday_url'} = $s2p->{next_url
};
910 $day_page{'events'} = "";
911 my $events = \
$day_page{'events'};
913 my $entries = $s2p->{entries
};
916 foreach my $item ($vars->{DAY_SORT_MODE
} eq 'reverse' ?
reverse @
$entries : @
$entries) {
917 $inevents .= LJ
::S1w2
::prepare_event
($item, $vars, 'DAY');
919 $$events = LJ
::fill_var_props
($vars, 'DAY_EVENTS', { events
=> $inevents });
922 $$events = LJ
::fill_var_props
($vars, 'DAY_NOEVENTS', {});
925 LJ
::S1w2
::prepare_adverts_and_control_strip
($vars, "DAY", \
%day_page, $u);
927 $$ret .= LJ
::fill_var_props
($vars, 'DAY_PAGE', \
%day_page);
931 # Temporary utility function called by LJ::make_journal in LJ/User.pm
932 # to make a diff between pure S1 output and S1w2 output.
934 my ($pure, $mine) = @_;
936 # This is really ghetto, hits the filesystem and
937 # won't work for two concurrent requests, but
938 # it works well enough for a single-user dev server.
939 my $tn1 = "/tmp/s1plain";
940 my $tn2 = "/tmp/s1w2";
941 open(S1PLAIN
, '>', $tn1);
942 open(S1w2
, '>', $tn2);
947 my $diff = `diff -u $tn1 $tn2`;