root/trunk/plagger/lib/Plagger/Plugin/Widget/Simple.pm

Revision 1741 (checked in by miyagawa, 14 years ago)

merge from hackathon-summary

Line 
1 package Plagger::Plugin::Widget::Simple;
2 use strict;
3 use base qw( Plagger::Plugin );
4
5 use Encode;
6 use HTML::Entities;
7 use URI;
8
9 sub register {
10     my($self, $context) = @_;
11     $context->register_hook(
12         $self,
13         'publish.entry.fixup' => \&add,
14         'plugin.init'         => \&initialize,
15     );
16 }
17
18 sub initialize {
19     my($self, $context, $args) = @_;
20
21     if (my $name = $self->conf->{widget}) {
22         my $found;
23         $self->load_assets(
24             "$name.yaml",
25             sub {
26                 my $data = YAML::LoadFile(shift);
27                 $self->{conf} = { %{$self->{conf}}, %$data };
28                 $found++;
29             },
30         );
31
32         unless ($found) {
33             $context->log(error => "Can't find widget for $name");
34         }
35     }
36 }
37
38 sub add {
39     my($self, $context, $args) = @_;
40
41     my $widget = Plagger::Plugin::Widget::Simple::Widget->new;
42     $widget->{feed}   = $args->{entry}->source || $args->{feed};
43     $widget->{plugin} = $self;
44
45     $args->{entry}->add_widget($widget);
46 }
47
48 package Plagger::Plugin::Widget::Simple::Widget;
49
50 sub new { bless {}, shift }
51
52 sub feed { shift->{feed} }
53 sub plugin { shift->{plugin} }
54
55 sub value {
56     my($self, $string, $args) = @_;
57
58     if ($string =~ /\$/) { # DWIM
59         $string = eval $string;
60         Plagger->context->log(error => $@) if $@;
61
62         $string = "$string"; # stringify ::Content
63         utf8::encode($string) if utf8::is_utf8($string);
64     }
65
66     $string;
67 }
68
69 sub html {
70     my($self, $entry) = @_;
71     my $uri = URI->new($self->plugin->conf->{link});
72
73     my $args = { entry => $entry, feed => $self->{feed} };
74
75     if (my $append = $self->plugin->conf->{append}) {
76         $uri->path( $uri->path . $self->value($append, $args) );
77     }
78
79     if (my $query = $self->plugin->conf->{query}) {
80         if (ref $query) {
81             my @query = map {
82                 ($_ => $self->value($query->{$_}, $args));
83             } sort keys %$query;
84             $uri->query_form(@query);
85         } else {
86             $query = $self->value($query, $args);
87             $uri->query($query);
88         }
89     }
90
91     my $url = HTML::Entities::encode($uri->as_string);
92
93     my $content;
94     if (my $template = $self->plugin->conf->{content_dynamic}) {
95         $content = $self->plugin->templatize(\$template, $args);
96     } else {
97         $content = $self->plugin->conf->{content};
98     }
99
100     return qq(<a href="$url">$content</a>);
101 }
102
103 1;
104 __END__
105
106 =head1 NAME
107
108 Plagger::Plugin::Widget::Simple - Simple widget creation using config
109
110 =head1 SYNOPSIS
111
112   - module: Widget::Simple
113     config:
114       link: http://www.example.com/
115       content_dynamic: "Entry from [% entry.author %]"
116
117 =head1 DESCRIPTION
118
119 Widget::Simple is a plugin that allows you to write your own widget
120 using a simple configuration file.
121
122 =head1 CONFIG
123
124 =over 4
125
126 =item link
127
128   link: http://example.com/add
129
130 URL that the widget links to. Required.
131
132 =item query
133
134   query:
135     version: 4
136     url: $args->{entry}->url
137
138 Query parameter to append to the URL. If the value contains C<$>,
139 it'll be automatically eval()ed. Optional.
140
141 =item content
142
143   content: <img src="http://example.com/img.gif" alt="foo" />
144
145 Content to display in a widget. HTML tags will be displayed as is and
146 thus any HTML meta characters have to be escaped. Required, if you
147 don't use I<content_dynamic>.
148
149 =item content_dynamic
150
151   content_dynamic: "Entry from [% entry.author | html %]"
152
153 If you want to dynamically generate the content of widget, use
154 I<content_dynamic> instead. Value of the content_dynamic is compiled
155 and rendered using Template-Toolkit. Required, if you don't use
156 I<content>.
157
158 =back
159
160 =head1 AUTHOR
161
162 Tatsuhiko Miyagawa
163
164 =head1 SEE ALSO
165
166 L<Plagger>
167
168 =cut
Note: See TracBrowser for help on using the browser.