Features by WooThemes - Version 1.0.0

Version Description

  • Initial release. Woo!

=

Download this release

Release Info

Developer woothemes
Plugin Icon wp plugin Features by WooThemes
Version 1.0.0
Comparing to
See all releases

Version 1.0.0

assets/css/admin.css ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #menu-posts-feature .wp-menu-image {
2
+ background: none;
3
+ background-image: url(../images/features-icon.png);
4
+ background-position: 7px -132px !important;
5
+ background-repeat: no-repeat;
6
+ }
7
+ #menu-posts-feature.wp-menu-open .wp-menu-image,
8
+ #menu-posts-feature:hover .wp-menu-image {
9
+ background-position: 7px -164px !important;
10
+ }
11
+ #icon-edit.icon32-posts-feature {
12
+ background: transparent url(../images/features-icon.png) no-repeat left top;
13
+ }
14
+ @media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2) {
15
+ #menu-posts-feature .wp-menu-image {
16
+ background-image: url(../images/features-icon@x2.png);
17
+ background-size: 32px 187px;
18
+ }
19
+ #icon-edit.icon32-posts-feature {
20
+ background-image: url(../images/features-icon@x2.png);
21
+ background-size: 32px 187px;
22
+ }
23
+ }
assets/css/admin.less ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Features icon
2
+ #menu-posts-feature {
3
+ .wp-menu-image {
4
+ background: none;
5
+ background-image: url(../images/features-icon.png);
6
+ background-position: 7px -132px !important;
7
+ background-repeat: no-repeat;
8
+ }
9
+ }
10
+
11
+ #menu-posts-feature.wp-menu-open, #menu-posts-feature:hover {
12
+ .wp-menu-image {
13
+ background-position: 7px -164px !important;
14
+ }
15
+ }
16
+
17
+ #icon-edit.icon32-posts-feature {
18
+ background: transparent url(../images/features-icon.png) no-repeat left top;
19
+ }
20
+
21
+ // Retina
22
+ @media only screen and (-webkit-min-device-pixel-ratio: 2),
23
+ only screen and ( min--moz-device-pixel-ratio: 2),
24
+ only screen and ( -o-min-device-pixel-ratio: 2/1),
25
+ only screen and ( min-device-pixel-ratio: 2),
26
+ {
27
+ #menu-posts-feature {
28
+ .wp-menu-image {
29
+ background-image: url(../images/features-icon@x2.png);
30
+ background-size: 32px 187px;
31
+ }
32
+ }
33
+ #icon-edit.icon32-posts-feature {
34
+ background-image: url(../images/features-icon@x2.png);
35
+ background-size: 32px 187px;
36
+ }
37
+ }
assets/images/features-icon.png ADDED
Binary file
assets/images/features-icon@x2.png ADDED
Binary file
classes/class-woothemes-features.php ADDED
@@ -0,0 +1,374 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly.
3
+
4
+ /**
5
+ * WooThemes Features Class
6
+ *
7
+ * All functionality pertaining to the Features feature.
8
+ *
9
+ * @package WordPress
10
+ * @subpackage WooThemes_Features
11
+ * @category Plugin
12
+ * @author Matty
13
+ * @since 1.0.0
14
+ */
15
+ class Woothemes_Features {
16
+ private $dir;
17
+ private $assets_dir;
18
+ private $assets_url;
19
+ private $token;
20
+ public $version;
21
+ private $file;
22
+
23
+ /**
24
+ * Constructor function.
25
+ *
26
+ * @access public
27
+ * @since 1.0.0
28
+ * @return void
29
+ */
30
+ public function __construct( $file ) {
31
+ $this->dir = dirname( $file );
32
+ $this->file = $file;
33
+ $this->assets_dir = trailingslashit( $this->dir ) . 'assets';
34
+ $this->assets_url = esc_url( str_replace( WP_PLUGIN_DIR, WP_PLUGIN_URL, $this->assets_dir ) );
35
+ $this->token = 'feature';
36
+
37
+ $this->load_plugin_textdomain();
38
+ add_action( 'init', array( &$this, 'load_localisation' ), 0 );
39
+
40
+ // Run this on activation.
41
+ register_activation_hook( $this->file, array( &$this, 'activation' ) );
42
+
43
+ add_action( 'init', array( &$this, 'register_post_type' ) );
44
+
45
+ if ( is_admin() ) {
46
+ global $pagenow;
47
+
48
+ add_filter( 'enter_title_here', array( &$this, 'enter_title_here' ) );
49
+ add_action( 'admin_print_styles', array( &$this, 'enqueue_admin_styles' ), 10 );
50
+ add_filter( 'post_updated_messages', array( &$this, 'updated_messages' ) );
51
+
52
+ if ( $pagenow == 'edit.php' && isset( $_GET['post_type'] ) && esc_attr( $_GET['post_type'] ) == $this->token ) {
53
+ add_filter( 'manage_edit-' . $this->token . '_columns', array( &$this, 'register_custom_column_headings' ), 10, 1 );
54
+ add_action( 'manage_posts_custom_column', array( &$this, 'register_custom_columns' ), 10, 2 );
55
+ }
56
+ }
57
+
58
+ add_action( 'after_setup_theme', array( &$this, 'ensure_post_thumbnails_support' ) );
59
+ add_action( 'after_theme_setup', array( &$this, 'register_image_sizes' ) );
60
+ } // End __construct()
61
+
62
+ /**
63
+ * Register the post type.
64
+ *
65
+ * @access public
66
+ * @param string $token
67
+ * @param string 'Testimonial'
68
+ * @param string 'Testimonials'
69
+ * @param array $supports
70
+ * @return void
71
+ */
72
+ public function register_post_type () {
73
+ $labels = array(
74
+ 'name' => _x( 'Features', 'post type general name', 'woothemes-features' ),
75
+ 'singular_name' => _x( 'Feature', 'post type singular name', 'woothemes-features' ),
76
+ 'add_new' => _x( 'Add New', 'feature', 'woothemes-features' ),
77
+ 'add_new_item' => sprintf( __( 'Add New %s', 'woothemes-features' ), __( 'Feature', 'woothemes-features' ) ),
78
+ 'edit_item' => sprintf( __( 'Edit %s', 'woothemes-features' ), __( 'Feature', 'woothemes-features' ) ),
79
+ 'new_item' => sprintf( __( 'New %s', 'woothemes-features' ), __( 'Feature', 'woothemes-features' ) ),
80
+ 'all_items' => sprintf( __( 'All %s', 'woothemes-features' ), __( 'Features', 'woothemes-features' ) ),
81
+ 'view_item' => sprintf( __( 'View %s', 'woothemes-features' ), __( 'Testimonial', 'woothemes-features' ) ),
82
+ 'search_items' => sprintf( __( 'Search %a', 'woothemes-features' ), __( 'Features', 'woothemes-features' ) ),
83
+ 'not_found' => sprintf( __( 'No %s Found', 'woothemes-features' ), __( 'Features', 'woothemes-features' ) ),
84
+ 'not_found_in_trash' => sprintf( __( 'No %s Found In Trash', 'woothemes-features' ), __( 'Features', 'woothemes-features' ) ),
85
+ 'parent_item_colon' => '',
86
+ 'menu_name' => __( 'Features', 'woothemes-features' )
87
+
88
+ );
89
+ $args = array(
90
+ 'labels' => $labels,
91
+ 'public' => true,
92
+ 'publicly_queryable' => true,
93
+ 'show_ui' => true,
94
+ 'show_in_menu' => true,
95
+ 'query_var' => true,
96
+ 'rewrite' => array( 'slug' => 'feature' ),
97
+ 'capability_type' => 'post',
98
+ 'has_archive' => array( 'slug' => 'features' ),
99
+ 'hierarchical' => false,
100
+ 'supports' => array( 'title', 'editor', 'thumbnail', 'page-attributes' ),
101
+ 'menu_position' => 5,
102
+ 'menu_icon' => ''
103
+ );
104
+ register_post_type( $this->token, $args );
105
+ } // End register_post_type()
106
+
107
+ /**
108
+ * Add custom columns for the "manage" screen of this post type.
109
+ *
110
+ * @access public
111
+ * @param string $column_name
112
+ * @param int $id
113
+ * @since 1.0.0
114
+ * @return void
115
+ */
116
+ public function register_custom_columns ( $column_name, $id ) {
117
+ global $wpdb, $post;
118
+
119
+ $meta = get_post_custom( $id );
120
+
121
+ switch ( $column_name ) {
122
+
123
+ case 'image':
124
+ $value = '';
125
+
126
+ $value = $this->get_image( $id, 40 );
127
+
128
+ echo $value;
129
+ break;
130
+
131
+ default:
132
+ break;
133
+
134
+ }
135
+ } // End register_custom_columns()
136
+
137
+ /**
138
+ * Add custom column headings for the "manage" screen of this post type.
139
+ *
140
+ * @access public
141
+ * @param array $defaults
142
+ * @since 1.0.0
143
+ * @return void
144
+ */
145
+ public function register_custom_column_headings ( $defaults ) {
146
+ $new_columns = array( 'image' => __( 'Image', 'woothemes-features' ) );
147
+
148
+ $last_item = '';
149
+
150
+ if ( isset( $defaults['date'] ) ) { unset( $defaults['date'] ); }
151
+
152
+ if ( count( $defaults ) > 2 ) {
153
+ $last_item = array_slice( $defaults, -1 );
154
+
155
+ array_pop( $defaults );
156
+ }
157
+ $defaults = array_merge( $defaults, $new_columns );
158
+
159
+ if ( $last_item != '' ) {
160
+ foreach ( $last_item as $k => $v ) {
161
+ $defaults[$k] = $v;
162
+ break;
163
+ }
164
+ }
165
+
166
+ return $defaults;
167
+ } // End register_custom_column_headings()
168
+
169
+ /**
170
+ * Update messages for the post type admin.
171
+ * @since 1.0.0
172
+ * @param array $messages Array of messages for all post types.
173
+ * @return array Modified array.
174
+ */
175
+ public function updated_messages ( $messages ) {
176
+ global $post, $post_ID;
177
+
178
+ $messages[$this->token] = array(
179
+ 0 => '', // Unused. Messages start at index 1.
180
+ 1 => sprintf( __( 'Feature updated. %sView feature%s', 'woothemes-features' ), '<a href="' . esc_url( get_permalink( $post_ID ) ) . '">', '</a>' ),
181
+ 2 => __( 'Custom field updated.', 'woothemes-features' ),
182
+ 3 => __( 'Custom field deleted.', 'woothemes-features' ),
183
+ 4 => __( 'Feature updated.', 'woothemes-features' ),
184
+ /* translators: %s: date and time of the revision */
185
+ 5 => isset($_GET['revision']) ? sprintf( __( 'Feature restored to revision from %s', 'woothemes-features' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
186
+ 6 => sprintf( __( 'Feature published. %sView feature%s', 'woothemes-features' ), '<a href="' . esc_url( get_permalink( $post_ID ) ) . '">', '</a>' ),
187
+ 7 => __('Feature saved.'),
188
+ 8 => sprintf( __( 'Feature submitted. %sPreview feature%s', 'woothemes-features' ), '<a target="_blank" href="' . esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ) . '">', '</a>' ),
189
+ 9 => sprintf( __( 'Feature scheduled for: %1$s. %2$sPreview feature%3$s', 'woothemes-features' ),
190
+ // translators: Publish box date format, see http://php.net/date
191
+ '<strong>' . date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ) . '</strong>', '<a target="_blank" href="' . esc_url( get_permalink($post_ID) ) . '">', '</a>' ),
192
+ 10 => sprintf( __( 'Feature draft updated. %sPreview feature%s', 'woothemes-features' ), '<a target="_blank" href="' . esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ) . '">', '</a>' ),
193
+ );
194
+
195
+ return $messages;
196
+ } // End updated_messages()
197
+
198
+ /**
199
+ * Customise the "Enter title here" text.
200
+ *
201
+ * @access public
202
+ * @since 1.0.0
203
+ * @param string $title
204
+ * @return void
205
+ */
206
+ public function enter_title_here ( $title ) {
207
+ if ( get_post_type() == $this->token ) {
208
+ $title = __( 'Enter the feature title here', 'woothemes-features' );
209
+ }
210
+ return $title;
211
+ } // End enter_title_here()
212
+
213
+ /**
214
+ * Enqueue post type admin CSS.
215
+ *
216
+ * @access public
217
+ * @since 1.0.0
218
+ * @return void
219
+ */
220
+ public function enqueue_admin_styles () {
221
+ wp_register_style( 'woothemes-features-admin', $this->assets_url . '/css/admin.css', array(), '1.0.2' );
222
+ wp_enqueue_style( 'woothemes-features-admin' );
223
+ } // End enqueue_admin_styles()
224
+
225
+ /**
226
+ * Get the image for the given ID.
227
+ * @param int $id Post ID.
228
+ * @param string/array/int $size Image dimension. (default: "feature-thumbnail")
229
+ * @since 1.0.0
230
+ * @return string <img> tag.
231
+ */
232
+ protected function get_image ( $id, $size = 'feature-thumbnail' ) {
233
+ $response = '';
234
+
235
+ if ( has_post_thumbnail( $id ) ) {
236
+ // If not a string or an array, and not an integer, default to 150x9999.
237
+ if ( is_int( $size ) || ( 0 < intval( $size ) ) ) {
238
+ $size = array( intval( $size ), intval( $size ) );
239
+ } elseif ( ! is_string( $size ) && ! is_array( $size ) ) {
240
+ $size = array( 150, 9999 );
241
+ }
242
+ $response = get_the_post_thumbnail( intval( $id ), $size );
243
+ }
244
+
245
+ return $response;
246
+ } // End get_image()
247
+
248
+ /**
249
+ * Register image sizes.
250
+ * @since 1.0.0
251
+ * @return void
252
+ */
253
+ public function register_image_sizes () {
254
+ if ( function_exists( 'add_image_size' ) ) {
255
+ add_image_size( 'feature-thumbnail', 150, 9999 ); // 150 pixels wide (and unlimited height)
256
+ }
257
+ } // End register_image_sizes()
258
+
259
+ /**
260
+ * Get features.
261
+ * @param string/array $args Arguments to be passed to the query.
262
+ * @since 1.0.0
263
+ * @return array/boolean Array if true, boolean if false.
264
+ */
265
+ public function get_features ( $args = '' ) {
266
+ $defaults = array(
267
+ 'limit' => 5,
268
+ 'orderby' => 'menu_order',
269
+ 'order' => 'DESC',
270
+ 'id' => 0
271
+ );
272
+
273
+ $args = wp_parse_args( $args, $defaults );
274
+
275
+ // Allow child themes/plugins to filter here.
276
+ $args = apply_filters( 'woothemes_get_features_args', $args );
277
+
278
+ // The Query Arguments.
279
+ $query_args = array();
280
+ $query_args['post_type'] = 'feature';
281
+ $query_args['numberposts'] = $args['limit'];
282
+ $query_args['orderby'] = $args['orderby'];
283
+ $query_args['order'] = $args['order'];
284
+
285
+ if ( is_numeric( $args['id'] ) && ( intval( $args['id'] ) > 0 ) ) {
286
+ $query_args['p'] = intval( $args['id'] );
287
+ }
288
+
289
+ // Whitelist checks.
290
+ if ( ! in_array( $query_args['orderby'], array( 'none', 'ID', 'author', 'title', 'date', 'modified', 'parent', 'rand', 'comment_count', 'menu_order', 'meta_value', 'meta_value_num' ) ) ) {
291
+ $query_args['orderby'] = 'date';
292
+ }
293
+
294
+ if ( ! in_array( $query_args['order'], array( 'ASC', 'DESC' ) ) ) {
295
+ $query_args['order'] = 'DESC';
296
+ }
297
+
298
+ if ( ! in_array( $query_args['post_type'], get_post_types() ) ) {
299
+ $query_args['post_type'] = 'feature';
300
+ }
301
+
302
+ // The Query.
303
+ $query = get_posts( $query_args );
304
+
305
+ // The Display.
306
+ if ( ! is_wp_error( $query ) && is_array( $query ) && count( $query ) > 0 ) {
307
+ foreach ( $query as $k => $v ) {
308
+ $meta = get_post_custom( $v->ID );
309
+
310
+ // Get the image.
311
+ $query[$k]->image = $this->get_image( $v->ID, $args['size'] );
312
+ }
313
+ } else {
314
+ $query = false;
315
+ }
316
+
317
+ return $query;
318
+ } // End get_features()
319
+
320
+ /**
321
+ * Load the plugin's localisation file.
322
+ * @access public
323
+ * @since 1.0.0
324
+ * @return void
325
+ */
326
+ public function load_localisation () {
327
+ load_plugin_textdomain( 'woothemes-features', false, dirname( plugin_basename( $this->file ) ) . '/lang/' );
328
+ } // End load_localisation()
329
+
330
+ /**
331
+ * Load the plugin textdomain from the main WordPress "languages" folder.
332
+ * @since 1.0.0
333
+ * @return void
334
+ */
335
+ public function load_plugin_textdomain () {
336
+ $domain = 'woothemes-features';
337
+ // The "plugin_locale" filter is also used in load_plugin_textdomain()
338
+ $locale = apply_filters( 'plugin_locale', get_locale(), $domain );
339
+
340
+ load_textdomain( $domain, WP_LANG_DIR . '/' . $domain . '/' . $domain . '-' . $locale . '.mo' );
341
+ load_plugin_textdomain( $domain, FALSE, dirname( plugin_basename( $this->file ) ) . '/lang/' );
342
+ } // End load_plugin_textdomain()
343
+
344
+ /**
345
+ * Run on activation.
346
+ * @access public
347
+ * @since 1.0.0
348
+ * @return void
349
+ */
350
+ public function activation () {
351
+ $this->register_plugin_version();
352
+ } // End activation()
353
+
354
+ /**
355
+ * Register the plugin's version.
356
+ * @access public
357
+ * @since 1.0.0
358
+ * @return void
359
+ */
360
+ private function register_plugin_version () {
361
+ if ( $this->version != '' ) {
362
+ update_option( 'woothemes-features' . '-version', $this->version );
363
+ }
364
+ } // End register_plugin_version()
365
+
366
+ /**
367
+ * Ensure that "post-thumbnails" support is available for those themes that don't register it.
368
+ * @since 1.0.1
369
+ * @return void
370
+ */
371
+ public function ensure_post_thumbnails_support () {
372
+ if ( ! current_theme_supports( 'post-thumbnails' ) ) { add_theme_support( 'post-thumbnails' ); }
373
+ } // End ensure_post_thumbnails_support()
374
+ } // End Class
classes/class-woothemes-widget-features.php ADDED
@@ -0,0 +1,227 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) || ! function_exists( 'woothemes_features' ) ) exit; // Exit if accessed directly.
3
+
4
+ /**
5
+ * WooThemes Features Widget
6
+ *
7
+ * A WooThemes standardized features widget.
8
+ *
9
+ * @package WordPress
10
+ * @subpackage WooThemes_Features
11
+ * @category Widgets
12
+ * @author WooThemes
13
+ * @since 1.0.0
14
+ *
15
+ * TABLE OF CONTENTS
16
+ *
17
+ * protected $woothemes_widget_cssclass
18
+ * protected $woothemes_widget_description
19
+ * protected $woothemes_widget_idbase
20
+ * protected $woothemes_widget_title
21
+ *
22
+ * - __construct()
23
+ * - widget()
24
+ * - update()
25
+ * - form()
26
+ * - get_orderby_options()
27
+ */
28
+ class Woothemes_Widget_Features extends WP_Widget {
29
+ protected $woothemes_widget_cssclass;
30
+ protected $woothemes_widget_description;
31
+ protected $woothemes_widget_idbase;
32
+ protected $woothemes_widget_title;
33
+
34
+ /**
35
+ * Constructor function.
36
+ * @since 1.0.0
37
+ * @return void
38
+ */
39
+ public function __construct() {
40
+ /* Widget variable settings. */
41
+ $this->woothemes_widget_cssclass = 'widget_woothemes_features';
42
+ $this->woothemes_widget_description = __( 'Recent features listed on your site.', 'woothemes-features' );
43
+ $this->woothemes_widget_idbase = 'woothemes_features';
44
+ $this->woothemes_widget_title = __( 'Features', 'woothemes-features' );
45
+
46
+ /* Widget settings. */
47
+ $widget_ops = array( 'classname' => $this->woothemes_widget_cssclass, 'description' => $this->woothemes_widget_description );
48
+
49
+ /* Widget control settings. */
50
+ $control_ops = array( 'width' => 250, 'height' => 350, 'id_base' => $this->woothemes_widget_idbase );
51
+
52
+ /* Create the widget. */
53
+ $this->WP_Widget( $this->woothemes_widget_idbase, $this->woothemes_widget_title, $widget_ops, $control_ops );
54
+ } // End __construct()
55
+
56
+ /**
57
+ * Display the widget on the frontend.
58
+ * @since 1.0.0
59
+ * @param array $args Widget arguments.
60
+ * @param array $instance Widget settings for this instance.
61
+ * @return void
62
+ */
63
+ public function widget( $args, $instance ) {
64
+ extract( $args, EXTR_SKIP );
65
+
66
+ /* Our variables from the widget settings. */
67
+ $title = apply_filters('widget_title', $instance['title'], $instance, $this->id_base );
68
+
69
+ /* Before widget (defined by themes). */
70
+ // echo $before_widget;
71
+
72
+ $args = array();
73
+
74
+ /* Display the widget title if one was input (before and after defined by themes). */
75
+ if ( $title ) { $args['title'] = $title; }
76
+
77
+ /* Widget content. */
78
+ // Add actions for plugins/themes to hook onto.
79
+ do_action( $this->woothemes_widget_cssclass . '_top' );
80
+
81
+ // Integer values.
82
+ if ( isset( $instance['limit'] ) && ( 0 < count( $instance['limit'] ) ) ) { $args['limit'] = intval( $instance['limit'] ); }
83
+ if ( isset( $instance['specific_id'] ) && ( 0 < count( $instance['specific_id'] ) ) ) { $args['id'] = intval( $instance['specific_id'] ); }
84
+ if ( isset( $instance['size'] ) && ( 0 < count( $instance['size'] ) ) ) { $args['size'] = intval( $instance['size'] ); }
85
+ if ( isset( $instance['per_row'] ) && ( 0 < count( $instance['per_row'] ) ) ) { $args['per_row'] = intval( $instance['per_row'] ); }
86
+
87
+ // Select boxes.
88
+ if ( isset( $instance['orderby'] ) && in_array( $instance['orderby'], array_keys( $this->get_orderby_options() ) ) ) { $args['orderby'] = $instance['orderby']; }
89
+ if ( isset( $instance['order'] ) && in_array( $instance['order'], array_keys( $this->get_order_options() ) ) ) { $args['order'] = $instance['order']; }
90
+
91
+ // Display the features.
92
+ woothemes_features( $args );
93
+
94
+ // Add actions for plugins/themes to hook onto.
95
+ do_action( $this->woothemes_widget_cssclass . '_bottom' );
96
+
97
+ /* After widget (defined by themes). */
98
+ // echo $after_widget;
99
+ } // End widget()
100
+
101
+ /**
102
+ * Method to update the settings from the form() method.
103
+ * @since 1.0.0
104
+ * @param array $new_instance New settings.
105
+ * @param array $old_instance Previous settings.
106
+ * @return array Updated settings.
107
+ */
108
+ public function update ( $new_instance, $old_instance ) {
109
+ $instance = $old_instance;
110
+
111
+ /* Strip tags for title and name to remove HTML (important for text inputs). */
112
+ $instance['title'] = strip_tags( $new_instance['title'] );
113
+
114
+ /* Make sure the integer values are definitely integers. */
115
+ $instance['limit'] = intval( $new_instance['limit'] );
116
+ $instance['specific_id'] = intval( $new_instance['specific_id'] );
117
+ $instance['size'] = intval( $new_instance['size'] );
118
+ $instance['per_row'] = intval( $new_instance['per_row'] );
119
+
120
+ /* The select box is returning a text value, so we escape it. */
121
+ $instance['orderby'] = esc_attr( $new_instance['orderby'] );
122
+ $instance['order'] = esc_attr( $new_instance['order'] );
123
+
124
+ return $instance;
125
+ } // End update()
126
+
127
+ /**
128
+ * The form on the widget control in the widget administration area.
129
+ * Make use of the get_field_id() and get_field_name() function when creating your form elements. This handles the confusing stuff.
130
+ * @since 1.0.0
131
+ * @param array $instance The settings for this instance.
132
+ * @return void
133
+ */
134
+ public function form( $instance ) {
135
+
136
+ /* Set up some default widget settings. */
137
+ /* Make sure all keys are added here, even with empty string values. */
138
+ $defaults = array(
139
+ 'title' => '',
140
+ 'limit' => 5,
141
+ 'orderby' => 'menu_order',
142
+ 'order' => 'DESC',
143
+ 'specific_id' => '',
144
+ 'size' => 50,
145
+ 'per_row' => 3
146
+ );
147
+
148
+ $instance = wp_parse_args( (array) $instance, $defaults );
149
+ ?>
150
+ <!-- Widget Title: Text Input -->
151
+ <p>
152
+ <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e( 'Title (optional):', 'woothemes-features' ); ?></label>
153
+ <input type="text" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo $instance['title']; ?>" class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" />
154
+ </p>
155
+ <!-- Widget Limit: Text Input -->
156
+ <p>
157
+ <label for="<?php echo $this->get_field_id( 'limit' ); ?>"><?php _e( 'Limit:', 'woothemes-features' ); ?></label>
158
+ <input type="text" name="<?php echo $this->get_field_name( 'limit' ); ?>" value="<?php echo $instance['limit']; ?>" class="widefat" id="<?php echo $this->get_field_id( 'limit' ); ?>" />
159
+ </p>
160
+ <!-- Widget Image Size: Text Input -->
161
+ <p>
162
+ <label for="<?php echo $this->get_field_id( 'size' ); ?>"><?php _e( 'Image Size (in pixels):', 'woothemes-features' ); ?></label>
163
+ <input type="text" name="<?php echo $this->get_field_name( 'size' ); ?>" value="<?php echo $instance['size']; ?>" class="widefat" id="<?php echo $this->get_field_id( 'size' ); ?>" />
164
+ </p>
165
+ <!-- Widget Per Row: Text Input -->
166
+ <p>
167
+ <label for="<?php echo $this->get_field_id( 'per_row' ); ?>"><?php _e( 'Items Per Row:', 'woothemes-features' ); ?></label>
168
+ <input type="text" name="<?php echo $this->get_field_name( 'per_row' ); ?>" value="<?php echo $instance['per_row']; ?>" class="widefat" id="<?php echo $this->get_field_id( 'per_row' ); ?>" />
169
+ </p>
170
+ <!-- Widget Order By: Select Input -->
171
+ <p>
172
+ <label for="<?php echo $this->get_field_id( 'orderby' ); ?>"><?php _e( 'Order By:', 'woothemes-features' ); ?></label>
173
+ <select name="<?php echo $this->get_field_name( 'orderby' ); ?>" class="widefat" id="<?php echo $this->get_field_id( 'orderby' ); ?>">
174
+ <?php foreach ( $this->get_orderby_options() as $k => $v ) { ?>
175
+ <option value="<?php echo $k; ?>"<?php selected( $instance['orderby'], $k ); ?>><?php echo $v; ?></option>
176
+ <?php } ?>
177
+ </select>
178
+ </p>
179
+ <!-- Widget Order: Select Input -->
180
+ <p>
181
+ <label for="<?php echo $this->get_field_id( 'order' ); ?>"><?php _e( 'Order Direction:', 'woothemes-features' ); ?></label>
182
+ <select name="<?php echo $this->get_field_name( 'order' ); ?>" class="widefat" id="<?php echo $this->get_field_id( 'order' ); ?>">
183
+ <?php foreach ( $this->get_order_options() as $k => $v ) { ?>
184
+ <option value="<?php echo $k; ?>"<?php selected( $instance['order'], $k ); ?>><?php echo $v; ?></option>
185
+ <?php } ?>
186
+ </select>
187
+ </p>
188
+ <!-- Widget ID: Text Input -->
189
+ <p>
190
+ <label for="<?php echo $this->get_field_id( 'specific_id' ); ?>"><?php _e( 'Specific ID (optional):', 'woothemes-features' ); ?></label>
191
+ <input type="text" name="<?php echo $this->get_field_name( 'specific_id' ); ?>" value="<?php echo $instance['specific_id']; ?>" class="widefat" id="<?php echo $this->get_field_id( 'specific_id' ); ?>" />
192
+ </p>
193
+ <p><small><?php _e( 'Display a specific testimonial, rather than a list.', 'woothemes-features' ); ?></small></p>
194
+ <?php
195
+ } // End form()
196
+
197
+ /**
198
+ * Get an array of the available orderby options.
199
+ * @since 1.0.0
200
+ * @return array
201
+ */
202
+ protected function get_orderby_options () {
203
+ return array(
204
+ 'none' => __( 'No Order', 'woothemes-features' ),
205
+ 'ID' => __( 'Entry ID', 'woothemes-features' ),
206
+ 'title' => __( 'Title', 'woothemes-features' ),
207
+ 'date' => __( 'Date Added', 'woothemes-features' ),
208
+ 'menu_order' => __( 'Specified Order Setting', 'woothemes-features' )
209
+ );
210
+ } // End get_orderby_options()
211
+
212
+ /**
213
+ * Get an array of the available order options.
214
+ * @since 1.0.0
215
+ * @return array
216
+ */
217
+ protected function get_order_options () {
218
+ return array(
219
+ 'asc' => __( 'Ascending', 'woothemes-features' ),
220
+ 'desc' => __( 'Descending', 'woothemes-features' )
221
+ );
222
+ } // End get_order_options()
223
+ } // End Class
224
+
225
+ /* Register the widget. */
226
+ add_action( 'widgets_init', create_function( '', 'return register_widget("WooThemes_Widget_Features");' ), 1 );
227
+ ?>
lang/woothemes-features-en_GB.po ADDED
@@ -0,0 +1,256 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: Features v1.0.0\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: \n"
6
+ "PO-Revision-Date: 2012-10-17 12:43:43+0000\n"
7
+ "Last-Translator: Matt <matt@woothemes.com>\n"
8
+ "Language-Team: \n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "Plural-Forms: nplurals=2; plural=n != 1;\n"
13
+ "X-Poedit-Language: English\n"
14
+ "X-Poedit-Country: UNITED KINGDOM\n"
15
+ "X-Poedit-SourceCharset: utf-8\n"
16
+ "X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;\n"
17
+ "X-Poedit-Basepath: ../\n"
18
+ "X-Poedit-Bookmarks: \n"
19
+ "X-Poedit-SearchPath-0: .\n"
20
+ "X-Textdomain-Support: yes"
21
+
22
+ #: classes/class-woothemes-features.php:74
23
+ #@ woothemes-features
24
+ msgctxt "post type general name"
25
+ msgid "Features"
26
+ msgstr ""
27
+
28
+ #: classes/class-woothemes-features.php:75
29
+ #@ woothemes-features
30
+ msgctxt "post type singular name"
31
+ msgid "Feature"
32
+ msgstr ""
33
+
34
+ #: classes/class-woothemes-features.php:76
35
+ #@ woothemes-features
36
+ msgctxt "feature"
37
+ msgid "Add New"
38
+ msgstr ""
39
+
40
+ #: classes/class-woothemes-features.php:77
41
+ #, php-format
42
+ #@ woothemes-features
43
+ msgid "Add New %s"
44
+ msgstr ""
45
+
46
+ #: classes/class-woothemes-features.php:77
47
+ #: classes/class-woothemes-features.php:78
48
+ #: classes/class-woothemes-features.php:79
49
+ #@ woothemes-features
50
+ msgid "Feature"
51
+ msgstr ""
52
+
53
+ #: classes/class-woothemes-features.php:78
54
+ #, php-format
55
+ #@ woothemes-features
56
+ msgid "Edit %s"
57
+ msgstr ""
58
+
59
+ #: classes/class-woothemes-features.php:79
60
+ #, php-format
61
+ #@ woothemes-features
62
+ msgid "New %s"
63
+ msgstr ""
64
+
65
+ #: classes/class-woothemes-features.php:80
66
+ #, php-format
67
+ #@ woothemes-features
68
+ msgid "All %s"
69
+ msgstr ""
70
+
71
+ #: classes/class-woothemes-features.php:80
72
+ #: classes/class-woothemes-features.php:82
73
+ #: classes/class-woothemes-features.php:83
74
+ #: classes/class-woothemes-features.php:84
75
+ #: classes/class-woothemes-features.php:86
76
+ #: classes/class-woothemes-widget-features.php:44
77
+ #@ woothemes-features
78
+ msgid "Features"
79
+ msgstr ""
80
+
81
+ #: classes/class-woothemes-features.php:81
82
+ #, php-format
83
+ #@ woothemes-features
84
+ msgid "View %s"
85
+ msgstr ""
86
+
87
+ #: classes/class-woothemes-features.php:81
88
+ #@ woothemes-features
89
+ msgid "Testimonial"
90
+ msgstr ""
91
+
92
+ #: classes/class-woothemes-features.php:82
93
+ #, php-format
94
+ #@ woothemes-features
95
+ msgid "Search %a"
96
+ msgstr ""
97
+
98
+ #: classes/class-woothemes-features.php:83
99
+ #, php-format
100
+ #@ woothemes-features
101
+ msgid "No %s Found"
102
+ msgstr ""
103
+
104
+ #: classes/class-woothemes-features.php:84
105
+ #, php-format
106
+ #@ woothemes-features
107
+ msgid "No %s Found In Trash"
108
+ msgstr ""
109
+
110
+ #: classes/class-woothemes-features.php:146
111
+ #@ woothemes-features
112
+ msgid "Image"
113
+ msgstr ""
114
+
115
+ #: classes/class-woothemes-features.php:180
116
+ #, php-format
117
+ #@ woothemes-features
118
+ msgid "Feature updated. %sView feature%s"
119
+ msgstr ""
120
+
121
+ #: classes/class-woothemes-features.php:181
122
+ #@ woothemes-features
123
+ msgid "Custom field updated."
124
+ msgstr ""
125
+
126
+ #: classes/class-woothemes-features.php:182
127
+ #@ woothemes-features
128
+ msgid "Custom field deleted."
129
+ msgstr ""
130
+
131
+ #: classes/class-woothemes-features.php:183
132
+ #@ woothemes-features
133
+ msgid "Feature updated."
134
+ msgstr ""
135
+
136
+ #. translators: %s: date and time of the revision
137
+ #: classes/class-woothemes-features.php:185
138
+ #, php-format
139
+ #@ woothemes-features
140
+ msgid "Feature restored to revision from %s"
141
+ msgstr ""
142
+
143
+ #: classes/class-woothemes-features.php:186
144
+ #, php-format
145
+ #@ woothemes-features
146
+ msgid "Feature published. %sView feature%s"
147
+ msgstr ""
148
+
149
+ #: classes/class-woothemes-features.php:187
150
+ #@ default
151
+ msgid "Feature saved."
152
+ msgstr ""
153
+
154
+ #: classes/class-woothemes-features.php:188
155
+ #, php-format
156
+ #@ woothemes-features
157
+ msgid "Feature submitted. %sPreview feature%s"
158
+ msgstr ""
159
+
160
+ #: classes/class-woothemes-features.php:189
161
+ #, php-format
162
+ #@ woothemes-features
163
+ msgid "Feature scheduled for: %1$s. %2$sPreview feature%3$s"
164
+ msgstr ""
165
+
166
+ #: classes/class-woothemes-features.php:191
167
+ #@ default
168
+ msgid "M j, Y @ G:i"
169
+ msgstr ""
170
+
171
+ #: classes/class-woothemes-features.php:192
172
+ #, php-format
173
+ #@ woothemes-features
174
+ msgid "Feature draft updated. %sPreview feature%s"
175
+ msgstr ""
176
+
177
+ #: classes/class-woothemes-features.php:208
178
+ #@ woothemes-features
179
+ msgid "Enter the feature title here"
180
+ msgstr ""
181
+
182
+ #: classes/class-woothemes-widget-features.php:42
183
+ #@ woothemes-features
184
+ msgid "Recent features listed on your site."
185
+ msgstr ""
186
+
187
+ #: classes/class-woothemes-widget-features.php:149
188
+ #@ woothemes-features
189
+ msgid "Title (optional):"
190
+ msgstr ""
191
+
192
+ #: classes/class-woothemes-widget-features.php:154
193
+ #@ woothemes-features
194
+ msgid "Limit:"
195
+ msgstr ""
196
+
197
+ #: classes/class-woothemes-widget-features.php:159
198
+ #@ woothemes-features
199
+ msgid "Image Size (in pixels):"
200
+ msgstr ""
201
+
202
+ #: classes/class-woothemes-widget-features.php:164
203
+ #@ woothemes-features
204
+ msgid "Order By:"
205
+ msgstr ""
206
+
207
+ #: classes/class-woothemes-widget-features.php:173
208
+ #@ woothemes-features
209
+ msgid "Order Direction:"
210
+ msgstr ""
211
+
212
+ #: classes/class-woothemes-widget-features.php:182
213
+ #@ woothemes-features
214
+ msgid "Specific ID (optional):"
215
+ msgstr ""
216
+
217
+ #: classes/class-woothemes-widget-features.php:185
218
+ #@ woothemes-features
219
+ msgid "Display a specific testimonial, rather than a list."
220
+ msgstr ""
221
+
222
+ #: classes/class-woothemes-widget-features.php:196
223
+ #@ woothemes-features
224
+ msgid "No Order"
225
+ msgstr ""
226
+
227
+ #: classes/class-woothemes-widget-features.php:197
228
+ #@ woothemes-features
229
+ msgid "Entry ID"
230
+ msgstr ""
231
+
232
+ #: classes/class-woothemes-widget-features.php:198
233
+ #@ woothemes-features
234
+ msgid "Title"
235
+ msgstr ""
236
+
237
+ #: classes/class-woothemes-widget-features.php:199
238
+ #@ woothemes-features
239
+ msgid "Date Added"
240
+ msgstr ""
241
+
242
+ #: classes/class-woothemes-widget-features.php:200
243
+ #@ woothemes-features
244
+ msgid "Specified Order Setting"
245
+ msgstr ""
246
+
247
+ #: classes/class-woothemes-widget-features.php:211
248
+ #@ woothemes-features
249
+ msgid "Ascending"
250
+ msgstr ""
251
+
252
+ #: classes/class-woothemes-widget-features.php:212
253
+ #@ woothemes-features
254
+ msgid "Descending"
255
+ msgstr ""
256
+
lang/woothemes-features-xx_XX.pot ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ msgid ""
2
+ msgstr ""
3
+ "Project-Id-Version: PlaceHolder\n"
4
+ "Report-Msgid-Bugs-To: \n"
5
+ "POT-Creation-Date: \n"
6
+ "PO-Revision-Date: 2012-10-17 12:43:24+0000\n"
7
+ "Last-Translator: none\n"
8
+ "Language-Team: \n"
9
+ "MIME-Version: 1.0\n"
10
+ "Content-Type: text/plain; charset=UTF-8\n"
11
+ "Content-Transfer-Encoding: 8bit\n"
12
+ "Plural-Forms: nplurals=2; plural=n != 1;\n"
13
+ "X-Poedit-Language: English\n"
14
+ "X-Poedit-Country: UNITED STATES\n"
15
+ "X-Poedit-SourceCharset: utf-8\n"
16
+ "X-Poedit-KeywordsList: __;_e;__ngettext:1,2;_n:1,2;__ngettext_noop:1,2;_n_noop:1,2;_c,_nc:4c,1,2;_x:1,2c;_ex:1,2c;_nx:4c,1,2;_nx_noop:4c,1,2;\n"
17
+ "X-Poedit-Basepath: ../\n"
18
+ "X-Poedit-Bookmarks: \n"
19
+ "X-Poedit-SearchPath-0: .\n"
20
+ "X-Textdomain-Support: yes"
21
+
readme.txt ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Features by WooThemes ===
2
+ Contributors: woothemes, mattyza, jameskoster
3
+ Donate link: http://woothemes.com/
4
+ Tags: features, widget, shortcode, template-tag, services
5
+ Requires at least: 3.4.2
6
+ Tested up to: 3.5-beta2
7
+ Stable tag: 1.0.0
8
+ License: GPLv2 or later
9
+ License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
+
11
+ Show off what features your company, product or service offers, using our shortcode, widget or template tag.
12
+
13
+ == Description ==
14
+
15
+ "Features by WooThemes" is a clean and easy-to-use features showcase management system for WordPress. Load in the features your product, company or services offers, and display them via a shortcode, widget or template tag on your website.
16
+
17
+ === Usage ===
18
+
19
+ To display your features via a theme or a custom plugin, please use the following code:
20
+
21
+ `<?php do_action( 'woothemes_features' ); ?>`
22
+
23
+ To add arguments to this, please use any of the following arguments, using the syntax provided below:
24
+
25
+ * 'limit' => 5 (the maximum number of items to display)
26
+ * 'orderby' => 'menu_order' (how to order the items - accepts all default WordPress ordering options)
27
+ * 'order' => 'DESC' (the order direction)
28
+ * 'id' => 0 (display a specific item)
29
+ * 'echo' => true (whether to display or return the data - useful with the template tag)
30
+ * 'size' => 50 (the pixel dimensions of the image)
31
+ * 'per_row' => 3 (when creating rows, how many items display in a single row?)
32
+ * 'link_title' => true (link the feature's title to it's permalink)
33
+ * 'title' => '' (an optional title)
34
+
35
+ `<?php do_action( 'woothemes_features', array( 'limit' => 10, 'link_title' => false ) ); ?>`
36
+
37
+ The same arguments apply to the shortcode which is `[woothemes_features]` and the template tag, which is `<?php woothemes_features(); ?>`.
38
+
39
+ == Installation ==
40
+
41
+ Installing "Features by WooThemes" can be done either by searching for "Features by WooThemes" via the "Plugins > Add New" screen in your WordPress dashboard, or by using the following steps:
42
+
43
+ 1. Download the plugin via WordPress.org.
44
+ 1. Upload the ZIP file through the "Plugins > Add New > Upload" screen in your WordPress dashboard.
45
+ 1. Activate the plugin through the 'Plugins' menu in WordPress
46
+ 1. Place `<?php do_action( 'woothemes_features' ); ?>` in your templates, or use the provided widget or shortcode.
47
+
48
+ == Frequently Asked Questions ==
49
+
50
+ = The plugin looks unstyled when I activate it. Why is this? =
51
+
52
+ "Features by WooThemes" is a lean plugin that aims to keep it's purpose as clean and clear as possible. Thus, we don't load any preset CSS styling, to allow full control over the styling within your theme or child theme.
53
+
54
+ = How do I contribute? =
55
+
56
+ We encourage everyone to contribute their ideas, thoughts and code snippets. This can be done by forking the [repository over at GitHub](http://github.com/woothemes/features/).
57
+
58
+ == Screenshots ==
59
+
60
+ 1. The features management screen within the WordPress admin.
61
+
62
+ == Upgrade Notice ==
63
+
64
+ = 1.0.0 =
65
+ * Initial release. Woo!
66
+
67
+ == Changelog ==
68
+
69
+ = 1.0.0 =
70
+ * Initial release. Woo!
woothemes-features-template.php ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ if ( ! defined( 'ABSPATH' ) ) exit;
3
+
4
+ if ( ! function_exists( 'woothemes_get_features' ) ) {
5
+ /**
6
+ * Wrapper function to get the testimonials from the WooDojo_Testimonials class.
7
+ * @param string/array $args Arguments.
8
+ * @since 1.0.0
9
+ * @return array/boolean Array if true, boolean if false.
10
+ */
11
+ function woothemes_get_features ( $args = '' ) {
12
+ global $woothemes_features;
13
+ return $woothemes_features->get_features( $args );
14
+ } // End woothemes_get_features()
15
+ }
16
+
17
+ /**
18
+ * Enable the usage of do_action( 'woothemes_features' ) to display features within a theme/plugin.
19
+ *
20
+ * @since 1.0.0
21
+ */
22
+ add_action( 'woothemes_features', 'woothemes_features' );
23
+
24
+ if ( ! function_exists( 'woothemes_features' ) ) {
25
+ /**
26
+ * Display or return HTML-formatted testimonials.
27
+ * @param string/array $args Arguments.
28
+ * @since 1.0.0
29
+ * @return string
30
+ */
31
+ function woothemes_features ( $args = '' ) {
32
+ global $post;
33
+
34
+ $defaults = array(
35
+ 'limit' => 5,
36
+ 'orderby' => 'menu_order',
37
+ 'order' => 'DESC',
38
+ 'id' => 0,
39
+ 'echo' => true,
40
+ 'size' => 50,
41
+ 'per_row' => 3,
42
+ 'link_title' => true,
43
+ 'title' => ''
44
+ );
45
+
46
+ $args = wp_parse_args( $args, $defaults );
47
+
48
+ // Allow child themes/plugins to filter here.
49
+ $args = apply_filters( 'woothemes_features_args', $args );
50
+ $html = '';
51
+
52
+ do_action( 'woothemes_features_before', $args );
53
+
54
+ // The Query.
55
+ $query = woothemes_get_features( $args );
56
+
57
+ // The Display.
58
+ if ( ! is_wp_error( $query ) && is_array( $query ) && count( $query ) > 0 ) {
59
+ $html .= '<div class="widget widget_woothemes_features">' . "\n";
60
+ $html .= '<div class="features">' . "\n";
61
+
62
+ if ( '' != $args['title'] ) {
63
+ $html .= '<h2>' . esc_html( $args['title'] ) . '</h2>' . "\n";
64
+ }
65
+
66
+ // Begin templating logic.
67
+ $tpl = '<div class="%%CLASS%%">%%IMAGE%%<h3 class="feature-title">%%TITLE%%</h3><div class="feature-content">%%CONTENT%%</div></div>';
68
+ $tpl = apply_filters( 'woothemes_features_item_template', $tpl, $args );
69
+
70
+ $i = 0;
71
+ foreach ( $query as $post ) {
72
+ $template = $tpl;
73
+ $i++;
74
+
75
+ setup_postdata( $post );
76
+
77
+ $class = 'feature';
78
+
79
+ if ( count( $query ) == $i || ( 0 == $i % $args['per_row'] ) ) {
80
+ $class .= ' last';
81
+ } elseif ( 0 == ( $i - 1 ) % $args['per_row'] && count( $query ) != $i ) {
82
+ $class .= ' first';
83
+ }
84
+
85
+
86
+ $title = get_the_title();
87
+ if ( true == $args['link_title'] ) {
88
+ $title = '<a href="' . esc_url( get_permalink( get_the_ID() ) ) . '" title="' . esc_attr( $title ) . '">' . $title . '</a>';
89
+ }
90
+
91
+ // Optionally display the image, if it is available.
92
+ if ( isset( $post->image ) && ( '' != $post->image ) ) {
93
+ $template = str_replace( '%%IMAGE%%', $post->image, $template );
94
+ } else {
95
+ $template = str_replace( '%%IMAGE%%', '', $template );
96
+ }
97
+
98
+ $template = str_replace( '%%CLASS%%', $class, $template );
99
+ $template = str_replace( '%%TITLE%%', $title, $template );
100
+ $template = str_replace( '%%CONTENT%%', get_the_content(), $template );
101
+
102
+ $html .= $template;
103
+
104
+ if( ( 0 == $i % $args['per_row'] ) ) {
105
+ $html .= '<div class="fix"></div>' . "\n";
106
+ }
107
+ }
108
+
109
+ $html .= '</div><!--/.features-->' . "\n";
110
+ $html .= '</div><!--/.widget widget_woothemes_features-->' . "\n";
111
+
112
+ wp_reset_postdata();
113
+ }
114
+
115
+ // Allow child themes/plugins to filter here.
116
+ $html = apply_filters( 'woothemes_features_html', $html, $query, $args );
117
+
118
+ if ( $args['echo'] != true ) { return $html; }
119
+
120
+ // Should only run is "echo" is set to true.
121
+ echo $html;
122
+
123
+ do_action( 'woothemes_features_after', $args ); // Only if "echo" is set to true.
124
+ } // End woothemes_features()
125
+ }
126
+
127
+ if ( ! function_exists( 'woothemes_features_shortcode' ) ) {
128
+ function woothemes_features_shortcode ( $atts, $content = null ) {
129
+ $args = (array)$atts;
130
+
131
+ $defaults = array(
132
+ 'limit' => 5,
133
+ 'orderby' => 'menu_order',
134
+ 'order' => 'DESC',
135
+ 'id' => 0,
136
+ 'echo' => true,
137
+ 'size' => 50,
138
+ 'per_row' => 3
139
+ );
140
+
141
+ $args = shortcode_atts( $defaults, $atts );
142
+
143
+ // Make sure we return and don't echo.
144
+ $args['echo'] = false;
145
+
146
+ // Fix integers.
147
+ if ( isset( $args['limit'] ) ) $args['limit'] = intval( $args['limit'] );
148
+ if ( isset( $args['id'] ) ) $args['id'] = intval( $args['id'] );
149
+ if ( isset( $args['size'] ) && ( 0 < intval( $args['size'] ) ) ) $args['size'] = intval( $args['size'] );
150
+ if ( isset( $args['per_row'] ) && ( 0 < intval( $args['per_row'] ) ) ) $args['per_row'] = intval( $args['per_row'] );
151
+
152
+ // Fix booleans.
153
+ foreach ( array( 'link_title' ) as $k => $v ) {
154
+ if ( isset( $args[$v] ) && ( 'true' == $args[$v] ) ) {
155
+ $args[$v] = true;
156
+ } else {
157
+ $args[$v] = false;
158
+ }
159
+ }
160
+
161
+ return woothemes_features( $args );
162
+ } // End woothemes_features_shortcode()
163
+ }
164
+
165
+ add_shortcode( 'woothemes_features', 'woothemes_features_shortcode' );
166
+ ?>
woothemes-features.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Plugin Name: Features
4
+ * Plugin URI: http://woothemes.com/
5
+ * Description: Hi, I'm your feature showcase plugin for WordPress. Show off what features your company, product or service offers, using our shortcode, widget or template tag.
6
+ * Author: WooThemes
7
+ * Version: 1.0.0
8
+ * Author URI: http://woothemes.com/
9
+ *
10
+ * @package WordPress
11
+ * @subpackage WooThemes_Features
12
+ * @author Matty
13
+ * @since 1.0.0
14
+ */
15
+
16
+ require_once( 'classes/class-woothemes-features.php' );
17
+ require_once( 'woothemes-features-template.php' );
18
+ require_once( 'classes/class-woothemes-widget-features.php' );
19
+ global $woothemes_features;
20
+ $woothemes_features = new Woothemes_Features( __FILE__ );
21
+ ?>