404page – your smart custom 404 error page - Version 2.2

Version Description

Enhanced compatibility. Automated Operating Method select removed. Several fixes.

Download this release

Release Info

Developer smartware.cc
Plugin Icon 128x128 404page – your smart custom 404 error page
Version 2.2
Comparing to
See all releases

Code changes from version 2.1 to 2.2

Files changed (3) hide show
  1. 404page.php +228 -150
  2. pluginicon.png +0 -0
  3. readme.txt +51 -22
404page.php CHANGED
@@ -1,35 +1,23 @@
1
  <?php
2
  /*
3
  Plugin Name: 404page - your smart custom 404 error page
4
- Plugin URI: http://smartware.cc/free-wordpress-plugins/404page/
5
  Description: Custom 404 the easy way! Set any page as custom 404 error page. No coding needed. Works with (almost) every Theme.
6
- Version: 2.1
7
- Author: smartware.cc, Peter's Plugins
8
- Author URI: http://smartware.cc
9
  Text Domain: 404page
10
- License: GPL2
 
11
  */
12
 
13
- /* Copyright 2016 Peter Raschendorfer (email : sw@smartware.cc)
14
-
15
- This program is free software; you can redistribute it and/or modify
16
- it under the terms of the GNU General Public License, version 2, as
17
- published by the Free Software Foundation.
18
-
19
- This program is distributed in the hope that it will be useful,
20
- but WITHOUT ANY WARRANTY; without even the implied warranty of
21
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
- GNU General Public License for more details.
23
-
24
- You should have received a copy of the GNU General Public License
25
- along with this program; if not, write to the Free Software
26
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27
- */
28
 
29
  if ( ! defined( 'WPINC' ) ) {
30
  die;
31
  }
32
 
 
 
