Latest Tweets Widget - Version 1.0.3

Version Description

  • Added theme filters
  • Added configs for showing replies and RTs
Download this release

Release Info

Developer timwhitlock
Plugin Icon 128x128 Latest Tweets Widget
Version 1.0.3
Comparing to
See all releases

Code changes from version 1.0.2 to 1.0.3

Files changed (2) hide show
  1. latest-tweets.php +109 -49
  2. readme.txt +95 -7
latest-tweets.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: Latest Tweets
4
  Plugin URI: http://wordpress.org/extend/plugins/latest-tweets-widget/
5
  Description: Provides a sidebar widget showing latest tweets - compatible with the new Twitter API 1.1
6
  Author: Tim Whitlock
7
- Version: 1.0.2
8
  Author URI: http://timwhitlock.info/
9
  */
10
 
@@ -14,44 +14,64 @@ Author URI: http://timwhitlock.info/
14
  * Pull latest tweets with some caching of raw data.
15
  * @param string account whose tweets we're pulling
16
  * @param int number of tweets to get and display
 
 
17
  * @return array blocks of html expected by the widget
18
  */
19
- function latest_tweets_render( $screen_name, $count ){
20
- if( ! function_exists('twitter_api_get') ){
21
- require_once dirname(__FILE__).'/lib/twitter-api.php';
22
- }
23
- if( function_exists('apc_fetch') ){
24
- // We could cache the rendered HTML, but this tests the twitter_api cache functions
25
- twitter_api_enable_cache( 300 );
26
- }
27
  try {
28
- // Note that exluding replies means we may get less than $count tweets.
29
- // So we'll get more than we want and trim the result.
30
- $tweets = twitter_api_get('statuses/user_timeline', array (
31
- 'count' => 3 * $count,
32
- 'exclude_replies' => true,
33
- 'include_rts' => false,
34
- 'trim_user' => true,
35
- 'screen_name' => $screen_name,
36
- ) );
 
 
 
 
 
 
 
 
 
37
  if( isset($tweets[$count]) ){
38
  $tweets = array_slice( $tweets, 0, $count );
39
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  }
41
  catch( Exception $Ex ){
42
- return array( '<p><strong>Error:</strong> '.esc_html($Ex->getMessage()).'</p>' );
43
  }
44
- // render each tweet as a blocks of html for the widget list items
45
- twitter_api_include('utils');
46
- $rendered = array();
47
- foreach( $tweets as $tweet ){
48
- extract( $tweet );
49
- $link = esc_html( 'http://twitter.com/'.$screen_name.'/status/'.$id_str);
50
- $date = esc_html( twitter_api_relative_date($created_at) );
51
- $rendered[] = '<p class="text">'.twitter_api_html($text).'</p>'.
52
- '<p class="details"><a href="'.$link.'" target="_blank"><time datetime="'.$created_at.'">'.$date.'</time></a></p>';
53
- }
54
- return $rendered;
55
  }
56
 
57
 
@@ -67,48 +87,88 @@ class Latest_Tweets_Widget extends WP_Widget {
67
  $this->options = array(
68
  array (
69
  'name' => 'title',
70
- 'label' => 'Widget title',
71
  'type' => 'text'
72
  ),
73
  array (
74
  'name' => 'screen_name',
75
- 'label' => 'Twitter handle',
76
  'type' => 'text'
77
  ),
78
  array (
79
  'name' => 'num',
80
- 'label' => 'Number of tweets',
81
  'type' => 'text'
82
  ),
 
 
 
 
 
 
 
 
 
 
83
  );
84
  parent::__construct( $id_base, $name, $widget_options, $control_options );
85
  }
86
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
  /** @see WP_Widget::form */
88
  public function form( $instance ) {
89
- if ( empty($instance) ) {
90
- $instance['title'] = 'Latest Tweets';
91
- $instance['screen_name'] = '';
92
- $instance['num'] = '5';
93
- }
94
  foreach ( $this->options as $val ) {
95
- $label = '<label for="'.$this->get_field_id($val['name']).'">'.$val['label'].'</label>';
96
- echo '<p>'.$label.'<br />';
97
- echo '<input class="widefat" id="'.$this->get_field_id($val['name']).'" name="'.$this->get_field_name($val['name']).'" type="text" value="'.esc_attr($instance[$val['name']]).'" /></p>';
 
 
 
 
 
 
 
 
 
98
  }
99
  }
100
 
101
  /** @see WP_Widget::widget */
102
  public function widget( array $args, $instance ) {
103
- $title = apply_filters('widget_title', $instance['title']);
104
- echo $args['before_widget'], '<div class="latest-tweets">';
105
- echo $args['before_title'], $instance['title'], $args['after_title'];
106
- echo '<ul class="latest-tweets">';
107
- foreach( latest_tweets_render( $instance['screen_name'], $instance['num'] ) as $tweet ){
108
- echo '<li class="latest-tweet">',$tweet,'</li>';
 
 
109
  }
110
- echo '</ul>';
111
- echo '</div>',$args['after_widget'];
 
 
 
 
 
 
 
 
112
  }
113
 
114
  }
