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

Version Description

Version 2.4 fixes several issues. See changelog for details.

Download this release

Release Info

Developer petersplugins
Plugin Icon 128x128 404page – your smart custom 404 error page
Version 2.4
Comparing to
See all releases

Code changes from version 2.3 to 2.4

Files changed (3) hide show
  1. 404page.php +116 -46
  2. pluginicon.png +0 -0
  3. readme.txt +26 -10
404page.php CHANGED
@@ -3,15 +3,14 @@
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.3
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
}
@@ -32,9 +31,9 @@ class Smart404Page {
32
public function __construct() {
33
$this->plugin_name = '404page';
34
$this->plugin_slug = '404page';
35
- $this->version = '2.3';
36
$this->get_settings();
37
- $this->init();
38
}
39
40
// get all settings
@@ -46,12 +45,22 @@ class Smart404Page {
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
@@ -91,7 +100,8 @@ class Smart404Page {
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
@@ -111,7 +121,7 @@ class Smart404Page {
111
function show404_standard_mode( $template ) {
112
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;
@@ -132,27 +142,39 @@ class Smart404Page {
132
function show404_compatiblity_mode( $posts ) {
133
134
// remove the filter so we handle only the first query - no custom queries
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;
146
- $this->template = get_page_template_slug( $pageid );
147
- if ( $this->template == '' ) {
148
- $this->template = get_page_template();
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
-
156
$this->do_404page_action();
157
158
} elseif ( 1 == count( $posts ) && 'page' == $posts[0]->post_type ) {
@@ -192,6 +214,7 @@ class Smart404Page {
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
$new_template = locate_template( array( $this->template ) );
197
if ( '' != $new_template ) {
@@ -226,7 +249,7 @@ class Smart404Page {
226
// show title - Customizr Compatibility Mode
227
function show404title_customizr_mode( $title ) {
228
if ( ! $this->settings['404page_native'] ) {
229
- return '<h1 class="entry-title">' . get_the_title( $this->settings['404page_page_id'] ) . '</h1>';
230
} else {
231
return $title;
232
}
@@ -235,7 +258,7 @@ class Smart404Page {
235
// show content - Customizr Compatibility Mode
236
function show404_customizr_mode( $content ) {
237
if ( ! $this->settings['404page_native'] ) {
238
- return '<div class="entry-content">' . apply_filters( 'the_content', get_post_field( 'post_content', $this->settings['404page_page_id'] ) ) . '</div>';
239
} else {
240
return $content;
241
}
@@ -245,7 +268,7 @@ class Smart404Page {
245
// change article selectors - Customizr Compatibility Mode
246
function show404articleselectors_customizr_mode( $selectors ) {
247
if ( ! $this->settings['404page_native'] ) {
248
- return 'id="post-' . $this->settings['404page_page_id'] . '" ' . 'class="' . join( ' ', get_post_class( 'row-fluid', $this->settings['404page_page_id'] ) ) . '"';
249
} else {
250
return $selectors;
251
}
@@ -272,7 +295,9 @@ class Smart404Page {
272
function admin_css() {
273
echo '<style type="text/css">#select404page {width: 100%; }';
274
if ( $this->settings['404page_page_id'] > 0 ) {
275
- echo ' #the-list #post-' . $this->settings['404page_page_id'] . ' .column-title {min-height: 32px; background-position: left top; background-repeat: no-repeat; background-image: url(' . plugins_url( 'pluginicon.png', __FILE__ ) . '); padding-left: 40px;}';
276
}
277
echo '</style>';
278
}
@@ -321,7 +346,7 @@ class Smart404Page {
321
322
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>';
323
324
- } elseif ( defined( 'POLYLANG_VERSION' ) ) {
325
326
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>';
327
@@ -341,22 +366,25 @@ class Smart404Page {
341
342
// this function hides the selected page from the list of pages
343
function exclude_404page( $query ) {
344
- if ( $this->settings['404page_page_id'] > 0 ) {
345
global $pagenow;
346
347
$post_type = $query->get( 'post_type' );
348
349
// as of v 2.3 we check the post_type on front end
350
if( ( is_admin() && ( 'edit.php' == $pagenow && !current_user_can( 'create_users' ) ) ) || ( ! is_admin() && ( !empty( $post_type) && ( ('page' === $post_type || 'any' === $post_type) || ( is_array( $post_type ) && in_array( 'page', $post_type ) ) ) )) ) {
351
- $pageid = $this->settings['404page_page_id'];
352
353
- if ( ! is_admin() ) {
354
- $pageid = $this->get_page_id( $pageid );
355
}
356
357
// as of v 2.3 we add the ID of the 404 page to post__not_in
358
// using just $query->set() overrides existing settings but not adds a new setting
359
- $query->set( 'post__not_in', array_merge( (array)$query->get( 'post__not_in', array() ), array( $pageid ) ) );
360
361
}
362
}
@@ -364,8 +392,8 @@ class Smart404Page {
364
365
// this function removes the 404 page from get_pages result array
366
function remove_404page_from_array( $pages, $r ) {
367
- if ( $this->settings['404page_page_id'] > 0 ) {
368
- $pageid = $this->get_page_id( $this->settings['404page_page_id'] );
369
for ( $i = 0; $i < sizeof( $pages ); $i++ ) {
370
if ( $pages[$i]->ID == $pageid ) {
371
unset( $pages[$i] );
@@ -438,7 +466,7 @@ class Smart404Page {
438
439
// returns the selected method
440
private function get_404page_method() {
441
- if ( defined( 'ICL_SITEPRESS_VERSION' ) || defined( 'POLYLANG_VERSION' ) ) {
442
// WPML or Polylang is active
443
return 'CMP';
444
} else {
@@ -456,20 +484,27 @@ class Smart404Page {
456
return (bool)get_option( '404page_fire_error', true );
457
}
458
459
- // this function gets the id of the translated page if WPML or Polylang is active - otherwise the original pageid is returned
460
- private function get_page_id( $pageid ) {
461
462
- if ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
463
464
- // WPML is active
465
- $pageid = apply_filters( 'wpml_object_id', $pageid, 'page', true );
466
467
- } elseif ( defined( 'POLYLANG_VERSION' ) ) {
468
469
- // Polylang is active
470
- $translatedpageid = pll_get_post( $pageid );
471
- if ( !empty( $translatedpageid ) && 'publish' == get_post_status( $translatedpageid ) ) {
472
- $pageid = $translatedpageid;
473
}
474
475
}
@@ -478,6 +513,41 @@ class Smart404Page {
478
479
}
480
481
// make plugin expandable
482
function do_404page_action() {
483
do_action( '404page_after_404' );
@@ -574,7 +644,7 @@ class Smart404Page {
574
function pp_404_get_the_title() {
575
$title = '';
576
if ( $this->settings['404page_page_id'] > 0 && $this->settings['404page_native'] ) {
577
- $title = get_the_title( $this->settings['404page_page_id'] );
578
}
579
return $title;
580
}
@@ -588,7 +658,7 @@ class Smart404Page {
588
function pp_404_get_the_content() {
589
$content = '';
590
if ( $this->settings['404page_page_id'] > 0 && $this->settings['404page_native'] ) {
591
- $content = apply_filters( 'the_content', get_post_field( 'post_content', $this->settings['404page_page_id'] ) );
592
}
593
return $content;
594
}
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.4
7
+ Author: Peter's Plugins (formerly 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
if ( ! defined( 'WPINC' ) ) {
15
die;
16
}
31
public function __construct() {
32
$this->plugin_name = '404page';
33
$this->plugin_slug = '404page';
34
+ $this->version = '2.4';
35
$this->get_settings();
36
+ $this->load();
37
}
38
39
// get all settings
45
// $this->settings['404page_method'] = $this->get_404page_method(); --> moved to set_mode in v 2.2 because this may be too early here
46
$this->settings['404page_native'] = false;
47
}
48
+
49
+ // load
50
+ // this function was introduced in v 2.4 and runs the init() function on firing of init action to ensure everything is loaded properly
51
+ private function load() {
52
+
53
+ add_action( 'init', array( $this, 'init' ) );
54
+
55
+ }
56
57
+ // do plugin init
58
+ // as of v 2.4 this runs after init action has fired to ensure everything is loaded properly
59
+ function init() {
60
61
// as of v 2.2 always call set_mode
62
+ // as of v 2.4 we do not need to add an init action hook
63
+ $this->set_mode();
64
65
if ( !is_admin() ) {
66
100
} elseif ( $this->settings['404page_method'] != 'STD' ) {
101
102
// Compatibility Mode
103
+ // As of v 2.4 we use the the_posts filter instead of posts_results, because the posts array is internally processed after posts_results fires
104
+ add_filter( 'the_posts', array( $this, 'show404_compatiblity_mode' ), 999 );
105
106
} else {
107
121
function show404_standard_mode( $template ) {
122
123
global $wp_query;
124
+ $pageid = $this->get_page_id();
125
if ( $pageid > 0 ) {
126
if ( ! $this->settings['404page_native'] ) {
127
$wp_query = null;
142
function show404_compatiblity_mode( $posts ) {
143
144
// remove the filter so we handle only the first query - no custom queries
145
+ remove_filter( 'the_posts', array( $this, 'show404_compatiblity_mode' ), 999 );
146
147
+ $pageid = $this->get_page_id();
148
if ( $pageid > 0 && ! $this->settings['404page_native'] ) {
149
if ( empty( $posts ) && is_main_query() && !is_robots() && !is_home() && !is_feed() && !is_search() && !is_archive() && ( !defined('DOING_AJAX') || !DOING_AJAX ) ) {
150
151
// 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
152
$this->postid = $pageid;
153
+
154
+ // as of v 2.4 we use the the_posts filter instead of posts_results
155
+ // therefore we have to reset $wp_query
156
+ // resetting $wp_query also forces us to remove the pre_get_posts action plus the get_pages filter
157
+
158
+ remove_action( 'pre_get_posts', array ( $this, 'exclude_404page' ) );
159
+ remove_filter( 'get_pages', array ( $this, 'remove_404page_from_array' ), 10, 2 );
160
+
161
+ global $wp_query;
162
+ $wp_query = null;
163
+ $wp_query = new WP_Query();
164
+ $wp_query->query( 'page_id=' . $pageid );
165
+ $wp_query->the_post();
166
+
167
+ $this->template = get_page_template();
168
+
169
+ $posts = $wp_query->posts;
170
+
171
+ $wp_query->rewind_posts();
172
+
173
+
174
add_action( 'wp', array( $this, 'do_404_header' ) );
175
add_filter( 'body_class', array( $this, 'add_404_body_class' ) );
176
add_filter( 'template_include', array( $this, 'change_404_template' ), 999 );
177
178
$this->do_404page_action();
179
180
} elseif ( 1 == count( $posts ) && 'page' == $posts[0]->post_type ) {
214
215
// this function overrides the page template in compatibilty mode
216
function change_404_template( $template ) {
217
+
218
// 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
219
$new_template = locate_template( array( $this->template ) );
220
if ( '' != $new_template ) {
249
// show title - Customizr Compatibility Mode
250
function show404title_customizr_mode( $title ) {
251
if ( ! $this->settings['404page_native'] ) {
252
+ return '<h1 class="entry-title">' . get_the_title( $this->get_page_id() ) . '</h1>';
253
} else {
254
return $title;
255
}
258
// show content - Customizr Compatibility Mode
259
function show404_customizr_mode( $content ) {
260
if ( ! $this->settings['404page_native'] ) {
261
+ return '<div class="entry-content">' . apply_filters( 'the_content', get_post_field( 'post_content', $this->get_page_id() ) ) . '</div>';
262
} else {
263
return $content;
264
}
268
// change article selectors - Customizr Compatibility Mode
269
function show404articleselectors_customizr_mode( $selectors ) {
270
if ( ! $this->settings['404page_native'] ) {
271
+ return 'id="post-' . $this->get_page_id() . '" ' . 'class="' . join( ' ', get_post_class( 'row-fluid', $this->get_page_id() ) ) . '"';
272
} else {
273
return $selectors;
274
}
295
function admin_css() {
296
echo '<style type="text/css">#select404page {width: 100%; }';
297
if ( $this->settings['404page_page_id'] > 0 ) {
298
+ foreach ( $this->get_all_page_ids() as $pid ) {
299
+ echo ' #the-list #post-' . $pid . ' .column-title .row-title:before { content: "404"; background-color: #333; color: #FFF; display: inline-block; padding: 0 5px; margin-right: 10px; }';
300
+ }
301
}
302
echo '</style>';
303
}
346
347
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>';
348
349
+ } elseif ( defined( 'xxxPOLYLANG_VERSION' ) ) {
350
351
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>';
352
366
367
// this function hides the selected page from the list of pages
368
function exclude_404page( $query ) {
369
+ $pageid = $this->get_page_id();
370
+ if ( $pageid > 0 ) {
371
global $pagenow;
372
373
$post_type = $query->get( 'post_type' );
374
375
// as of v 2.3 we check the post_type on front end
376
if( ( is_admin() && ( 'edit.php' == $pagenow && !current_user_can( 'create_users' ) ) ) || ( ! is_admin() && ( !empty( $post_type) && ( ('page' === $post_type || 'any' === $post_type) || ( is_array( $post_type ) && in_array( 'page', $post_type ) ) ) )) ) {
377
378
+ // as of v 2.4 we hide all translations in admin for WPML
379
+ if ( is_admin() ) {
380
+ $pageids = $this->get_all_page_ids();
381
+ } else {
382
+ $pageids = array( $pageid );
383
}
384
385
// as of v 2.3 we add the ID of the 404 page to post__not_in
386
// using just $query->set() overrides existing settings but not adds a new setting
387
+ $query->set( 'post__not_in', array_merge( (array)$query->get( 'post__not_in', array() ), $pageids ) );
388
389
}
390
}
392
393
// this function removes the 404 page from get_pages result array
394
function remove_404page_from_array( $pages, $r ) {
395
+ $pageid = $this->get_page_id();
396
+ if ( $pageid > 0 ) {
397
for ( $i = 0; $i < sizeof( $pages ); $i++ ) {
398
if ( $pages[$i]->ID == $pageid ) {
399
unset( $pages[$i] );
466
467
// returns the selected method
468
private function get_404page_method() {
469
+ if ( defined( 'ICL_SITEPRESS_VERSION' ) || defined( 'xxxPOLYLANG_VERSION' ) ) {
470
// WPML or Polylang is active
471
return 'CMP';
472
} else {
484
return (bool)get_option( '404page_fire_error', true );
485
}
486
487
+ // as of version 2.4 this function returns the page id of the 404 page in the current language
488
+ // in previous versions this functions required a parameter and only did the translation if WPML or Polylang is active
489
+ // now we have all in one function
490
+ private function get_page_id() {
491
492
+ $pageid = $this->settings['404page_page_id'];
493
+
494
+ if ( $pageid > 0 ) {
495
+
496
+ if ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
497
498
+ // WPML is active
499
+ $pageid = apply_filters( 'wpml_object_id', $pageid, 'page', true );
500
501
+ } elseif ( defined( 'POLYLANG_VERSION' ) ) {
502
503
+ // Polylang is active
504
+ $translatedpageid = pll_get_post( $pageid );
505
+ if ( !empty( $translatedpageid ) && 'publish' == get_post_status( $translatedpageid ) ) {
506
+ $pageid = $translatedpageid;
507
+ }
508
}
509
510
}
513
514
}
515
516
+ // if WPML is active this function returns an array of all page ids in all available languages
517
+ // otherwise it returns the page id as array
518
+ // introduced in v 2.4
519
+ private function get_all_page_ids() {
520
+
521
+ if ( defined( 'ICL_SITEPRESS_VERSION' ) ) {
522
+
523
+ // WPML is active
524
+ // get an array for all translations
525
+
526
+ $pageid = $this->settings['404page_page_id'];
527
+ $pages = array( $pageid );
528
+ if ( $pageid > 0 ) {
529
+ $languages = apply_filters( 'wpml_active_languages', NULL );
530
+ if ( !empty( $languages ) ) {
531
+ foreach( $languages as $l ) {
532
+ $p = apply_filters( 'wpml_object_id', $pageid, 'page', false, $l['language_code'] );
533
+ if ( $p ) {
534
+ $pages[] = $p;
535
+ }
536
+ }
537
+ }
538
+ }
539
+ $pageids = array_unique( $pages, SORT_NUMERIC );
540
+
541
+ } else {
542
+
543
+ $pageids = array( $this->get_page_id() );
544
+
545
+ }
546
+
547
+ return $pageids;
548
+
549
+ }
550
+
551
// make plugin expandable
552
function do_404page_action() {
553
do_action( '404page_after_404' );
644
function pp_404_get_the_title() {
645
$title = '';
646
if ( $this->settings['404page_page_id'] > 0 && $this->settings['404page_native'] ) {
647
+ $title = get_the_title( $this->get_page_id() );
648
}
649
return $title;
650
}
658
function pp_404_get_the_content() {
659
$content = '';
660
if ( $this->settings['404page_page_id'] > 0 && $this->settings['404page_native'] ) {
661
+ $content = apply_filters( 'the_content', get_post_field( 'post_content', $this->get_page_id() ) );
662
}
663
return $content;
664
}
pluginicon.png CHANGED
Binary file
readme.txt CHANGED
@@ -4,7 +4,7 @@ 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.7
7
- Stable tag: 2.3
8
License: GPLv2 or later
9
License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
@@ -12,29 +12,31 @@ Custom 404 the easy way! Set any page as custom 404 error page. No coding needed
12
13
== Description ==
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
https://www.youtube.com/watch?v=VTL07Lf0IsY
20
21
- Create your custom 404 Page as a normal WordPress Page using the full power of WordPress. You can use a Custom Page Template or Custom Fields, you can set a Featured Image - everything like on every other Page. Then go to 'Appearance' -> '404 Error Page' from your WordPress Dashbord and select the created Page as your 404 error page. That's it!
22
-
23
= Why you should choose this plugin =
24
25
* Different from other similar plugins the 404page plugin **does not create redirects**. That’s **quite important** because a correct code 404 is delivered which tells search engines that the page does not exist and has to be removed from the index. A redirect would result in a HTTP code 301 or 302 and the URL would remain in the search index.
26
* Different from other similar plugins the 404page plugin **does not create additional server requests**.
27
28
- = Translations =
29
-
30
- 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).
31
32
- **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/).
33
34
= Do you like the 404page Plugin? =
35
36
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.
37
38
= More plugins from Peter =
39
40
* **[hashtagger](https://wordpress.org/plugins/hashtagger/)** - Use hashtags in WordPress
@@ -80,6 +82,13 @@ The 404page plugin adds a CSS class `error404` to the `<body>` tag which can be
80
81
== Changelog ==
82
83
= 2.3 (2016-11-21) =
84
* a few minor bug fixes solve some problems with page templates in certain combinations
85
@@ -135,6 +144,12 @@ The 404page plugin adds a CSS class `error404` to the `<body>` tag which can be
135
136
== Upgrade Notice ==
137
138
= 2.2 =
139
Enhanced compatibility. Automated Operating Method select removed. Several fixes.
140
@@ -152,6 +167,7 @@ Editing of the 404 page is now possible directly from settings page. Portuguese
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/)
@@ -174,7 +190,7 @@ Editing of the 404 page is now possible directly from settings page. Portuguese
174
* [Zerif Lite](http://themeisle.com/themes/zerif-lite/)
175
176
= The 404page plugin was sucessfully tested by the author with the following starter themes =
177
- * [Bones}(http://themble.com/bones/)
178
* [JointsWP](http://jointswp.com/)
179
* [undersores](http://underscores.me/)
180
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.7
7
+ Stable tag: 2.4
8
License: GPLv2 or later
9
License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
12
13
== Description ==
14
15
+ Create your custom 404 Page as a normal WordPress Page using the full power of WordPress. You can use a Custom Page Template or Custom Fields, you can set a Featured Image - everything like on every other Page. Then go to 'Appearance' -> '404 Error Page' from your WordPress Dashbord and select the created Page as your 404 error page. That's it!
16
17
+ = Watch the video =
18
19
https://www.youtube.com/watch?v=VTL07Lf0IsY
20
21
= Why you should choose this plugin =
22
23
* Different from other similar plugins the 404page plugin **does not create redirects**. That’s **quite important** because a correct code 404 is delivered which tells search engines that the page does not exist and has to be removed from the index. A redirect would result in a HTTP code 301 or 302 and the URL would remain in the search index.
24
* Different from other similar plugins the 404page plugin **does not create additional server requests**.
25
26
+ = More information =
27
28
+ See [Plugin Homepage](http://petersplugins.com/free-wordpress-plugins/404page/) and [Plugin Doc](http://petersplugins.com/docs/404page/).
29
30
= Do you like the 404page Plugin? =
31
32
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.
33
34
+ = Translations =
35
+
36
+ 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).
37
+
38
+ **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/).
39
+
40
= More plugins from Peter =
41
42
* **[hashtagger](https://wordpress.org/plugins/hashtagger/)** - Use hashtags in WordPress
82
83
== Changelog ==
84
85
+ = 2.4 (2017-03-08) =
86
+ * ensure that all core files are loaded properly ([See Topic](https://wordpress.org/support/topic/had-to-deactivate-404page-to-make-wordpress-correctly))
87
+ * Polylang plugin does no longer require Compatibility Mode ([See Topic](https://wordpress.org/support/topic/still-displaying-the-themes-404-page-with-polylang/))
88
+ * hide all translations if WPML is installed and "Hide 404 page" is active (thanks to the [WPML](https://wpml.org/) guys for pointing me at this)
89
+ * post status fix ([See topic](https://wordpress.org/support/topic/doesnt-work-with-custom-post-status/))
90
+ * [Enfold theme](https://themeforest.net/item/enfold-responsive-multipurpose-theme/4519990?ref=petersplugins) issue fix (thanks to the guys at [Kriesi.at](http://www.kriesi.at/) for supporting me)
91
+
92
= 2.3 (2016-11-21) =
93
* a few minor bug fixes solve some problems with page templates in certain combinations
94
144
145
== Upgrade Notice ==
146
147
+ = 2.4 =
148
+ Version 2.4 fixes several issues. See [changelog](https://wordpress.org/plugins/404page/changelog/) for details.
149
+
150
+ = 2.3 =
151
+ A few minor bug fixes solve some problems with page templates in certain combinations.
152
+
153
= 2.2 =
154
Enhanced compatibility. Automated Operating Method select removed. Several fixes.
155
167
= The 404page plugin was sucessfully tested by the author with the following themes =
168
* [Athena](https://wordpress.org/themes/athena/)
169
* [Customizr](https://wordpress.org/themes/customizr/) (Read more about [Customizr Compatibility Mode](http://petersplugins.com/docs/404page/#settings_operating_method))
170
+ * [Enfold](https://themeforest.net/item/enfold-responsive-multipurpose-theme/4519990?ref=petersplugins)
171
* [evolve](https://wordpress.org/themes/evolve/)
172
* [GeneratePress](https://wordpress.org/themes/generatepress/)
173
* [Graphene](https://wordpress.org/themes/graphene/)
190
* [Zerif Lite](http://themeisle.com/themes/zerif-lite/)
191
192
= The 404page plugin was sucessfully tested by the author with the following starter themes =
193
+ * [Bones](http://themble.com/bones/)
194
* [JointsWP](http://jointswp.com/)
195
* [undersores](http://underscores.me/)
196