mark: A photo of Mark kneeling on top of the Taal Volcano in the Philippines. It was a long hike. (Default)
Mark Smith ([staff profile] mark) wrote in [site community profile] changelog2009-09-21 12:49 am

[dw-free] Sticky entry module

[commit: http://hg.dwscoalition.org/dw-free/rev/7adcc3ea6e4f]

http://bugs.dwscoalition.org/show_bug.cgi?id=1281

Add support for specifying a 'sticky entry', i.e. an entry that always shows
up at the top of your journal on the recent entries view.

Patch by [personal profile] yvi.

Files modified:
  • bin/upgrading/en.dat
  • bin/upgrading/proplists.dat
  • bin/upgrading/s2layers/core2.s2
  • bin/upgrading/s2layers/negatives/layout.s2
  • bin/upgrading/s2layers/zesty/layout.s2
  • cgi-bin/DW/Setting/StickyEntry.pm
  • cgi-bin/LJ/S2.pm
  • cgi-bin/LJ/S2/RecentPage.pm
  • cgi-bin/LJ/S2Theme.pm
  • cgi-bin/LJ/User.pm
  • htdocs/img/silk/entry/sticky_entry.png
  • htdocs/manage/settings/index.bml
--------------------------------------------------------------------------------
diff -r 5ecad953068f -r 7adcc3ea6e4f bin/upgrading/en.dat
--- a/bin/upgrading/en.dat	Mon Sep 21 00:35:50 2009 +0000
+++ b/bin/upgrading/en.dat	Mon Sep 21 00:49:15 2009 +0000
@@ -2791,6 +2791,10 @@ setting.sitescheme.error.invalid=Invalid
 
 setting.sitescheme.label=Site Scheme
 
+setting.stickyentry.error.invalid=Invalid Dreamwidth entry ID or URL entered. 
+
+setting.stickyentry.label=ID or URL of post to make sticky
+
 setting.stylemine.label=Comment Pages
 
 setting.stylemine.option=View comment pages from my Friends page in my own style
diff -r 5ecad953068f -r 7adcc3ea6e4f bin/upgrading/proplists.dat
--- a/bin/upgrading/proplists.dat	Mon Sep 21 00:35:50 2009 +0000
+++ b/bin/upgrading/proplists.dat	Mon Sep 21 00:49:15 2009 +0000
@@ -966,6 +966,14 @@ userproplist.state:
   multihomed: 0
   prettyname: State
 
+userproplist.sticky_entry:
+  cldversion: 4
+  datatype: char
+  des: Sticky Entry ID
+  indexed: 0
+  multihomed: 0
+  prettyname: Sticky Entry ID
+
 userproplist.stylesys:
   cldversion: 4
   datatype: num
diff -r 5ecad953068f -r 7adcc3ea6e4f bin/upgrading/s2layers/core2.s2
--- a/bin/upgrading/s2layers/core2.s2	Mon Sep 21 00:35:50 2009 +0000
+++ b/bin/upgrading/s2layers/core2.s2	Mon Sep 21 00:49:15 2009 +0000
@@ -391,6 +391,16 @@ class Entry extends EntryLite
     "Prints a small horizontal bar of site-specific content between entries in a journal.";
 }
 
+class StickyEntry extends Entry
+"An entry that is shown on top of the journal's recent entries page"
+{
+    var Image sticky_entry_icon "A little icon displayed next to the subject of a sticky entry post";
+
+    function print_sticky_icon () "prints the icon into the subject line";
+}
+
+
+
 class Comment extends EntryLite
 "A comment to a journal entry, or to another comment."
 {
@@ -648,6 +658,11 @@ class RecentPage extends Page
 
     var RecentNav nav;
 
+    var StickyEntry stickyentry
+    "Entry shown on top of the Recent Entries page";
+
+    function print_sticky_entry(StickyEntry s)
+    "function to print the sticky entry";
 }
 
 class FriendsPage extends RecentPage
@@ -2109,6 +2124,8 @@ property string text_permalink {
     size = 20;
 }
 
+property string text_stickyentry_subject { des = "Text that appears before the subject of the sticky entry"; }
+
 set text_entry_prev = "Previous Entry";
 set text_entry_next = "Next Entry";
 set text_edit_entry = "Edit Entry";