4
  Plugin URI: http://wordpress.org/extend/plugins/latest-tweets-widget/
5
  Description: Provides a sidebar widget showing latest tweets - compatible with the new Twitter API 1.1
6
  Author: Tim Whitlock
7
+ Version: 1.0.3
8
  Author URI: http://timwhitlock.info/
9
  */
10
 
14
  * Pull latest tweets with some caching of raw data.
15
  * @param string account whose tweets we're pulling
16
  * @param int number of tweets to get and display
17
+ * @param bool whether to show retweets
18
+ * @param bool whether to show at replies
19
  * @return array blocks of html expected by the widget
20
  */
21
+ function latest_tweets_render( $screen_name, $count, $rts, $ats ){
 
 
 
 
 
 
 
22
  try {
23
+ if( ! function_exists('twitter_api_get') ){
24
+ require_once dirname(__FILE__).'/lib/twitter-api.php';
25
+ }
26
+ if( function_exists('apc_fetch') ){
27
+ // We could cache the rendered HTML right here, but this keeps caching abstracted in library
28
+ twitter_api_enable_cache( 300 );
29
+ }
30
+ // Build API params for "statuses/user_timeline" // https://dev.twitter.com/docs/api/1.1/get/statuses/user_timeline
31
+ $trim_user = true;
32
+ $include_rts = ! empty($rts);
33
+ $exclude_replies = empty($ats);
34
+ $params = compact('count','exclude_replies','include_rts','trim_user','screen_name');
35
+ if( $exclude_replies || ! $include_rts ){
36
+ // Stripping tweets means we may get less than $count tweets.
37
+ // there is no good way around this other than fetch extra and hope for the best
38
+ $params['count'] *= 3;
39
+ }
40
+ $tweets = twitter_api_get('statuses/user_timeline', $params );
41
  if( isset($tweets[$count]) ){
42
  $tweets = array_slice( $tweets, 0, $count );
43
  }
44
+ // render each tweet as a blocks of html for the widget list items
45
+ $rendered = array();
46
+ foreach( $tweets as $tweet ){
47
+ extract( $tweet );
48
+ $link = esc_html( 'http://twitter.com/'.$screen_name.'/status/'.$id_str);
49
+ // render nice datetime, unless theme overrides with filter
50
+ $date = apply_filters( 'latest_tweets_render_date', $created_at );
51
+ if( $date === $created_at ){
52
+ function_exists('twitter_api_relative_date') or twitter_api_include('utils');
53
+ $date = esc_html( twitter_api_relative_date($created_at) );
54
+ $date = '<time datetime="'.$created_at.'">'.$date.'</time>';
55
+ }
56
+ // render and linkify tweet, unless theme overrides with filter
57
+ $html = apply_filters('latest_tweets_render_text', $text );
58
+ if( $html === $text ){
59
+ function_exists('twitter_api_html') or twitter_api_include('utils');
60
+ $html = twitter_api_html( $text );
61
+ }
62
+ // piece together the whole tweet, allowing overide
63
+ $final = apply_filters('latest_tweets_render_tweet', $html, $date, $link );
64
+ if( $final === $html ){
65
+ $final = '<p class="tweet-text">'.$html.'</p>'.
66
+ '<p class="tweet-details"><a href="'.$link.'" target="_blank">'.$date.'</a></p>';
67
+ }
68
+ $rendered[] = $final;
69
+ }
70
+ return $rendered;
71
  }
72
  catch( Exception $Ex ){
73
+ return array( '<p class="tweet-text"><strong>Error:</strong> '.esc_html($Ex->getMessage()).'</p>' );
74
  }
 
 
 
 
 
 
 
 
 
 
 
75
  }
76
 
77
 
87
  $this->options = array(
88
  array (
89
  'name' => 'title',
90
+ 'label' => __('Widget title'),
91
  'type' => 'text'
92
  ),
93
  array (
94
  'name' => 'screen_name',
95
+ 'label' => __('Twitter handle'),
96
  'type' => 'text'
97
  ),
98
  array (
99
  'name' => 'num',
100
+ 'label' => __('Number of tweets'),
101
  'type' => 'text'
102
  ),
103
+ array (
104
+ 'name' => 'rts',
105
+ 'label' => __('Show Retweets'),
106
+ 'type' => 'bool'
107
+ ),
108
+ array (
109
+ 'name' => 'ats',
110
+ 'label' => __('Show Replies'),
111
+ 'type' => 'bool'
112
+ ),
113
  );