33
  class Smart404Page {
34
  public $plugin_name;
35
  public $plugin_slug;
@@ -44,7 +32,7 @@ class Smart404Page {
44
  public function __construct() {
45
  $this->plugin_name = '404page';
46
  $this->plugin_slug = '404page';
47
- $this->version = '2.1';
48
  $this->get_settings();
49
  $this->init();
50
  }
@@ -55,17 +43,20 @@ class Smart404Page {
55
  $this->settings['404page_page_id'] = $this->get_404page_id();
56
  $this->settings['404page_hide'] = $this->get_404page_hide();
57
  $this->settings['404page_fire_error'] = $this->get_404page_fire_error();
58
- $this->settings['404page_method'] = $this->get_404page_method();
 
59
  }
60
 
61
  // do plugin init
62
  private function init() {
63
 
64
- register_activation_hook( __FILE__, array( $this, 'init_admin_notice' ) );
 
65
 
66
  if ( !is_admin() ) {
67
 
68
- add_action( 'init', array( $this, 'set_mode' ) );
 
69
 
70
  } else {
71
 
@@ -78,11 +69,6 @@ class Smart404Page {
78
  add_action( 'pre_get_posts' ,array ( $this, 'exclude_404page' ) );
79
  }
80
 
81
- if ( 'NOT_DISMISSED' == get_option( '404page_notice_dismissed', 'NOT_DISMISSED' ) ) {
82
- add_action( 'admin_notices', array( $this, 'admin_notice' ) );
83
- add_action( 'wp_ajax_nopriv_404page_dismiss_admin_notice', array( $this, 'dismiss_admin_notice' ) );
84
- add_action( 'wp_ajax_404page_dismiss_admin_notice', array( $this, 'dismiss_admin_notice' ) );
85
- }
86
  }
87
 
88
  }
@@ -90,30 +76,33 @@ class Smart404Page {
90
  // init filters
91
  function set_mode() {
92
 
93
- if ( defined( 'CUSTOMIZR_VER' ) ) {
94
-
95
- // Customizr Compatibility Mode
96
-
97
- add_filter( 'tc_404_header_content', array( $this, 'show404title_customizr_mode' ), 999 );
98
- add_filter( 'tc_404_content', array( $this, 'show404_customizr_mode' ), 999 );
99
- add_filter( 'tc_404_selectors', array( $this, 'show404articleselectors_customizr_mode' ), 999 );
100
-
101
- } else {
102
-
103
- if ( $this->settings['404page_method'] != 'STD' ) {
104
 
 
 
105
  // Compatibility Mode
106
  add_filter( 'posts_results', array( $this, 'show404_compatiblity_mode' ), 999 );
107
-
108
  } else {
109
-
110
  // Standard Mode
111
  add_filter( '404_template', array( $this, 'show404_standard_mode' ), 999 );
112
  if ( $this->settings['404page_fire_error'] ) {
113
  add_action( 'template_redirect', array( $this, 'do_404_header_standard_mode' ) );
114
  }
115
-
116
  }
 
117
  }
118
 
119
  }
@@ -124,13 +113,15 @@ class Smart404Page {
124
  global $wp_query;
125
  $pageid = $this->settings['404page_page_id'];
126
  if ( $pageid > 0 ) {
127
- $wp_query = null;
128
- $wp_query = new WP_Query();
129
- $wp_query->query( 'page_id=' . $pageid );
130
- $wp_query->the_post();
131
- $template = get_page_template();
132
- rewind_posts();
133
- add_filter( 'body_class', array( $this, 'add_404_body_class' ) );
 
 
134
  $this->do_404page_action();
135
  }
136
  return $template;
@@ -144,23 +135,11 @@ class Smart404Page {
144
  remove_filter( 'posts_results', array( $this, 'show404_compatiblity_mode' ), 999 );
145
 
146
  $pageid = $this->settings['404page_page_id'];
147
- if ( 0 != $pageid ) {
148
- if ( empty( $posts ) && is_main_query() && !is_robots() && !is_home() && !is_feed() && !is_search() &&( !defined('DOING_AJAX') || !DOING_AJAX ) ) {
149
  // we need to get the 404 page
150
 
151
- if ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
152
-
153
- // WPML is active
154
- $pageid = apply_filters( 'wpml_object_id', $pageid, 'page', true );
155
-
156
- } elseif ( defined( 'POLYLANG_VERSION' ) ) {
157
-
158
- // Polylang is active
159
- $translatedpageid = pll_get_post( $pageid );
160
- if ( !empty( $translatedpageid ) && 'publish' == get_post_status( $translatedpageid ) ) {
161
- $pageid = $translatedpageid;
162
- }
163
- }
164
 
165
  // as of v2.1 we do not alter the posts argument here because this does not work with SiteOrigin's Page Builder Plugin, template_include filter introduced
166
  $this->postid = $pageid;
@@ -170,6 +149,7 @@ class Smart404Page {
170
  }
171
  add_action( 'wp', array( $this, 'do_404_header' ) );
172
  add_filter( 'body_class', array( $this, 'add_404_body_class' ) );
 
173
 
174
  $posts[] = get_post( $pageid );
175
 
@@ -204,10 +184,21 @@ class Smart404Page {
204
  }
205
 
206
  }
 
 
207
  }
208
  return $posts;
209
  }
210
 
 
 
 
 
 
 
 
 
 
211
  // send a 404 HTTP header - Standard Mode
212
  function do_404_header_standard_mode() {
213
  if ( is_page() && get_the_ID() == $this->settings['404page_page_id'] && !is_404() ) {
@@ -233,25 +224,37 @@ class Smart404Page {
233
 
234
  // show title - Customizr Compatibility Mode
235
  function show404title_customizr_mode( $title ) {
236
- return '<h1 class="entry-title">' . get_the_title( $this->settings['404page_page_id'] ) . '</h1>';
 
 
 
 
237
  }
238
 
239
  // show content - Customizr Compatibility Mode
240
  function show404_customizr_mode( $content ) {
241
- return '<div class="entry-content">' . apply_filters( 'the_content', get_post_field( 'post_content', $this->settings['404page_page_id'] ) ) . '</div>';
 
 
 
 
242
  $this->do_404page_action();
243
  }
244
 
245
  // change article selectors - Customizr Compatibility Mode
246
  function show404articleselectors_customizr_mode( $selectors ) {
247
- return 'id="post-' . $this->settings['404page_page_id'] . '" ' . 'class="' . join( ' ', get_post_class( 'row-fluid', $this->settings['404page_page_id'] ) ) . '"';
 
 
 
 
248
  }
249
 
250
  // init the admin section
251
  function admin_init() {
252
  $this->wp_url = 'https://wordpress.org/plugins/' . $this->plugin_slug;
253
- $this->my_url = 'http://smartware.cc/free-wordpress-plugins/' . $this->plugin_slug;
254
- $this->dc_url = 'http://smartware.cc/docs/' . $this->plugin_slug;
255
  load_plugin_textdomain( '404page' );
256
  add_settings_section( '404page-settings', null, null, '404page_settings_section' );
257
  register_setting( '404page_settings', '404page_page_id' );
@@ -304,41 +307,66 @@ class Smart404Page {
304
 
305
  // handle the settings field method
306
  function admin_method() {
307
- if ( defined( 'CUSTOMIZR_VER' ) || defined( 'ICL_SITEPRESS_VERSION' ) || defined( 'POLYLANG_VERSION' ) || defined( 'SITEORIGIN_PANELS_VERSION' ) || class_exists( 'bbPress' ) ) {
308
- $dis = ' disabled="disabled"';
309
- } else {
310
- $dis = '';
311
- }
312
- echo '<p><input type="radio" id="404page_settings_method_standard" name="404page_method" value="STD"' . checked( 'STD', $this->settings['404page_method'], false ) . $dis . ' />';
313
- echo '<label for="404page_settings_method_standard">' . __( 'Standard Mode', '404page' ) . '</label></p>';
314
-
315
- echo '<p><input type="radio" id="404page_settings_method_compatibility" name="404page_method" value="CMP"' . checked( 'CMP', $this->settings['404page_method'], false ) . $dis . '/>';
316
- echo '<label for="404page_settings_method_compatibility">' . __( 'Compatibility Mode', '404page' ) . '</label></p>';
317
 
318
- if ( defined( 'CUSTOMIZR_VER' ) ) {
319
- echo '<p><span class="dashicons dashicons-warning"></span>&nbsp;' . __( 'Customizr Theme detected. The 404page Plugin works in Customizr Compatibility Mode.', '404page' ) . ' (<a href="' . $this->dc_url . '/#customizr_mode">' . __( 'Read more', '404page' ) . '</a>)</p>';
320
  } elseif ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
321
- echo '<p><span class="dashicons dashicons-warning"></span>&nbsp;' . __( 'WPML Plugin detected. Operating Method set to Compatibility Mode automatically.', '404page' ) . ' (<a href="' . $this->dc_url . '/#compatibilty_mode">' . __( 'Read more', '404page' ) . '</a>)</p>';
 
 
322
  } elseif ( defined( 'POLYLANG_VERSION' ) ) {
323
- echo '<p><span class="dashicons dashicons-warning"></span>&nbsp;' . __( 'Polylang Plugin detected. Operating Method set to Compatibility Mode automatically.', '404page' ) . ' (<a href="' . $this->dc_url . '/#compatibilty_mode">' . __( 'Read more', '404page' ) . '</a>)</p>';
324
- } elseif ( defined( 'SITEORIGIN_PANELS_VERSION' ) ) {
325
- echo '<p><span class="dashicons dashicons-warning"></span>&nbsp;' . __( 'Page Builder by SiteOrigin Plugin detected. Operating Method set to Compatibility Mode automatically.', '404page' ) . ' (<a href="' . $this->dc_url . '/#compatibilty_mode">' . __( 'Read more', '404page' ) . '</a>)</p>';
326
- } elseif ( class_exists( 'bbPress' ) ) {
327
- echo '<p><span class="dashicons dashicons-warning"></span>&nbsp;' . __( 'bbPress Plugin detected. Operating Method set to Compatibility Mode automatically.', '404page' ) . ' (<a href="' . $this->dc_url . '/#compatibilty_mode">' . __( 'Read more', '404page' ) . '</a>)</p>';
328
  } else {
 
 
 
 
 
 
 
329
  echo '<p><span class="dashicons dashicons-info"></span>&nbsp;' . __( 'Standard Mode uses the WordPress Template System and should work in most cases. If the 404page plugin does not work properly, probably you are using a theme or plugin that modifies the WordPress Template System. In this case the Compatibility Mode maybe can fix the problem, although it cannot be guaranteed that every possible configuration can be handled by Compatibility Mode. Standard Mode is the recommended method, only switch to Compatibility Mode if you have any problems.', '404page' ) . '</p>';
 
330
  }
 
331
  }
332
 
333
  // this function hides the selected page from the list of pages
334
  function exclude_404page( $query ) {
335
- global $pagenow;
336
- if( 'edit.php' == $pagenow && ( get_query_var( 'post_type' ) && 'page' == get_query_var( 'post_type' ) ) && !current_user_can( 'create_users' ) ) {
337
- $query->set( 'post__not_in', array( $this->settings['404page_page_id'] ) );
 
 
 
 
 
 
338
  }
339
  return $query;
340
  }
341
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
342
  // adds the options page to admin menu
343
  function admin_menu() {
344
  $page_handle = add_theme_page ( __( '404 Error Page', "404page" ), __( '404 Error Page', '404page' ), 'manage_options', '404pagesettings', array( $this, 'admin_page' ) );
@@ -358,7 +386,7 @@ class Smart404Page {
358
  ?>
359
  <div class="wrap">
360
  <?php screen_icon(); ?>
361
- <h2 style="min-height: 32px; line-height: 32px; padding-left: 40px; background-image: url(<?php echo plugins_url( 'pluginicon.png', __FILE__ ); ?>); background-repeat: no-repeat; background-position: left center"><a href="' . $this->my_url . '">404page</a> <?php echo __( 'Settings', '404page' ); ?></h2>
362
  <?php settings_errors(); ?>
363
  <hr />
364
  <p>Plugin Version: <?php echo $this->version; ?> <a class="dashicons dashicons-editor-help" href="<?php echo $this->wp_url; ?>/changelog/"></a></p>
@@ -387,57 +415,6 @@ class Smart404Page {
387
  <?php
388
  }
389
 
390
- // show a dismissible notice
391
- function admin_notice() {
392
- if ( current_user_can( 'manage_options' ) ) {
393
- echo '<div class="notice notice-info is-dismissible" id="404page_admin_notice"><p><strong>404page Plugin:</strong> ';
394
- if ( defined( 'CUSTOMIZR_VER' ) ) {
395
- // Customizr Theme
396
- _e( 'Customizr Theme detected. The 404page Plugin works in Customizr Compatibility Mode.', '404page' );
397
- } elseif ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
398
- // WPML
399
- _e( 'WPML Plugin detected. Operating Method is set to Compatibility Mode automatically to make the 404page Plugin work with WPML.', '404page' );
400
- } elseif ( defined( 'POLYLANG_VERSION' ) ) {
401
- // Polylang
402
- _e( 'Polylang Plugin detected. Operating Method is set to Compatibility Mode automatically to make the 404page Plugin work with Polylang.', '404page' );
403
- } elseif ( defined( 'SITEORIGIN_PANELS_VERSION' ) ) {
404
- // Page Builder by SiteOrigin
405
- _e( 'Page Builder by SiteOrigin Plugin detected. Operating Method is set to Compatibility Mode automatically to make the 404page Plugin work with Page Builder by SiteOrigin.', '404page' );
406
- } elseif ( class_exists( 'bbPress' ) ) {
407
- // bbPress
408
- _e( 'bbPress Plugin detected. Operating Method is set to Compatibility Mode automatically to make the 404page Plugin work with bbPress.', '404page' );
409
- } elseif ( function_exists( 'wpsupercache_activate' ) ) {
410
- // WP Super Cache
411
- _e( 'WP Super Cache Plugin detected. Please check Settings!', '404page' );
412
- } else {
413
- _e( 'Please check Operating Method.', '404page' );
414
- }
415
- echo '<br /><a href="' . admin_url( 'themes.php?page=404pagesettings' ) . '">' . __( 'Settings', '404page' ) . '</a>';
416
- echo '</p></div>';
417
- }
418
- }
419
-
420
- // dismiss the notice (AJAX)
421
- function dismiss_admin_notice() {
422
- update_option( '404page_notice_dismissed', 'DISMISSED' );
423
- }
424
-
425
- // Reset dismiss state for notice on plugin activation
426
- function init_admin_notice( $network_wide ) {
427
- global $wpdb;
428
- if ( is_multisite() && $network_wide ) {
429
- $current_blog = $wpdb->blogid;
430
- $blog_ids = $wpdb->get_col( "SELECT blog_id FROM $wpdb->blogs" );
431
- foreach ( $blog_ids as $blog_id ) {
432
- switch_to_blog( $blog_id );
433
- delete_option( '404page_notice_dismissed' );
434
- }
435
- switch_to_blog( $current_blog );
436
- } else {
437
- delete_option( '404page_notice_dismissed' );
438
- }
439
- }
440
-
441
  // returns the id of the 404 page if one is defined, returns 0 if none is defined, returns -1 if the defined page id does not exist
442
  private function get_404page_id() {
443
  $pageid = get_option( '404page_page_id', 0 );
@@ -452,8 +429,8 @@ class Smart404Page {
452
 
453
  // returns the selected method
454
  private function get_404page_method() {
455
- if ( defined( 'ICL_SITEPRESS_VERSION' ) || defined( 'POLYLANG_VERSION' ) || defined( 'SITEORIGIN_PANELS_VERSION' ) || class_exists( 'bbPress' ) ) {
456
- // WPML or bbPress is active
457
  return 'CMP';
458
  } else {
459
  return get_option( '404page_method', 'STD' );
@@ -470,6 +447,28 @@ class Smart404Page {
470
  return (bool)get_option( '404page_fire_error', true );
471
  }
472
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
473
  // make plugin expandable
474
  function do_404page_action() {
475
  do_action( '404page_after_404' );
@@ -486,9 +485,9 @@ class Smart404Page {
486
  <ul>
487
  <li><div class="dashicons dashicons-wordpress"></div>&nbsp;&nbsp;<a href="<?php echo $this->wp_url; ?>/"><?php _e( 'Please rate the plugin', '404page' ); ?></a></li>
488
  <li><div class="dashicons dashicons-admin-home"></div>&nbsp;&nbsp;<a href="<?php echo $this->my_url; ?>/"><?php _e( 'Plugin homepage', '404page'); ?></a></li>
489
- <li><div class="dashicons dashicons-admin-home"></div>&nbsp;&nbsp;<a href="http://smartware.cc/"><?php _e( 'Author homepage', '404page' );?></a></li>
490
- <li><div class="dashicons dashicons-googleplus"></div>&nbsp;&nbsp;<a href="http://g.smartware.cc/"><?php _e( 'Authors Google+ Page', '404page' ); ?></a></li>
491
- <li><div class="dashicons dashicons-facebook-alt"></div>&nbsp;&nbsp;<a href="http://f.smartware.cc/"><?php _e( 'Authors facebook Page', '404page' ); ?></a></li>
492
  </ul>
493
  </div>
494
  </div>
@@ -499,7 +498,7 @@ class Smart404Page {
499
  <li><div class="dashicons dashicons-book-alt"></div>&nbsp;&nbsp;<a href="<?php echo $this->dc_url; ?>"><?php _e( 'Take a look at the Plugin Doc', '404page' ); ?></a></li>
500
  <li><div class="dashicons dashicons-wordpress"></div>&nbsp;&nbsp;<a href="<?php echo $this->wp_url; ?>/faq/"><?php _e( 'Take a look at the FAQ section', '404page' ); ?></a></li>
501
  <li><div class="dashicons dashicons-wordpress"></div>&nbsp;&nbsp;<a href="http://wordpress.org/support/plugin/<?php echo $this->plugin_slug; ?>/"><?php _e( 'Take a look at the Support section', '404page'); ?></a></li>
502
- <li><div class="dashicons dashicons-admin-comments"></div>&nbsp;&nbsp;<a href="http://smartware.cc/contact/"><?php _e( 'Feel free to contact the Author', '404page' ); ?></a></li>
503
  </ul>
504
  </div>
505
  </div>
@@ -547,8 +546,87 @@ class Smart404Page {
547
  delete_option( $key );
548
  }
549
  }
550
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
551
  }
552
 
553
  $smart404page = new Smart404Page();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
554
  ?>
1
  <?php
2
  /*
3
  Plugin Name: 404page - your smart custom 404 error page
4
+ Plugin URI: http://petersplugins.com/free-wordpress-plugins/404page/
5
  Description: Custom 404 the easy way! Set any page as custom 404 error page. No coding needed. Works with (almost) every Theme.
6
+ Version: 2.2
7
+ Author: Peter's Plugins, smartware.cc
8
+ Author URI: http://petersplugins.com
9
  Text Domain: 404page
10
+ License: GPL2+
11
+ License URI: http://www.gnu.org/licenses/gpl-2.0.txt
12
  */
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
  if ( ! defined( 'WPINC' ) ) {
16
  die;
17
  }
18
 
19
+ define( 'PP_404', true );
20
+
21
  class Smart404Page {
22
  public $plugin_name;
23
  public $plugin_slug;
32
  public function __construct() {
33
  $this->plugin_name = '404page';
34
  $this->plugin_slug = '404page';
35
+ $this->version = '2.2';
36
  $this->get_settings();
37
  $this->init();
38
  }
43
  $this->settings['404page_page_id'] = $this->get_404page_id();
44
  $this->settings['404page_hide'] = $this->get_404page_hide();
45
  $this->settings['404page_fire_error'] = $this->get_404page_fire_error();
46
+ // $this->settings['404page_method'] = $this->get_404page_method(); --> moved to set_mode in v 2.2 because this may be too early here
47
+ $this->settings['404page_native'] = false;
48
  }
49
 
50
  // do plugin init
51
  private function init() {
52
 
53
+ // as of v 2.2 always call set_mode
54
+ add_action( 'init', array( $this, 'set_mode' ) );
55
 
56
  if ( !is_admin() ) {
57
 
58
+ add_action( 'pre_get_posts', array ( $this, 'exclude_404page' ) );
59
+ add_filter( 'get_pages', array ( $this, 'remove_404page_from_array' ), 10, 2 );
60
 
61
  } else {
62
 
69
  add_action( 'pre_get_posts' ,array ( $this, 'exclude_404page' ) );
70
  }
71
 
 
 
 
 
 
72
  }
73
 
74
  }
76
  // init filters
77
  function set_mode() {
78
 
79
+ $this->settings['404page_method'] = $this->get_404page_method();
80
+
81
+ if ( !is_admin() ) {
82
+
83
+ if ( defined( 'CUSTOMIZR_VER' ) ) {
84
+
85
+ // Customizr Compatibility Mode
86
+
87
+ add_filter( 'tc_404_header_content', array( $this, 'show404title_customizr_mode' ), 999 );
88
+ add_filter( 'tc_404_content', array( $this, 'show404_customizr_mode' ), 999 );
89
+ add_filter( 'tc_404_selectors', array( $this, 'show404articleselectors_customizr_mode' ), 999 );
90
 
91
+ } elseif ( $this->settings['404page_method'] != 'STD' ) {
92
+
93
  // Compatibility Mode
94
  add_filter( 'posts_results', array( $this, 'show404_compatiblity_mode' ), 999 );
95
+
96
  } else {
97
+
98
  // Standard Mode
99
  add_filter( '404_template', array( $this, 'show404_standard_mode' ), 999 );
100
  if ( $this->settings['404page_fire_error'] ) {
101
  add_action( 'template_redirect', array( $this, 'do_404_header_standard_mode' ) );
102
  }
103
+
104
  }
105
+
106
  }
107
 
108
  }
113
  global $wp_query;
114
  $pageid = $this->settings['404page_page_id'];
115
  if ( $pageid > 0 ) {
116
+ if ( ! $this->settings['404page_native'] ) {
117
+ $wp_query = null;
118
+ $wp_query = new WP_Query();
119
+ $wp_query->query( 'page_id=' . $pageid );
120
+ $wp_query->the_post();
121
+ $template = get_page_template();
122
+ rewind_posts();
123
+ add_filter( 'body_class', array( $this, 'add_404_body_class' ) );
124
+ }
125
  $this->do_404page_action();
126
  }
127
  return $template;
135
  remove_filter( 'posts_results', array( $this, 'show404_compatiblity_mode' ), 999 );
136
 
137
  $pageid = $this->settings['404page_page_id'];
138
+ if ( $pageid > 0 && ! $this->settings['404page_native'] ) {
139
+ if ( empty( $posts ) && is_main_query() && !is_robots() && !is_home() && !is_feed() && !is_search() && !is_archive() && ( !defined('DOING_AJAX') || !DOING_AJAX ) ) {
140
  // we need to get the 404 page
141
 
142
+ $pageid = $this->get_page_id( $pageid );
 
 
 
 
 
 
 
 
 
 
 
 
143
 
144
  // as of v2.1 we do not alter the posts argument here because this does not work with SiteOrigin's Page Builder Plugin, template_include filter introduced
145
  $this->postid = $pageid;
149
  }
150
  add_action( 'wp', array( $this, 'do_404_header' ) );
151
  add_filter( 'body_class', array( $this, 'add_404_body_class' ) );
152
+ add_filter( 'template_include', array( $this, 'change_404_template' ), 999 );
153
 
154
  $posts[] = get_post( $pageid );
155
 
184
  }
185
 
186
  }
187
+ } elseif ( $pageid > 0 && $this->settings['404page_native'] ) {
188
+ $this->do_404page_action();
189
  }
190
  return $posts;
191
  }
192
 
193
+ // this function overrides the page template in compatibilty mode
194
+ function change_404_template( $template ) {
195
+ // we have to check if the template file is there because if the theme was changed maybe a wrong template is stored in the database
196
+ if ( file_exists( $this->template ) || '' != locate_template( $this->template ) ) {
197
+ return $this->template;
198
+ }
199
+ return $template;
200
+ }
201
+
202
  // send a 404 HTTP header - Standard Mode
203
  function do_404_header_standard_mode() {
204
  if ( is_page() && get_the_ID() == $this->settings['404page_page_id'] && !is_404() ) {
224
 
225
  // show title - Customizr Compatibility Mode
226
  function show404title_customizr_mode( $title ) {
227
+ if ( ! $this->settings['404page_native'] ) {
228
+ return '<h1 class="entry-title">' . get_the_title( $this->settings['404page_page_id'] ) . '</h1>';
229
+ } else {
230
+ return $title;
231
+ }
232
  }
233
 
234
  // show content - Customizr Compatibility Mode
235
  function show404_customizr_mode( $content ) {
236
+ if ( ! $this->settings['404page_native'] ) {
237
+ return '<div class="entry-content">' . apply_filters( 'the_content', get_post_field( 'post_content', $this->settings['404page_page_id'] ) ) . '</div>';
238
+ } else {
239
+ return $content;
240
+ }
241
  $this->do_404page_action();
242
  }
243
 
244
  // change article selectors - Customizr Compatibility Mode
245
  function show404articleselectors_customizr_mode( $selectors ) {
246
+ if ( ! $this->settings['404page_native'] ) {
247
+ return 'id="post-' . $this->settings['404page_page_id'] . '" ' . 'class="' . join( ' ', get_post_class( 'row-fluid', $this->settings['404page_page_id'] ) ) . '"';
248
+ } else {
249
+ return $selectors;
250
+ }
251
  }
252
 
253
  // init the admin section
254
  function admin_init() {
255
  $this->wp_url = 'https://wordpress.org/plugins/' . $this->plugin_slug;
256
+ $this->my_url = 'http://petersplugins.com/free-wordpress-plugins/' . $this->plugin_slug;
257
+ $this->dc_url = 'http://petersplugins.com/docs/' . $this->plugin_slug;
258
  load_plugin_textdomain( '404page' );
259
  add_settings_section( '404page-settings', null, null, '404page_settings_section' );
260
  register_setting( '404page_settings', '404page_page_id' );
307
 
308
  // handle the settings field method
309
  function admin_method() {
310
+
311
+ if ( $this->settings['404page_native'] ) {
312
+
313
+ echo '<p><span class="dashicons dashicons-info"></span>&nbsp;' . __( 'This setting is not available because the Theme you are using natively supports the 404page plugin.', '404page' ) . ' (<a href="' . $this->dc_url . '/#native_mode">' . __( 'Read more', '404page' ) . '</a>)</p>';
314
+
315
+ } elseif ( defined( 'CUSTOMIZR_VER' ) ) {
316
+
317
+ echo '<p><span class="dashicons dashicons-info"></span>&nbsp;' . __( 'This setting is not availbe because the 404page Plugin works in Customizr Compatibility Mode.', '404page' ) . ' (<a href="' . $this->dc_url . '/#special_modes">' . __( 'Read more', '404page' ) . '</a>)</p>';
 
 
318
 
 
 
319
  } elseif ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
320
+
321
+ echo '<p><span class="dashicons dashicons-info"></span>&nbsp;' . __( 'This setting is not availbe because the 404page Plugin works in WPML Mode.', '404page' ) . ' (<a href="' . $this->dc_url . '/#special_modes">' . __( 'Read more', '404page' ) . '</a>)</p>';
322
+
323
  } elseif ( defined( 'POLYLANG_VERSION' ) ) {
324
+
325
+ echo '<p><span class="dashicons dashicons-info"></span>&nbsp;' . __( 'This setting is not availbe because the 404page Plugin works in Polylang Mode.', '404page' ) . ' (<a href="' . $this->dc_url . '/#special_modes">' . __( 'Read more', '404page' ) . '</a>)</p>';
326
+
 
 
327
  } else {
328
+
329
+ echo '<p><input type="radio" id="404page_settings_method_standard" name="404page_method" value="STD"' . checked( 'STD', $this->settings['404page_method'], false ) . ' />';
330
+ echo '<label for="404page_settings_method_standard">' . __( 'Standard Mode', '404page' ) . '</label></p>';
331
+
332
+ echo '<p><input type="radio" id="404page_settings_method_compatibility" name="404page_method" value="CMP"' . checked( 'CMP', $this->settings['404page_method'], false ) . '/>';
333
+ echo '<label for="404page_settings_method_compatibility">' . __( 'Compatibility Mode', '404page' ) . '</label></p>';
334
+
335
  echo '<p><span class="dashicons dashicons-info"></span>&nbsp;' . __( 'Standard Mode uses the WordPress Template System and should work in most cases. If the 404page plugin does not work properly, probably you are using a theme or plugin that modifies the WordPress Template System. In this case the Compatibility Mode maybe can fix the problem, although it cannot be guaranteed that every possible configuration can be handled by Compatibility Mode. Standard Mode is the recommended method, only switch to Compatibility Mode if you have any problems.', '404page' ) . '</p>';
336
+
337
  }
338
+
339
  }
340
 
341
  // this function hides the selected page from the list of pages
342
  function exclude_404page( $query ) {
343
+ if ( $this->settings['404page_page_id'] > 0 ) {
344
+ global $pagenow;
345
+ if( is_admin() && ( 'edit.php' == $pagenow && ( get_query_var( 'post_type' ) && 'page' == get_query_var( 'post_type' ) ) && !current_user_can( 'create_users' ) ) || ! is_admin() ) {
346
+ $pageid = $this->settings['404page_page_id'];
347
+ if ( ! is_admin() ) {
348
+ $pageid = $this->get_page_id( $pageid );
349
+ }
350
+ $query->set( 'post__not_in', array( $pageid ) );
351
+ }
352
  }
353
  return $query;
354
  }
355
 
356
+ // this function removes the 404 page from get_pages result array
357
+ function remove_404page_from_array( $pages, $r ) {
358
+ if ( $this->settings['404page_page_id'] > 0 ) {
359
+ $pageid = $this->get_page_id( $this->settings['404page_page_id'] );
360
+ for ( $i = 0; $i < sizeof( $pages ); $i++ ) {
361
+ if ( $pages[$i]->ID == $pageid ) {
362
+ unset( $pages[$i] );
363
+ break;
364
+ }
365
+ }
366
+ }
367
+ return array_values( $pages );
368
+ }
369
+
370
  // adds the options page to admin menu
371
  function admin_menu() {
372
  $page_handle = add_theme_page ( __( '404 Error Page', "404page" ), __( '404 Error Page', '404page' ), 'manage_options', '404pagesettings', array( $this, 'admin_page' ) );
386
  ?>
387
  <div class="wrap">
388
  <?php screen_icon(); ?>
389
+ <h2 style="min-height: 32px; line-height: 32px; padding-left: 40px; background-image: url(<?php echo plugins_url( 'pluginicon.png', __FILE__ ); ?>); background-repeat: no-repeat; background-position: left center"><a href="<?php echo $this->my_url; ?>">404page</a> <?php echo __( 'Settings', '404page' ); ?></h2>
390
  <?php settings_errors(); ?>
391
  <hr />
392
  <p>Plugin Version: <?php echo $this->version; ?> <a class="dashicons dashicons-editor-help" href="<?php echo $this->wp_url; ?>/changelog/"></a></p>
415
  <?php
416
  }
417
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
418
  // returns the id of the 404 page if one is defined, returns 0 if none is defined, returns -1 if the defined page id does not exist
419
  private function get_404page_id() {
420
  $pageid = get_option( '404page_page_id', 0 );
429
 
430
  // returns the selected method
431
  private function get_404page_method() {
432
+ if ( defined( 'ICL_SITEPRESS_VERSION' ) || defined( 'POLYLANG_VERSION' ) ) {
433
+ // WPML or Polylang is active
434
  return 'CMP';
435
  } else {
436
  return get_option( '404page_method', 'STD' );
447
  return (bool)get_option( '404page_fire_error', true );
448
  }
449
 
450
+ // thsi function gets the id of the translated page if WPML or Polylang is active - otherwise the original pageid is returned
451
+ private function get_page_id( $pageid ) {
452
+
453
+ if ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
454
+
455
+ // WPML is active
456
+ $pageid = apply_filters( 'wpml_object_id', $pageid, 'page', true );
457
+
458
+ } elseif ( defined( 'POLYLANG_VERSION' ) ) {
459
+
460
+ // Polylang is active
461
+ $translatedpageid = pll_get_post( $pageid );
462
+ if ( !empty( $translatedpageid ) && 'publish' == get_post_status( $translatedpageid ) ) {
463
+ $pageid = $translatedpageid;
464
+ }
465
+
466
+ }
467
+
468
+ return $pageid;
469
+
470
+ }
471
+
472
  // make plugin expandable
473
  function do_404page_action() {
474
  do_action( '404page_after_404' );
485
  <ul>
486
  <li><div class="dashicons dashicons-wordpress"></div>&nbsp;&nbsp;<a href="<?php echo $this->wp_url; ?>/"><?php _e( 'Please rate the plugin', '404page' ); ?></a></li>
487
  <li><div class="dashicons dashicons-admin-home"></div>&nbsp;&nbsp;<a href="<?php echo $this->my_url; ?>/"><?php _e( 'Plugin homepage', '404page'); ?></a></li>
488
+ <li><div class="dashicons dashicons-admin-home"></div>&nbsp;&nbsp;<a href="http://petersplugins.com/"><?php _e( 'Author homepage', '404page' );?></a></li>
489
+ <li><div class="dashicons dashicons-googleplus"></div>&nbsp;&nbsp;<a href="http://g.petersplugins.com/"><?php _e( 'Authors Google+ Page', '404page' ); ?></a></li>
490
+ <li><div class="dashicons dashicons-facebook-alt"></div>&nbsp;&nbsp;<a href="http://f.petersplugins.com/"><?php _e( 'Authors facebook Page', '404page' ); ?></a></li>
491
  </ul>
492
  </div>
493
  </div>
498
  <li><div class="dashicons dashicons-book-alt"></div>&nbsp;&nbsp;<a href="<?php echo $this->dc_url; ?>"><?php _e( 'Take a look at the Plugin Doc', '404page' ); ?></a></li>
499
  <li><div class="dashicons dashicons-wordpress"></div>&nbsp;&nbsp;<a href="<?php echo $this->wp_url; ?>/faq/"><?php _e( 'Take a look at the FAQ section', '404page' ); ?></a></li>
500
  <li><div class="dashicons dashicons-wordpress"></div>&nbsp;&nbsp;<a href="http://wordpress.org/support/plugin/<?php echo $this->plugin_slug; ?>/"><?php _e( 'Take a look at the Support section', '404page'); ?></a></li>
501
+ <li><div class="dashicons dashicons-admin-comments"></div>&nbsp;&nbsp;<a href="http://petersplugins.com/contact/"><?php _e( 'Feel free to contact the Author', '404page' ); ?></a></li>
502
  </ul>
503
  </div>
504
  </div>
546
  delete_option( $key );
547
  }
548
  }
549
+
550
+ // *
551
+ // * functions for theme usage
552
+ // *
553
+
554
+ // check if there's a custom 404 page set
555
+ function pp_404_is_active() {
556
+ return ( $this->settings['404page_page_id'] > 0 );
557
+ }
558
+
559
+ // activate the native theme support
560
+ function pp_404_set_native_support() {
561
+ $this->settings['404page_native'] = true;
562
+ }
563
+
564
+ // get the title - native theme support
565
+ function pp_404_get_the_title() {
566
+ $title = '';
567
+ if ( $this->settings['404page_page_id'] > 0 && $this->settings['404page_native'] ) {
568
+ $title = get_the_title( $this->settings['404page_page_id'] );
569
+ }
570
+ return $title;
571
+ }
572
+
573
+ // print title - native theme support
574
+ function pp_404_the_title() {
575
+ echo $this->pp_404_get_the_title();
576
+ }
577
+
578
+ // get the content - native theme support
579
+ function pp_404_get_the_content() {
580
+ $content = '';
581
+ if ( $this->settings['404page_page_id'] > 0 && $this->settings['404page_native'] ) {
582
+ $content = apply_filters( 'the_content', get_post_field( 'post_content', $this->settings['404page_page_id'] ) );
583
+ }
584
+ return $content;
585
+ }
586
+
587
+ // print content - native theme support
588
+ function pp_404_the_content() {
589
+ echo $this->pp_404_get_the_content();
590
+ }
591
+
592
  }
593
 
594
  $smart404page = new Smart404Page();
595
+
596
+ // this function can be used by a theme to check if there's an active custom 404 page
597
+ function pp_404_is_active() {
598
+ global $smart404page;
599
+ return $smart404page->pp_404_is_active();
600
+ }
601
+
602
+ // this function can be used by a theme to activate native support
603
+ function pp_404_set_native_support() {
604
+ global $smart404page;
605
+ $smart404page->pp_404_set_native_support();
606
+ }
607
+
608
+ // this function can be used by a theme to get the title of the custom 404 page in native support
609
+ function pp_404_get_the_title() {
610
+ global $smart404page;
611
+ return $smart404page->pp_404_get_the_title();
612
+ }
613
+
614
+ // this function can be used by a theme to print out the title of the custom 404 page in native support
615
+ function pp_404_the_title() {
616
+ global $smart404page;
617
+ $smart404page->pp_404_the_title();
618
+ }
619
+
620
+ // this function can be used by a theme to get the content of the custom 404 page in native support
621
+ function pp_404_get_the_content() {
622
+ global $smart404page;
623
+ return $smart404page->pp_404_get_the_content();
624
+ }
625
+
626
+ // this function can be used by a theme to print out the content of the custom 404 page in native support
627
+ function pp_404_the_content() {
628
+ global $smart404page;
629
+ return $smart404page->pp_404_the_content();
630
+ }
631
+
632
  ?>
pluginicon.png CHANGED
Binary file
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
  === 404page - your smart custom 404 error page ===
2
- Contributors: smartware.cc, petersplugins
3
- Donate link:http://smartware.cc/make-a-donation/
4
  Tags: page, 404, error, error page, 404 page, page not found, page not found error, 404 error page, missing, broken link, template, 404 link, seo, custom 404, custom 404 page, custom 404 error, custom 404 error page, customize 404, customize 404 page, customize 404 error page
5
  Requires at least: 3.0
6
- Tested up to: 4.5
7
- Stable tag: 2.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -14,10 +14,10 @@ Custom 404 the easy way! Set any page as custom 404 error page. No coding needed
14
 
15
  > Create your custom 404 Error Page using the full Power of WordPress
16
 
17
- **See also [Plugin Homepage](http://smartware.cc/free-wordpress-plugins/404page/) and [Plugin Doc](http://smartware.cc/docs/404page/)**
18
 
19
- = Version 2.1 Update Notice =
20
- Please take a look at the [release notes](http://smartware.cc/blog/2016/04/22/404page-is-now-officially-wpml-approved-and-much-more/).
21
 
22
  https://www.youtube.com/watch?v=VTL07Lf0IsY
23
 
@@ -30,21 +30,20 @@ Create your custom 404 Page as a normal WordPress Page using the full power of W
30
 
31
  = Translations =
32
 
33
- As of version 2.0 the 404page Plugin uses GlotPress - the wordpress.org Translation System - for translations. Translations can be submitted at [translate.wordpress.org](https://translate.wordpress.org/projects/wp-plugins/404page).
34
 
35
  **Translation are highly appreciated**. It would be great if you'd support the 404page Plugin by adding a new translation or keeping an existing one up to date. If you're new to GlotPress take a look at the [Translator Handbook](https://make.wordpress.org/polyglots/handbook/tools/glotpress-translate-wordpress-org/).
36
 
37
  = Do you like the 404page Plugin? =
38
 
39
- Thanks, I appreciate that. You don’t need to make a donation. No money, no beer, no coffee. Please, just [tell the world that you like what I’m doing](http://smartware.cc/make-a-donation/)! And that’s all.
40
 
41
- = More plugins from smartware.cc =
42
 
43
- * **[hashtagger](https://wordpress.org/plugins/hashtagger/)** Tag your posts by using #hashtags
44
- * **[JavaScript AutoLoader](https://wordpress.org/plugins/javascript-autoloader/)** - Load JavaScript files without changing files in the theme directory or installing several plugins to add all the desired functionality
45
- * **[link-log](https://wordpress.org/plugins/link-log/)** - Find out where your visitors leave to. Track clicks on external links.
46
  * **[smart Archive Page Remove](https://wordpress.org/plugins/smart-archive-page-remove/)** - Completely remove unwated Archive Pages from your Blog
47
  * **[smart User Slug Hider](https://wordpress.org/plugins/smart-user-slug-hider/)** - Hide usernames in author pages URLs to enhance security
 
48
 
49
  == Installation ==
50
 
@@ -73,6 +72,9 @@ No, there is no redirection! The chosen page is delivered as a 'real' 404 error
73
  = What about PHP Version 7? =
74
  The plugin works smoothly with PHP 7.
75
 
 
 
 
76
  == Screenshots ==
77
 
78
  1. Create your 404 Page as a normal WordPress Page
@@ -81,6 +83,14 @@ The plugin works smoothly with PHP 7.
81
 
82
  == Changelog ==
83
 
 
 
 
 
 
 
 
 
84
  = 2.1 (2016-04-22) =
85
  * introduction of selectable Operating Methods
86
  * several changes to Compatibility Mode for improved WPML and bbPress compatibility plus compatibility with Page Builder by SiteOrigin
@@ -102,7 +112,7 @@ The plugin works smoothly with PHP 7.
102
  * class `error404` added to the classes that are assigned to the body HTML element
103
  * the settings menu was moved from 'Settings' to 'Appearance'
104
  * translation files removed, using GlotPress exclusively
105
- * [Read more](http://smartware.cc/blog/2016/02/23/the-404page-plugin-now-works-with-wpml-and-other-enhancements/)
106
 
107
  = 1.4 (2015-08-07) =
108
  * edit the 404 page directly from settings page
@@ -125,8 +135,14 @@ The plugin works smoothly with PHP 7.
125
 
126
  == Upgrade Notice ==
127
 
 
 
 
 
 
 
128
  = 2.0 =
129
- Version 2.0 is more or less a completely new development and a big step forward. [Read more](http://smartware.cc/blog/2016/02/23/the-404page-plugin-now-works-with-wpml-and-other-enhancements/)
130
 
131
  = 1.4 =
132
  Editing of the 404 page is now possible directly from settings page. Portuguese translation added.
@@ -135,7 +151,7 @@ Editing of the 404 page is now possible directly from settings page. Portuguese
135
 
136
  = The 404page plugin was sucessfully tested by the author with the following themes =
137
  * [Athena](https://wordpress.org/themes/athena/)
138
- * [Customizr](https://wordpress.org/themes/customizr/) (Read more about [Customizr Compatibility Mode](http://smartware.cc/docs/404page/#settings_operating_method))
139
  * [evolve](https://wordpress.org/themes/evolve/)
140
  * [GeneratePress](https://wordpress.org/themes/generatepress/)
141
  * [Graphene](https://wordpress.org/themes/graphene/)
@@ -154,15 +170,28 @@ Editing of the 404 page is now possible directly from settings page. Portuguese
154
  * [Twenty Sixteen](https://wordpress.org/themes/twentysixteen/)
155
  * [Vantage](https://wordpress.org/themes/vantage/)
156
  * [Virtue](https://wordpress.org/themes/virtue/)
157
- * [Zerif Lite](https://wordpress.org/themes/zerif-lite/)
 
 
 
 
 
158
 
159
  = The 404page plugin was sucessfully tested by the author with the following plugins =
160
- * [bbPress](https://wordpress.org/plugins/bbpress/)(Read more about [Compatibility Mode](http://smartware.cc/docs/404page/#settings_operating_method))
161
  * [BuddyPress](https://wordpress.org/plugins/buddypress/)
162
  * [hashtagger](https://wordpress.org/plugins/hashtagger/)
163
- * [Page Builder by SiteOrigin](https://wordpress.org/plugins/siteorigin-panels/)(Read more about [Compatibility Mode](http://smartware.cc/docs/404page/#settings_operating_method))
164
- * [Polylang](https://wordpress.org/plugins/polylang/)(Read more about [Polylang Compatibility](http://smartware.cc/docs/404page/#settings_operating_method))
165
  * [User Submitted Posts](https://wordpress.org/plugins/user-submitted-posts/)
166
  * [WooCommerce](https://wordpress.org/plugins/woocommerce/)
167
- * [WP Super Cache](https://wordpress.org/plugins/wp-super-cache/)(Read more about [WP Super Cache Compatibility](http://smartware.cc/docs/404page/#wp_super_cache)
168
- * [WPML WordPress Multilingual Plugin](https://wpml.org/)([officially approved by WPML team](https://wpml.org/plugin/404page/))(Read more about [WPML Compatibility](http://smartware.cc/docs/404page/#settings_operating_method)
 
 
 
 
 
 
 
 
1
  === 404page - your smart custom 404 error page ===
2
+ Contributors: petersplugins, smartware.cc
3
+ Donate link:http://petersplugins.com/make-a-donation/
4
  Tags: page, 404, error, error page, 404 page, page not found, page not found error, 404 error page, missing, broken link, template, 404 link, seo, custom 404, custom 404 page, custom 404 error, custom 404 error page, customize 404, customize 404 page, customize 404 error page
5
  Requires at least: 3.0
6
+ Tested up to: 4.6
7
+ Stable tag: 2.2
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
14
 
15
  > Create your custom 404 Error Page using the full Power of WordPress
16
 
17
+ **See also [Plugin Homepage](http://petersplugins.com/free-wordpress-plugins/404page/) and [Plugin Doc](http://petersplugins.com/docs/404page/)**
18
 
19
+ = Version 2.2 Update Notice =
20
+ Please note that the Plugin **no longer switches to Compatibility Mode automatically** under certain conditions. Trying to identify several configurations where Compatibility Mode is required caused some other problems. Take a look at the [release notes](http://petersplugins.com/blog/2016/09/26/404page-version-2-2-a-lot-of-changes-under-the-hood).
21
 
22
  https://www.youtube.com/watch?v=VTL07Lf0IsY
23
 
30
 
31
  = Translations =
32
 
33
+ The 404page Plugin uses GlotPress - the wordpress.org Translation System - for translations. Translations can be submitted at [translate.wordpress.org](https://translate.wordpress.org/projects/wp-plugins/404page).
34
 
35
  **Translation are highly appreciated**. It would be great if you'd support the 404page Plugin by adding a new translation or keeping an existing one up to date. If you're new to GlotPress take a look at the [Translator Handbook](https://make.wordpress.org/polyglots/handbook/tools/glotpress-translate-wordpress-org/).
36
 
37
  = Do you like the 404page Plugin? =
38
 
39
+ Thanks, I appreciate that. You don’t need to make a donation. No money, no beer, no coffee. Please, just [tell the world that you like what I’m doing](http://petersplugins.com/make-a-donation/)! And that’s all.
40
 
41
+ = More plugins from Peter =
42
 
43
+ * **[hashtagger](https://wordpress.org/plugins/hashtagger/)** - Use hashtags in WordPress
 
 
44
  * **[smart Archive Page Remove](https://wordpress.org/plugins/smart-archive-page-remove/)** - Completely remove unwated Archive Pages from your Blog
45
  * **[smart User Slug Hider](https://wordpress.org/plugins/smart-user-slug-hider/)** - Hide usernames in author pages URLs to enhance security
46
+ * [See all](https://profiles.wordpress.org/petersplugins/#content-plugins)
47
 
48
  == Installation ==
49
 
72
  = What about PHP Version 7? =
73
  The plugin works smoothly with PHP 7.
74
 
75
+ = Is it possible to add custom CSS to the 404 page? =
76
+ The 404page plugin adds a CSS class `error404` to the `<body>` tag which can be used for extra styling.
77
+
78
  == Screenshots ==
79
 
80
  1. Create your 404 Page as a normal WordPress Page
83
 
84
  == Changelog ==
85
 
86
+ = 2.2 (2016-09-26) =
87
+ * automatic switch to Compatibility Mode for several plugins removed
88
+ * enhanced support for WPML and Polylang
89
+ * remove the 404 page from search results (for all languages if WPML or Polylang is used)
90
+ * remove the 404 page from sitemap or other page lists (for all languages if WPML or Polylang is used)
91
+ * bugfix for author archives
92
+ * confusing admin message removed
93
+
94
  = 2.1 (2016-04-22) =
95
  * introduction of selectable Operating Methods
96
  * several changes to Compatibility Mode for improved WPML and bbPress compatibility plus compatibility with Page Builder by SiteOrigin
112
  * class `error404` added to the classes that are assigned to the body HTML element
113
  * the settings menu was moved from 'Settings' to 'Appearance'
114
  * translation files removed, using GlotPress exclusively
115
+ * [Read more](http://petersplugins.com/blog/2016/02/23/the-404page-plugin-now-works-with-wpml-and-other-enhancements/)
116
 
117
  = 1.4 (2015-08-07) =
118
  * edit the 404 page directly from settings page
135
 
136
  == Upgrade Notice ==
137
 
138
+ = 2.2 =
139
+ Enhanced compatibility. Automated Operating Method select removed. Several fixes.
140
+
141
+ = 2.1 =
142
+ Introduced Compatibility Mode, improved compatibility with several plugins.
143
+
144
  = 2.0 =
145
+ Version 2.0 is more or less a completely new development and a big step forward. [Read more](http://petersplugins.com/blog/2016/02/23/the-404page-plugin-now-works-with-wpml-and-other-enhancements/)
146
 
147
  = 1.4 =
148
  Editing of the 404 page is now possible directly from settings page. Portuguese translation added.
151
 
152
  = The 404page plugin was sucessfully tested by the author with the following themes =
153
  * [Athena](https://wordpress.org/themes/athena/)
154
+ * [Customizr](https://wordpress.org/themes/customizr/) (Read more about [Customizr Compatibility Mode](http://petersplugins.com/docs/404page/#settings_operating_method))
155
  * [evolve](https://wordpress.org/themes/evolve/)
156
  * [GeneratePress](https://wordpress.org/themes/generatepress/)
157
  * [Graphene](https://wordpress.org/themes/graphene/)
170
  * [Twenty Sixteen](https://wordpress.org/themes/twentysixteen/)
171
  * [Vantage](https://wordpress.org/themes/vantage/)
172
  * [Virtue](https://wordpress.org/themes/virtue/)
173
+ * [Zerif Lite](http://themeisle.com/themes/zerif-lite/)
174
+
175
+ = The 404page plugin was sucessfully tested by the author with the following starter themes =
176
+ * [Bones}(http://themble.com/bones/)
177
+ * [JointsWP](http://jointswp.com/)
178
+ * [undersores](http://underscores.me/)
179
 
180
  = The 404page plugin was sucessfully tested by the author with the following plugins =
181
+ * [bbPress](https://wordpress.org/plugins/bbpress/)
182
  * [BuddyPress](https://wordpress.org/plugins/buddypress/)
183
  * [hashtagger](https://wordpress.org/plugins/hashtagger/)
184
+ * [Page Builder by SiteOrigin](https://wordpress.org/plugins/siteorigin-panels/)
185
+ * [Polylang](https://wordpress.org/plugins/polylang/)
186
  * [User Submitted Posts](https://wordpress.org/plugins/user-submitted-posts/)
187
  * [WooCommerce](https://wordpress.org/plugins/woocommerce/)
188
+ * [WP Super Cache](https://wordpress.org/plugins/wp-super-cache/)(Read more about [WP Super Cache Compatibility](http://petersplugins.com/docs/404page/#wp_super_cache)
189
+ * [WPML WordPress Multilingual Plugin](https://wpml.org/)([officially approved by WPML team](https://wpml.org/plugin/404page/))
190
+
191
+ == For developers ==
192
+
193
+ = Action Hook =
194
+ The plugin adds an action hook 404page_after_404 which you can use to add extra functionality. The exact position the action occurs after an 404 error is detected depends on the Operating Method. Your function must not generate any output. There are no parameters.
195
+
196
+ = Native Support =
197
+ If you are a theme developer you can add native support for the 404page plugin to your theme for full control. [Read more](http://petersplugins.com/docs/404page/#theme_native_support).