@@ -2118,6 +2135,7 @@ set text_watch_comments = "Track This";
 set text_watch_comments = "Track This";
 set text_unwatch_comments = "Untrack This";
 set text_permalink = "Link";
+set text_stickyentry_subject = "Sticky: ";
 
 ##===============================
 ## Text - comment actions
@@ -2382,11 +2400,13 @@ property string text_icon_alt_groups    
 property string text_icon_alt_groups    { noui = 1; des = "Alternative text for icons of custom friends group entries"; }
 property string text_icon_alt_nsfw      { noui = 1; des = "Alternative text for icons of NSFW entries"; }
 property string text_icon_alt_18        { noui = 1; des = "Alternative text for icons of 18+ entries"; }
+property string text_icon_alt_sticky_entry        { noui = 1; des = "Alternative text for icons of sticky entries"; }
 set text_icon_alt_protected = "[protected post]";
 set text_icon_alt_private = "[private post]";
 set text_icon_alt_groups = "[custom friends groups post]";
 set text_icon_alt_nsfw = "[NSFW]";
 set text_icon_alt_18 = "[18+]";
+set text_icon_alt_sticky_entry = "[sticky entry]";
 
 property string text_multiform_check { des = "Text beside a comment multi-action checkbox"; }
 
@@ -3908,6 +3928,13 @@ function Page::print_entry(Entry e)
     $e->print_wrapper_end();
 
 }