114
  parent::__construct( $id_base, $name, $widget_options, $control_options );
115
  }
116
 
117
+ /* ensure no missing keys in instance params */
118
+ private function check_instance( $instance ){
119
+ if( ! is_array($instance) ){
120
+ $instance = array();
121
+ }
122
+ $instance += array (
123
+ 'title' => __('Latest Tweets'),
124
+ 'screen_name' => '',
125
+ 'num' => '5',
126
+ 'rts' => '',
127
+ 'ats' => '',
128
+ );
129
+ return $instance;
130
+ }
131
+
132
  /** @see WP_Widget::form */
133
  public function form( $instance ) {
134
+ $instance = $this->check_instance( $instance );
 
 
 
 
135
  foreach ( $this->options as $val ) {
136
+ $elmid = $this->get_field_id( $val['name'] );
137
+ $fname = $this->get_field_name($val['name']);
138
+ $value = isset($instance[ $val['name'] ]) ? $instance[ $val['name'] ] : '';
139
+ $label = '<label for="'.$elmid.'">'.$val['label'].'</label>';
140
+ if( 'bool' === $val['type'] ){
141
+ $checked = $value ? ' checked="checked"' : '';
142
+ echo '<p><input type="checkbox" value="1" id="'.$elmid.'" name="'.$fname.'"'.$checked.' /> '.$label.'</p>';
143
+ }
144
+ else {
145
+ $attrs = '';
146
+ echo '<p>'.$label.'<br /><input class="widefat" type="text" value="'.esc_attr($value).'" id="'.$elmid.'" name="'.$fname.'" /></p>';
147
+ }
148
  }
149
  }
150
 
151
  /** @see WP_Widget::widget */
152
  public function widget( array $args, $instance ) {
153
+ extract( $this->check_instance($instance) );
154
+ // title is themed via Wordpress widget theming techniques
155
+ $title = $args['before_title'] . apply_filters('widget_title', $title) . $args['after_title'];
156
+ // by default tweets are rendered as an unordered list
157
+ $items = latest_tweets_render( $screen_name, $num, $rts, $ats );
158
+ $list = apply_filters('latest_tweets_render_list', $items );
159
+ if( is_array($list) ){
160
+ $list = '<ul><li>'.implode('</li><li>',$items).'</li></ul>';
161
  }
162
+ // output widget applying filters to each element
163
+ echo
164
+ $args['before_widget'],
165
+ '<div class="latest-tweets">',
166
+ $title,
167
+ apply_filters( 'latest_tweets_render_before', '' ),
168
+ $list,
169
+ apply_filters( 'latest_tweets_render_after', '' ),
170
+ '</div>',
171
+ $args['after_widget'];
172
  }
173
 
174
  }
readme.txt CHANGED
@@ -4,21 +4,23 @@ Donate link: http://timwhitlock.info/donate-to-a-project/
4
  Tags: twitter, tweets, oauth, api, rest, api, widget, sidebar
5
  Requires at least: 3.5.1
6
  Tested up to: 3.5.1
7
- Stable tag: trunk
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
11
- Latest Tweets widget, compatible with the new Twitter API 1.1
12
 
13
  == Description ==
14
 
15
  Connect your Twitter account to this plugin and the widget will display your latest tweets on your site.
16
 
17
- This plugin is compatible with the new Twitter API 1.1 and provides full authentication via the Wordpress admin area.
18
-
19
 
