PluginProbe
wp_head() cleaner / trunk
wp_head() cleaner vtrunk
3.1.0 trunk 1.0.0 1.1.0 1.4.0 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 All 30 releases
wp-head-cleaner / wp-head-cleaner.php

wp-head-cleaner.php in wp_head() cleaner trunk, at wp-head-cleaner.php

267 lines 9.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: wp_head() cleaner
4 * Plugin URI: https://wordpress.org/plugins/wp-head-cleaner/
5 * Description: Remove unused tags from wp_head() output.
6 * Version: 3.1.0
7 * License: GPL2
8 * Author: Jonathan Wilsson
9 * Author URI: http://jwilsson.com/
10 * Text Domain: wp-head-cleaner
11 */
12
13 if ( ! defined( 'ABSPATH' ) ) {
14 die( 'No direct access allowed!' );
15 }
16
17 class WP_Head_Cleaner {
18 const OPTION_GROUP = 'wp_head_cleaner_options';
19 const OPTION_NAME = 'wp_head_cleaner_hooks';
20 const OPTION_SLUG = 'wp_head_cleaner';
21
22 private $options = array();
23 private $hooks = array();
24
25 public function __construct() {
26 add_action( 'admin_init', array( $this, 'admin_init' ) );
27 add_action( 'admin_menu', array( $this, 'admin_menu' ) );
28 add_action( 'init', array( $this, 'init' ) );
29
30 add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'plugin_action_links' ) );
31 }
32
33 public function setup_hooks() {
34 $this->hooks = array(
35 array(
36 'title' => __( 'Really Simple Discovery', 'wp-head-cleaner' ),
37 'description' => __( 'Don\'t print tags for the XML-RPC discover mechanism.', 'wp-head-cleaner' ),
38 'action' => 'rsd_link',
39 'hook' => 'wp_head',
40 'priority' => 10,
41 'args' => 1,
42 ),
43 array(
44 'title' => __( 'Windows Live Writer', 'wp-head-cleaner' ),
45 'description' => __( 'Don\'t print tags used by Windows Live Writer.', 'wp-head-cleaner' ),
46 'action' => 'wlwmanifest_link',
47 'hook' => 'wp_head',
48 'priority' => 10,
49 'args' => 1,
50 ),
51 array(
52 'title' => __( 'WordPress generator meta tag', 'wp-head-cleaner' ),
53 'description' => __( 'Don\'t print the WordPress version.', 'wp-head-cleaner' ),
54 'action' => 'wp_generator',
55 'hook' => 'wp_head',
56 'priority' => 10,
57 'args' => 1,
58 ),
59 array(
60 'title' => __( 'Post shortlinks', 'wp-head-cleaner' ),
61 'description' => __( 'Don\'t print post short links.', 'wp-head-cleaner' ),
62 'action' => 'wp_shortlink_wp_head',
63 'hook' => 'wp_head',
64 'priority' => 10,
65 'args' => 0,
66 ),
67 array(
68 'title' => __( 'Canonical links', 'wp-head-cleaner' ),
69 'description' => __( 'Don\'t print post canonical link.', 'wp-head-cleaner' ),
70 'action' => 'rel_canonical',
71 'hook' => 'wp_head',
72 'priority' => 10,
73 'args' => 0,
74 ),
75 array(
76 'title' => __( 'Post and Comment Feed', 'wp-head-cleaner' ),
77 'description' => __( 'Don\'t print links for the posts and comments feeds.', 'wp-head-cleaner' ),
78 'action' => 'feed_links',
79 'hook' => 'wp_head',
80 'priority' => 2,
81 'args' => 1,
82 ),
83 array(
84 'title' => __( 'Other feeds, for example category feeds', 'wp-head-cleaner' ),
85 'description' => __( 'Don\'t print links to other feeds, for example categories.', 'wp-head-cleaner' ),
86 'action' => 'feed_links_extra',
87 'hook' => 'wp_head',
88 'priority' => 3,
89 'args' => 1,
90 ),
91 array(
92 'title' => __( 'Emoji scripts', 'wp-head-cleaner' ),
93 'description' => __( 'Don\'t print scripts for emoji support.', 'wp-head-cleaner' ),
94 'action' => 'print_emoji_detection_script',
95 'hook' => 'wp_head',
96 'priority' => 7,
97 'args' => 1,
98 ),
99 array(
100 'title' => __( 'Emoji styles', 'wp-head-cleaner' ),
101 'description' => __( 'Don\'t print styles for emoji support.', 'wp-head-cleaner' ),
102 'action' => 'print_emoji_styles',
103 'hook' => 'wp_print_styles',
104 'priority' => 10,
105 'args' => 1,
106 ),
107 array(
108 'title' => __( 'REST API', 'wp-head-cleaner' ),
109 'description' => __( 'Don\'t print REST API endpoint tags.', 'wp-head-cleaner' ),
110 'action' => 'rest_output_link_wp_head',
111 'hook' => 'wp_head',
112 'priority' => 10,
113 'args' => 0,
114 ),
115 array(
116 'title' => __( 'oEmbed tags', 'wp-head-cleaner' ),
117 'description' => __( 'Don\'t print tags for the oEmbed discover mechanism.', 'wp-head-cleaner' ),
118 'action' => 'wp_oembed_add_discovery_links',
119 'hook' => 'wp_head',
120 'priority' => 10,
121 'args' => 1,
122 ),
123 array(
124 'title' => __( 'oEmbed scripts', 'wp-head-cleaner' ),
125 'description' => __( 'Don\'t print scripts for the oEmbed discover mechanism.', 'wp-head-cleaner' ),
126 'action' => 'wp_oembed_add_host_js',
127 'hook' => 'wp_head',
128 'priority' => 10,
129 'args' => 1,
130 ),
131 array(
132 'title' => __( 'Resource hints', 'wp-head-cleaner' ),
133 'description' => __( 'Don\'t print tags for browser pre-fetching, pre-rendering, and pre-connecting hints.', 'wp-head-cleaner' ),
134 'action' => 'wp_resource_hints',
135 'hook' => 'wp_head',
136 'priority' => 2,
137 'args' => 1,
138 ),
139 array(
140 'title' => __( 'Robots image preview', 'wp-head-cleaner' ),
141 'description' => __( 'Don\'t print tags for web robots image preview directive.', 'wp-head-cleaner' ),
142 'action' => 'wp_robots_max_image_preview_large',
143 'hook' => 'wp_robots',
144 'priority' => 10,
145 'args' => 1,
146 ),
147 );
148 }
149
150 public function admin_init() {
151 global $pagenow;
152
153 // Don't do anything unless it's the correct page
154 if ( 'options.php' !== $pagenow && 'options-general.php' !== $pagenow ) {
155 return;
156 }
157
158 add_settings_section( 'default', '', array( $this, 'render_section' ), self::OPTION_SLUG );
159 register_setting( self::OPTION_GROUP, self::OPTION_NAME, array(
160 'type' => 'array',
161 'sanitize_callback' => function ( $input ) {
162 if ( ! is_array( $input ) ) {
163 return array();
164 }
165
166 return array_map( 'sanitize_text_field', $input );
167 },
168 ) );
169
170 foreach ( $this->hooks as $hook ) {
171 $action = $hook['action'];
172 $index = array_search( $action, $this->options );
173 $value = false !== $index ? $this->options[ $index ] : '';
174 $args = array(
175 'name' => $action,
176 'value' => (bool) $value,
177 'label_for' => $action,
178 'description' => $hook['description'],
179 'option_name' => self::OPTION_NAME,
180 );
181
182 add_settings_field(
183 $action,
184 $hook['title'],
185 array( $this, 'render_field' ),
186 self::OPTION_SLUG,
187 'default',
188 $args,
189 );
190 }
191 }
192
193 public function admin_menu() {
194 add_options_page(
195 __( 'Options for wp_head() cleaner', 'wp-head-cleaner' ),
196 __( 'wp_head() cleaner', 'wp-head-cleaner' ),
197 'manage_options',
198 self::OPTION_SLUG,
199 array( $this, 'render_page' ),
200 );
201 }
202
203 public function init() {
204 $this->options = (array) get_option( self::OPTION_NAME );
205 $this->setup_hooks();
206
207 foreach ( $this->hooks as $hook ) {
208 $action = $hook['action'];
209
210 // Bail if the tag shouldn't be removed
211 if ( ! in_array( $action, $this->options ) ) {
212 continue;
213 }
214
215 remove_action( $hook['hook'], $action, $hook['priority'], $hook['args'] );
216 }
217 }
218
219 public function plugin_action_links( $links ) {
220 $settings_link = esc_url( get_admin_url( null, 'options-general.php?page=' . self::OPTION_SLUG ) );
221
222 $links[] = sprintf( '<a href="%s">%s</a>', $settings_link, __( 'Settings', 'wp-head-cleaner' ) );
223 $links[] = '<a href="https://github.com/jwilsson/wp-head-cleaner" target="_blank">GitHub</a>';
224
225 return $links;
226 }
227
228 public function render_page() {
229 global $title;
230
231 if ( ! current_user_can( 'manage_options' ) ) {
232 wp_die( 'Cheatin\' Uh?' );
233 }
234 ?>
235 <div class="wrap">
236 <h1><?php echo esc_html( $title ); ?></h1>
237
238 <form action="options.php" method="post">
239 <?php
240 settings_fields( self::OPTION_GROUP );
241 do_settings_sections( self::OPTION_SLUG );
242 submit_button();
243 ?>
244 </form>
245 </div>
246 <?php
247 }
248
249 public function render_section() {
250 echo '<p>' . esc_html__( 'Check the tags you wish to remove.', 'wp-head-cleaner' ) . '</p>';
251 }
252
253 public function render_field( $args ) {
254 printf(
255 '<input type="checkbox" name="%s[]" id="%s" value="%s" %s> <label for="%s"><i>%s</i></label>',
256 esc_attr( $args['option_name'] ),
257 esc_attr( $args['label_for'] ),
258 esc_attr( $args['name'] ),
259 checked( $args['value'], true, false ),
260 esc_attr( $args['label_for'] ),
261 esc_html( $args['description'] ),
262 );
263 }
264 }
265
266 new WP_Head_Cleaner();
267