+
+function RecentPage::print_sticky_entry(StickyEntry s)
+"function to print the sticky entry. can be overrised by styles to print it differently than other entries."
+{
+    $this->print_entry( $s );
+}
+
 function Comment::print_edit_text() {
     if ($this.edited) {
         print "<div class='ljedittime'><em>$*text_comment_edittime ";
@@ -3946,10 +3973,25 @@ function EntryLite::print_subject( strin
         "</div>";
     }
     else {
-        """<h3 class="entry-title">""";
-        print $this->formatted_subject( $opts );
-        "</h3>";
-    }
+        if ($this isa StickyEntry) {
+            var StickyEntry s = $this as StickyEntry;
+            """<h3 class="sticky-entry-title entry-title">""";
+            $s->print_sticky_icon();
+            print $*text_stickyentry_subject + $this->formatted_subject( $opts );
+            "</h3>";
+        }
+        else {
+            """<h3 class="entry-title">""";
+            print $this->formatted_subject( $opts );
+            "</h3>";
+        }
+    }
+}
+
+function StickyEntry::print_sticky_icon() {
+    """<span class="sticky-entry-icon">""";
+    $this.sticky_entry_icon->print($*text_icon_alt_sticky_entry);
+    """</span>\n""";
 }
 
 function EntryLite::print_wrapper_start() {
@@ -3968,9 +4010,17 @@ function Entry::print_wrapper_start() {
     }
     var string userpic = $this.userpic ? "has-userpic" : "no-userpic";
 
-    """<div class="entry-wrapper $alternate security-$security restrictions-$adult_content_level $journal_type $poster $journal $userpic" id="entry-wrapper-$this.itemid">\n""";
-    """<div class="separator separator-before"><div class="inner"></div></div>\n""";
-    """<div class="entry" id="entry-$this.itemid">\n""";
+    #additional classes for sticky entries added
+    if ($this isa StickyEntry) {
+        """<div class="sticky-entry-wrapper entry-wrapper entry-wrapper-even security-$security restrictions-$adult_content_level $journal_type $poster $journal $userpic" id="sticky-entry-wrapper-$this.itemid">\n""";
+        """<div class="separator separator-before"><div class="inner"></div></div>\n""";
+        """<div class="sticky-entry entry" id="sticky-entry-$this.itemid">\n""";
+    }
+    else {
+        """<div class="entry-wrapper $alternate security-$security restrictions-$adult_content_level $journal_type $poster $journal $userpic" id="entry-wrapper-$this.itemid">\n""";
+        """<div class="separator separator-before"><div class="inner"></div></div>\n""";
+        """<div class="entry" id="entry-$this.itemid">\n""";
+    }
     """<div class="inner">\n""";
 }
 function Comment::print_wrapper_start() {
@@ -4237,7 +4287,13 @@ function RecentPage::print_body {
 
     foreach var Entry e ($.entries) {
         # Print the entry
-        $this->print_entry($e);
+        if ( $e isa StickyEntry ) {
+            var StickyEntry s = $e as StickyEntry;
+            $this->print_sticky_entry($s);
+        } 
+        else {
+	    $this->print_entry($e);
+        }
     }
 
             $this->print_navigation( { "class" => "bottomnav" } );
diff -r 5ecad953068f -r 7adcc3ea6e4f bin/upgrading/s2layers/negatives/layout.s2
--- a/bin/upgrading/s2layers/negatives/layout.s2	Mon Sep 21 00:35:50 2009 +0000
+++ b/bin/upgrading/s2layers/negatives/layout.s2	Mon Sep 21 00:49:15 2009 +0000
@@ -225,6 +225,7 @@ propgroup text {
     property use text_watch_comments; 
     property use text_unwatch_comments; 
     property use text_permalink;
+    property use text_stickyentry_subject;
 
     property use text_module_customtext;
     property use text_module_customtext_content;
diff -r 5ecad953068f -r 7adcc3ea6e4f bin/upgrading/s2layers/zesty/layout.s2
--- a/bin/upgrading/s2layers/zesty/layout.s2	Mon Sep 21 00:35:50 2009 +0000
+++ b/bin/upgrading/s2layers/zesty/layout.s2	Mon Sep 21 00:49:15 2009 +0000
@@ -159,10 +159,12 @@ propgroup Text {
     property use text_skiplinks_forward;
 
     property use text_permalink;
+    property use text_stickyentry_subject;
     property use text_post_comment;
     property use text_post_comment_friends;
 
         set text_permalink = "permalink";
+        set text_stickyentry_subject = "Sticky: ";
         set text_post_comment = "reply";
         set text_post_comment_friends = "reply";
 
@@ -1344,6 +1346,10 @@ function Page::lay_print_entry(Entry e) 
 
 function Page::print_entry(Entry e) {
     $this->lay_print_entry($e);
+}
+
+function RecentPage::print_sticky_entry(StickyEntry s) {
+    $this->lay_print_entry($s);
 }
 
 ###################################################
diff -r 5ecad953068f -r 7adcc3ea6e4f cgi-bin/DW/Setting/StickyEntry.pm
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cgi-bin/DW/Setting/StickyEntry.pm	Mon Sep 21 00:49:15 2009 +0000
@@ -0,0 +1,61 @@
+#!/usr/bin/perl
+#
+# DW::Setting::StickyEntry - set which entry should be used as a sticky entry on top of the journal
+#
+# Authors:
+#      Rebecca Freiburg <beckyvi@gmail.com>
+#
+# Copyright (c) 2009 by Dreamwidth Studios, LLC.
+#
+# This program is free software; you may redistribute it and/or modify it under
+# the same terms as Perl itself. For a copy of the license, please reference
+# 'perldoc perlartistic' or 'perldoc perlgpl'.
+
+package DW::Setting::StickyEntry;
+use base 'LJ::Setting';
+use strict;
+use warnings;
+
+sub should_render {
+    1;
+}
+
+sub label {
+    $_[0]->ml( 'setting.stickyentry.label' );
+}
+
+sub option {
+    my ( $class, $u, $errs, $args ) = @_;
+
+    my $key = $class->pkgkey;
+    my $ret;
+
+    $ret .= LJ::html_text({
+        name  => "${key}stickyid",
+        id    => "${key}stickyid",
+        class => "text",
+        value => $errs ? $class->get_arg( $args, "stickyid" ) : $u->sticky_entry,
+        size  => 30,
+        maxlength => 100,
+    });
+
+    my $errdiv = $class->errdiv( $errs, "stickyid" );
+    $ret .= "<br />$errdiv" if $errdiv;
+
+    return $ret;
+}
+
+sub save {
+    my ( $class, $u, $args ) = @_;
+
+    my $sticky = $class->get_arg( $args, "stickyid" );
+    $sticky = LJ::trim( $sticky || "" );
+    $sticky = LJ::text_trim( $sticky, 0, 100 );
+    unless ( $u->sticky_entry ( $sticky ) ) {
+        $class->errors( "stickyid" => $class->ml( 'setting.stickyentry.error.invalid' ) ) ;
+    }
+    return 1;
+}
+
+
+1;
diff -r 5ecad953068f -r 7adcc3ea6e4f cgi-bin/LJ/S2.pm
--- a/cgi-bin/LJ/S2.pm	Mon Sep 21 00:35:50 2009 +0000
+++ b/cgi-bin/LJ/S2.pm	Mon Sep 21 00:49:15 2009 +0000
@@ -2123,6 +2123,7 @@ sub Image_std
             'security-groups' => Image("$LJ::IMGPREFIX/silk/entry/filtered.png", 16, 16, $ctx->[S2::PROPS]->{'text_icon_alt_groups'}),
             'adult-nsfw' => Image("$LJ::IMGPREFIX/icon_nsfw.png", 16, 16, $ctx->[S2::PROPS]->{'text_icon_alt_nsfw'}),
             'adult-18' => Image("$LJ::IMGPREFIX/icon_18.png", 16, 16, $ctx->[S2::PROPS]->{'text_icon_alt_18'}),
+            'sticky-entry' => Image("$LJ::IMGPREFIX/silk/entry/sticky_entry.png", 16, 16, $ctx->[S2::PROPS]->{'text_icon_alt_sticky_entry'}),
         };
     }
     return $LJ::S2::RES_CACHE->{$name};
@@ -3422,7 +3423,7 @@ sub EntryLite__get_link
     my ($ctx, $this, $key) = @_;
     my $null_link = { '_type' => 'Link', '_isnull' => 1 };
     
-    if ($this->{_type} eq 'Entry') {
+    if ( $this->{_type} eq 'Entry' || $this->{_type} eq 'StickyEntry' ) {
         return _Entry__get_link($ctx, $this, $key);
     }
     elsif ($this->{_type} eq 'Comment') {
@@ -3440,7 +3441,7 @@ sub EntryLite__formatted_subject {
     my ($ctx, $this, $attrs) = @_;
     my $subject = $this->{subject};
     
-    if ( $this->{_type} eq 'Entry' ) {
+    if ( $this->{_type} eq 'Entry' || $this->{_type} eq 'StickyEntry' ) {
         # if an entry does not have a subject, and text_nosubject is not set, return nothing
         return if $subject eq ""  && $ctx->[S2::PROPS]->{text_nosubject} eq "";
 
diff -r 5ecad953068f -r 7adcc3ea6e4f cgi-bin/LJ/S2/RecentPage.pm
--- a/cgi-bin/LJ/S2/RecentPage.pm	Mon Sep 21 00:35:50 2009 +0000
+++ b/cgi-bin/LJ/S2/RecentPage.pm	Mon Sep 21 00:49:15 2009 +0000
@@ -103,6 +103,25 @@ sub RecentPage
 
     die $err if $err;
 
+    # prepare sticky entry for S2 - should there ever be a function to get an s2 formatted entry from an Entry object
+    # this should be changed to use that.  only show sticky entry on first page of Recent Entries, not on skip= pages
+    # or tag and security subfilters
+    my $stickyentry = $u->get_sticky_entry
+        if $skip == 0 && ! $opts->{securityfilter} && ! $opts->{tagids};
+
+    # only show if visible to user
+    if ( $stickyentry && $stickyentry->visible_to( $remote, $get->{viewall} ) ) {
+        unshift @items, {
+            posterid    => $stickyentry->poster->userid, 
+            itemid      => $stickyentry->jitemid, 
+            anum        => $stickyentry->anum,
+            security    => $stickyentry->security, 
+            allowmask   => $stickyentry->allowmask, 
+            alldatepart => LJ::alldatepart_s2($stickyentry->eventtime_mysql), 
+            sticky      => 1 
+        };
+    }
+  
     ### load the log properties
     my %logprops = ();
     my $logtext;
@@ -149,7 +168,8 @@ sub RecentPage
             $text    =~ s{<(?!/?lj)(.*?)>} {&lt;$1&gt;}gi;
         }
 
-        $itemnum++;
+        #don't count sticky item towards total
+        $itemnum++ unless $item->{sticky};
 
         # don't show posts from suspended users or suspended posts unless the user doing the viewing says to (and is allowed)
         next ENTRY if $apu{$posterid} && $apu{$posterid}->is_suspended && !$viewsome;
@@ -249,6 +269,12 @@ sub RecentPage
             'permalink_url' => $permalink,
         });
 
+        if ( $item->{sticky} ) {
+            my $sticky_icon = Image_std('sticky-entry');
+            $entry->{_type} = 'StickyEntry';
+            $entry->{'sticky_entry_icon'} = $sticky_icon;
+        }
+
         push @{$p->{'entries'}}, $entry;
         LJ::run_hook('notify_event_displayed', $entry_obj);
     } # end huge while loop
diff -r 5ecad953068f -r 7adcc3ea6e4f cgi-bin/LJ/S2Theme.pm
--- a/cgi-bin/LJ/S2Theme.pm	Mon Sep 21 00:35:50 2009 +0000
+++ b/cgi-bin/LJ/S2Theme.pm	Mon Sep 21 00:49:15 2009 +0000
@@ -766,6 +766,7 @@ sub entry_props {
         text_post_comment_friends
         text_read_comments_friends
         text_permalink
+        text_stickyentry_subject
         text_entry_prev
         text_entry_next
         text_tell_friend
diff -r 5ecad953068f -r 7adcc3ea6e4f cgi-bin/LJ/User.pm
--- a/cgi-bin/LJ/User.pm	Mon Sep 21 00:35:50 2009 +0000
+++ b/cgi-bin/LJ/User.pm	Mon Sep 21 00:49:15 2009 +0000
@@ -2205,6 +2205,35 @@ sub show_thread_expander {
     return 0;
 }
 
+#get/set Sticky Entry parent ID for settings menu
+sub sticky_entry {
+    my ( $u, $input ) = @_;
+
+    if ( defined $input ) {
+        #also takes URL
+        my $ditemid;
+        if ( $input =~ m!/(\d+)\.html! ) {
+            $ditemid = $1
+        } elsif ( $input =~ m!(\d+)! ) {
+            $ditemid = $1
+        } else {
+            return 0;
+        }
+        $u->set_prop( sticky_entry => $ditemid );
+    }
+    return $u->prop( 'sticky_entry' );
+}
+
+sub get_sticky_entry {
+    my $u = shift;
+
+    if ( my $ditemid = $u->sticky_entry ) {
+        my $item = LJ::Entry->new( $u, ditemid => $ditemid );
+        return $item if $item->valid;
+    }
+    return undef;
+}
+
 sub _lazy_migrate_infoshow {
     my ($u) = @_;
     return 1 unless LJ::is_enabled('infoshow_migrate');
diff -r 5ecad953068f -r 7adcc3ea6e4f htdocs/img/silk/entry/sticky_entry.png
Binary file htdocs/img/silk/entry/sticky_entry.png has changed
diff -r 5ecad953068f -r 7adcc3ea6e4f htdocs/manage/settings/index.bml
--- a/htdocs/manage/settings/index.bml	Mon Sep 21 00:35:50 2009 +0000
+++ b/htdocs/manage/settings/index.bml	Mon Sep 21 00:49:15 2009 +0000
@@ -71,6 +71,7 @@ body<=
                 LJ::Setting::SafeSearch
                 DW::Setting::GoogleAnalytics
                 DW::Setting::ExcludeOwnStats
+                DW::Setting::StickyEntry
             )],
         },
         notifications => {
--------------------------------------------------------------------------------
gchick: Small furry animal wearing a tin-foil hat (Default)

[personal profile] gchick 2009-09-21 02:58 am (UTC)(link)
*\o/*

(Seriously. The whole "date an entry ten years in the future" thing has been driving me nuts for the last, let's see, 8 years.)
yvi: woman showing her biceps, text: "We can DW it" (Dreamwidth)

[personal profile] yvi 2009-09-22 07:45 am (UTC)(link)
So far this can only take one entry. But that's also for communities, so yay shiny!
yvi: woman showing her biceps, text: "We can DW it" (Dreamwidth)

[personal profile] yvi 2009-09-21 07:16 am (UTC)(link)
This made my day!

Or maybe my week. It's only Monday, so I can't say.

*bounce bounce*
cesy: "Cesy" - An old-fashioned quill and ink (Default)

[personal profile] cesy 2009-09-21 12:36 pm (UTC)(link)
I am also happy about the big review/commit run over the weekend. There is lots of shiny on Dreamwidth. :)