20
  Built by [timwhitlock](https://twitter.com/timwhitlock)
21
 
 
 
22
 
23
  == Installation ==
24
 
@@ -39,19 +41,105 @@ Once your site is authenticated you can configure the widget as follows:
39
  9. Drag 'Latest Tweets' from 'Available widgets' to where you want it. e.g. Main Sidebar
40
  10. Optionally configure the widget title and number of tweets to display.
41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
  == Changelog ==
44
 
45
- = 1.0.1 =
46
- * First public release
 
47
 
48
  = 1.0.2 =
49
  * Fixed hook for PHP < 5.3
50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  == Credits ==
52
 
53
  Screenshot taken with permission from http://stayingalivefoundation.org/blog
54
 
55
  == Notes ==
56
 
57
- Be aware of [Twitter's display requirements](https://dev.twitter.com/terms/display-requirements) when rendering tweets on your website.
 
4
  Tags: twitter, tweets, oauth, api, rest, api, widget, sidebar
5
  Requires at least: 3.5.1
6
  Tested up to: 3.5.1
7
+ Stable tag: 1.0.3
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
11
+ Latest Tweets widget compatible with the new Twitter API 1.1
12
 
13
  == Description ==
14
 
15
  Connect your Twitter account to this plugin and the widget will display your latest tweets on your site.
16
 
17
+ This plugin is compatible with the new **Twitter API 1.1** and provides full **OAuth** authentication via the Wordpress admin area.
18
+
19
 
20
  Built by [timwhitlock](https://twitter.com/timwhitlock)
21
 
22
+ The underlying Twitter API library is [available on Github](https://github.com/timwhitlock/wp-twitter-api)
23
+
24
 
25
  == Installation ==
26
 
41
  9. Drag 'Latest Tweets' from 'Available widgets' to where you want it. e.g. Main Sidebar
42
  10. Optionally configure the widget title and number of tweets to display.
43
 
44
+ == Frequently Asked Questions ==
45
+
46
+ = How can I style the widget? =
47
+
48
+ See the 'Other Notes' tab for theming information.
49
+
50
+ = How I do know what my OAuth settings are? =
51
+
52
+ These details are available in the [Twitter dashboard](https://dev.twitter.com/apps)
53
+
54
+ = What do I put in the third and fourth fields? =
55
+
56
+ Once you've populated the first two fields, just click the *Connect* button and follow the prompts.
57
+
58
+
59
 
60
  == Changelog ==
61
 
62
+ = 1.0.3 =
63
+ * Added theme filters
64
+ * Added configs for showing replies and RTs
65
 
66
  = 1.0.2 =
67
  * Fixed hook for PHP < 5.3
68
 
69
+ = 1.0.1 =
70
+ * First public release
71
+
72
+ == Theming ==
73
+
74
+ For starters you can alter some of the HTML using built-in WordPress features.
75
+ See [Widget Filters](http://codex.wordpress.org/Plugin_API/Filter_Reference#Widgets)
76
+ and [Widgetizing Themes](http://codex.wordpress.org/Widgetizing_Themes)
77
+
78
+ **CSS**
79
+
80
+ This plugin contains no default CSS. That's deliberate, so you can style it how you want.
81
+
82
+ Tweets are rendered as a list which has various hooks you can use. Here's a rough template:
83
+
84
+ .latest-tweets {
85
+ /* style tweet list wrapper */
86
+ }
87
+ .latest-tweets h3 {
88
+ /* style whatever you did with the header */
89
+ }
90
+ .latest-tweets ul {
91
+ /* style tweet list*/
92
+ }
93
+ .latest-tweets li {
94
+ /* style tweet item */
95
+ }
96
+ .latest-tweets .tweet-text {
97
+ /* style main tweet text */
98
+ }
99
+ .latest-tweets .tweet-text a {
100
+ /* style links, hashtags and mentions */
101
+ }
102
+ .latest-tweets .tweet-details {
103
+ /* style datetime and link under tweet */
104
+ }
105
+
106
+
107
+ **Custom HTML**
108
+
109
+ If you want to override the default markup of the tweets, the following filters are also available:
110
+
111
+ * Add a header between the widget title and the tweets with `latest_tweets_render_before`
112
+ * Perform your own rendering of the timestamp with `latest_tweets_render_date`
113
+ * Render plain tweet text to your own HTML with `latest_tweets_render_text`
114
+ * Render each composite tweet with `latest_tweets_render_tweet`
115
+ * Override the unordered list for tweets with `latest_tweets_render_list`
116
+ * Add a footer before the end of the widget with `latest_tweets_render_after`
117
+
118
+ Here's an **example** of using some of the above in tour theme's functions.php file:
119
+
120
+ add_filter('latest_tweets_render_date', function( $created_at ){
121
+ $date = DateTime::createFromFormat('D M d H:i:s O Y', $created_at );
122
+ return $date->format('d M h:ia');
123
+ }, 10 , 1 );
124
+
125
+ add_filter('latest_tweets_render_text', function( $text ){
126
+ return $text; // <- will use default
127
+ }, 10 , 1 );
128
+
129
+ add_filter('latest_tweets_render_tweet', function( $html, $date, $link ){
130
+ return '<p class="my-tweet">'.$html.'</p><p class="my-date"><a href="'.$link.'">'.$date.'</a></p>';
131
+ }, 10, 3 );
132
+
133
+ add_filter('latest_tweets_render_after', function(){
134
+ return '<footer><a href="https://twitter.com/me">More from me</a></footer>';
135
+ }, 10, 0 );
136
+
137
+
138
  == Credits ==
139
 
140
  Screenshot taken with permission from http://stayingalivefoundation.org/blog
141
 
142
  == Notes ==
143
 
144
+ Be aware of [Twitter's display requirements](https://dev.twitter.com/terms/display-requirements) when rendering tweets on your website.
145
+