I have a challenge where you guys might help. I do have an REST interface from where get some JSON data to fill the necessary post / page data like headlines, copy and so on. On the other hand there's WordPress handling 404's on URIs that do not exists. So lets face the following scenario.
User requests the URI www.webpage.com/im-not-there/ and because that post / page doesn't exist it send you to the 404.php template. So far. so good, but this is where it becomes tricky.
Before I want WP to send the 404 I want to query the REST interface, asking it if the page exist (sure it's a bit more complicated as this ;) ). So possible answers from the REST interface could be TRUE or FALSE.
On TRUE I want to let WP go where it belongs, but on FALSE I want to "put" my data into the WP file. For that I do have the proper code and use the right hooks.
There might be the case that the post / page doesn't exist so the output (404) is correct.
Easier explanation:
User requests URI -> page / post exists -> requested template and WP stuff
User requests URI -> page / post doesn't exist -> ask REST interface and it returns
-> TRUE -> tell WP "don't use 404.php but use template-xy.php" and do your stuff as you're used to
-> FALSE -> standard WP behaviour.
Found out the following:
WP codex says cleary: "Loading a different template is not a good use of this action hook". The referenced hook is 'template_redirect'
Using template_include - see the codex example - causes further errors like the page is properly loaded but <title> is still from 404.php template
https://codex.wordpress.org/Plugin_API/Filter_Reference/template_include
Sure I can re-add all the neccessary filters like option_template and option_stylesheet and so on but is this really the way?
Codex says to the "wp" hook the following: "This hook is one effective place to perform any high-level filtering or validation, following queries, but before WordPress does any routing, processing, or handling. [...]"
From this point I'm not getting any further.
Further reading:
https://developer.wordpress.org/reference/classes/wp/handle_404/
Setup
Vagrant & PuPHPet
Nginx
MySQL 5.6
PHP 5.6
WordPress 4.6.1
No Plugins activated
Pretty URLs
Restrictions:
no core overrides
can't use server-side handling
using a filter on template_include is too late and causes further "errors" e.g. <title>
Sorry for not posting all codex links but Stackoverflow won't let me. :)
Thank you very much
Found the solution, I missed one but important step!
To set the HTTP header from 404 to 200 and also tell WP hat everything wen'T well.
So to use the codex example this is the solution on a 404
add_filter( 'template_include', 'portfolio_page_template', 99 );
function portfolio_page_template( $template ) {
global $wp_query;
if ( $wp_query->is_404 ) { // TRUE
$new_template = locate_template( array( 'no-404-template.php' ) );
if ( '' != $new_template ) {
if ($wp_query->is_404) {
$wp_query->is_404 = FALSE;
$wp_query->is_archive = TRUE;
}
header("HTTP/1.1 200 OK");
return $new_template ;
}
}
return $template;
}
Related
I want user to type any URL, example:
mywebsite.com/helloworld
After, with PHP i'd like to take slug helloworld, and print it on the page.
By default Wordpress shows 404 page. My idea was to disable this page, but not sure if there's a better solution.
How i can achieve that?
add_filter( 'pre_handle_404', function() {
# you can do anything you want here but the easiest and safest is
# wp_redirect( 'your url with query parameters from the failing 404 url' );
# exit();
return FALSE;
} );
404 is one of many HTTP Status Codes and as such if you completely remove the page, you'll need to both disable it in WordPress and on your web server, eg Apache or Nginx. This is not advised as it will make browsers display legitimate 404's with uncontrollable/undesirable responses.
If your question is "the default/my templates 404 page is terrible and I want to change it" refer to the Codex page on custom 404 page or use one of the numerous plugins designed to template error pages.
I would also, personally, advise against directing error pages to a page of your choosing, eg your homepage. This does very little except confuse people wondering why example.com/helloworld goes to example.com. From a programmers perspective, it could add time to your development as you may find it harder to diagnose why you're getting redirected to your homepage rather than it coming up with 404 or 500 which each tell you different information.
To go off of #magenta you can add conditions to this as well. This is what I did:
add_action( 'pre_handle_404', function() {
global $wp_query;
if(!$wp_query->found_posts){
if($wp_query->query['post_type']=="clients"){
wp_redirect( '/login' );
exit;
}
}
return FALSE;
} );
I have been building a wordpress plugin that displays information on the site. This data has been POSTed via cURL to a page in my plugins/[plugin_name]/inc/ directory (update.php) and runs the relevant function required to update the database. The pluging works fine, but when I submitted it for review, I have two remaining issues that I can't seem to solve:
1. Allowing Direct File Access to plugin files
...avoid this by putting this code at the top of all php files:
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
Surely I need direct access to this file to send the POST data to? Or is there another way I should do this?
2. Calling core loading files directly
Including wp-config.php, wp-blog-header.php, wp-load.php, or pretty much any other WordPress core file that you have to call directly via an include is not a good idea and we cannot approve a plugin that does so unless it has a very good reason to load the file(s). It is prone to failure since not all WordPress installs have the exact same file structure.
Usually plugins will include wp-config.php or wp-load.php in order to gain access to core WordPress functions, but there are much better ways to do this. It's best if you tie your processing functions (the ones that need but don't have access to core functions) into an action hook, such as "init" or "admin_init".
At the top of the same file (update.php) I have included as such:
require( dirname(dirname(dirname(dirname(dirname(__FILE__))))) . '\wp-load.php' );
Because I need to access the core wp functions and classes such as
$wpdb->prepare
And I'm not sure how I can otherwise do this. I would appreciate any help with these problems!
As for 1. You should create a method in your plugin that handles the post data and runs the CURL request.
As for 2. I think you can get away with global $wpdb;
https://codex.wordpress.org/Class_Reference/wpdb
Here's what I did, if anyone else has this question:
1. I added this function and hook to my plugin file:
//GET POST DATA IF APPLICABLE
function wp_getpostdata() {
if ( isset( $_POST['user'] ) && isset( $_POST['pass'] ) && isset( $_POST['op'] )) {
require 'inc/update.php';
exit;
} // end if
} // end wp_getpostdata
add_action( 'init', 'wp_getpostdata' );`
2. Removed the wp-load include and added
global $wpdb;
to my update.php file as Kyra suggested. And finally...
3. Changed the POST target to my website address.
Works like a charm - hope others find it useful!
In order to achieve the magic of http://someserver.com/blog/ pointing to myserver.wpengine.com/blog/ I had to create a multisite in wpengine.
From there I was able to point to the backend successfully with a basic varnish rewrite.
So, now the page shows up at someserver-dot-com/blog/ and appears to write post links to someserver-dot-com/blog/some-post when I set 'home' to 'http:/someserver-dot-com/blog'.
But, when I navigate to those posts, I get an internal WP "page not found". It's not actually a 404, because if I go to http://someserver.com/blog/some-post it returns the page properly, which means the multi-site and references are working properly. WTF!?!
I've checked the database, and everything appears to be proper in the DB tables.
To me, this is something inside some wordpress php function, cache or something within wpengine. I've definitely purged the cache of all the things from the network login in the wordpress admin plugin for wpengine. Has anyone experienced this problem?
It's been a few days of debugging, and I've read every man page in existence, and tried setting paths via wp-config, and all that does is increase complexity of writes, and it doesn't seem like it works either.
Astonishingly,
This works:
In functions.php, right after php tags, add this line:
update_option('home','http://someblog.com/blog/');
Obviously, this should just add that to the 'home' keypair in the wp_2_options table, but actually it does something else. It fires this at some point:
$notoptions = wp_cache_get( 'notoptions', 'options' );
if ( is_array( $notoptions ) && isset( $notoptions[$option] ) ) {
unset( $notoptions[$option] );
wp_cache_set( 'notoptions', $notoptions, 'options' );
}
I believe this deletes option cache, and currently either wordpress or wpengine has an issue with some cache, and the plain vanilla 'home' keypair should have worked right in the first place, leaving 'site' as 'someblog.wpengine.com' and leaving all wp_config as the plain vanilla multi-site/root configs that wpengine will set-up.
I've been looking for hours trying to find a straightforward answer to this but I just can't seem to find anything out there which tackles this issue. There are numerous examples for rewriting standard URLs, but nothing in-terms of rewriting pages from within a custom plugin.
I've created a custom plugin with a special directory in it called test. The test directory has several pages which are blah.php and shmeh.php. Is it possible to create rewrite rules to these pages i.e. http://example.com/blah, http://example.com/shmeh
Thank you very much for all the help.
So essentially what you are looking for, is to have Wordpress load a specific page template (blah.php) when the user visits http://example.com/blah/. Also, you need it to to be completely generated in your plug-in without actually creating any pages or posts. You are on the right track. What you want to do here is create a rewrite rule that utilizes a specific query var to load the page. Here it is step by step:
Step 1: Rewrite rules
http://codex.wordpress.org/Function_Reference/add_action
http://codex.wordpress.org/Plugin_API/Action_Reference/init
http://codex.wordpress.org/Rewrite_API/add_rewrite_rule
/* Rewrite Rules */
add_action('init', 'yourpluginname_rewrite_rules');
function yourpluginname_rewrite_rules() {
add_rewrite_rule( 'blah/?$', 'index.php?blah=true', 'top' );
}
So in the above code, your just telling Wordpress that example.com/blah/ should be treated as if the user were visiting example.com/index.php?blah=true. Now "blah" is a query var that you will set up in the next function below. Query vars are just what Wordpress calls $_GET variables. However they must be registered with Wordpress so it can properly store the value (which is "true" in this case). We will do that below in the next function. It's also worth noting the third setting in the function "top", which gives this rewrite rule priority over other rewrite rules. Alternatively, setting it to "bottom" would check that no other rewrite rules match first before using this one.
Step 2: Query Vars
http://codex.wordpress.org/Function_Reference/add_filter
http://codex.wordpress.org/Plugin_API/Filter_Reference/query_vars
/* Query Vars */
add_filter( 'query_vars', 'yourpluginname_register_query_var' );
function yourpluginname_register_query_var( $vars ) {
$vars[] = 'blah';
return $vars;
}
In the code above, your just registering the query var "blah" with Wordpress. That way, when someone visits example.com/blah/, which your rewrite rule tells Wordpress to treat it like they are visiting example.com/index.php?blah=true, Wordpress actually bothers to save it's value (which is set to true). This is so you can use it in the next function, which loads the template you want when users visit your url.
Step 3: Template Include
http://codex.wordpress.org/Function_Reference/add_filter
http://codex.wordpress.org/Plugin_API/Filter_Reference/template_include
http://codex.wordpress.org/Class_Reference/WP_Query#Interacting_with_WP_Query
http://codex.wordpress.org/Function_Reference/plugin_dir_path
/* Template Include */
add_filter('template_include', 'yourpluginname_blah_template_include', 1, 1);
function yourpluginname_blah_template_include($template)
{
global $wp_query; //Load $wp_query object
$page_value = $wp_query->query_vars['blah']; //Check for query var "blah"
if ($page_value && $page_value == "true") { //Verify "blah" exists and value is "true".
return plugin_dir_path(__FILE__).'test/blah.php'; //Load your template or file
}
return $template; //Load normal template when $page_value != "true" as a fallback
}
In the code above, you are simply telling Wordpress to use your blah.php template any time the query var "blah" is present and set to true. In this case it is present because a user is visiting a url with a rewrite rule that utilizes the "blah" query var. The function checks if the "blah" query var is present, then checks if "blah" is set to true, and if so loads the template. Also note that the template path is test/blah.php. You are using plugin_dir_path(__FILE__) to relatively include the template based on the location of your plugin. That way it's relative as a plug-in should be.
Step 4: The Actual Template (blah.php)
http://codex.wordpress.org/Function_Reference/get_header
http://codex.wordpress.org/Function_Reference/get_footer
http://codex.wordpress.org/Function_Reference/get_sidebar
Your template file will need to load the header, footer, and sidebar itself. When using template_include, Wordpress will not automatically load the header and footer as if you were using a page template. Be sure your template file calls get_header(), get_footer(), and get_sidebar() so that you get your complete layout.
Notes
Hope this helps, I was searching for something similar the other day and had to figure it out the hard way. It's also worth noting that I have prefixed all of the functions as "yourpluginname_". You can change this to whatever you want your prefix to be, but be sure to update the function names to match as well.
I now need to make a Kohana 3 site have a Wordpress blog.
I've seen Kerkness' Kohana For Wordpress, but it seems to be the opposite of what I want.
Here are the options I have thought of
Style a template to look exactly like the Kohana site (time consuming, non DRY and may not work)
Include the blog within an iframe (ugly as all hell)
cURL the Wordpress pages in. This of course means I will need to create layers between comment posting, etc, which sounds like too much work.
Is there any way I can include a Wordpress blog within an existing Kohana application? Do you have any suggestions?
I found this post detailing the Kohana for Wordpress plugin, but I am still confused as to how it works.
Does it mean from within Wordpress, I can call a Kohana controller? Is this useful to me in my situation?
Oh, I did this a long time ago (actually towards the end of last year).
Assumptions
You are using Wordpress permalinks with mod_rewrite or a similar option.
You don't have register_globals() turned on. Turn it off to ensure Wordpress's global variables don't get removed by Kohana.
Renaming
First, you need to rename the __() function in Kohana. Say, you rename it to __t(). You'd need to replace it everywhere it appears, which if you use an editor like Netbeans that can find usages of a function or method is pretty easy.
Hierarchy
The next decision you need to make is whether you want to load Wordpress inside Kohana or Kohana inside Wordpress. I prefer the latter, which I'm documenting below. I could document the latter if you'd prefer to go that route.
I put the kohana directory in my theme directory.
In your functions.php file of your theme, simply
include TEMPLATEPATH . '/kohana/index.php';
Kohana Configuration
Your Kohana's index.php file also needs some work. Remove the lines that look for install.php as they will load ABSPATH . WPINC . 'install.php' instead and display an error message in your wordpress admin. You also need to change the error_reporting as at the moment Wordpress fails E_STRICT.
You will very likely need to remove the last few lines of your bootstrap (in Kohana) that process the request, and change your init:
Kohana::init(array(
'base_url' => get_bloginfo('home') . '/',
'index_file' => '',
));
In either your Wordpress functions.php file or in your bootstrap, add these lines:
remove_filter('template_redirect', 'redirect_canonical');
add_filter('template_redirect', 'Application::redirect_canonical');
where Application is a class of your choosing.
My code for the Application class (without the class definition) is:
public static function redirect_canonical($requested_url=null, $do_redirect=true)
{
if (is_404() && self::test_url())
{
echo Request::instance()->execute()->send_headers()->response;
exit;
}
redirect_canonical($requested_url, $do_redirect);
}
public static function test_url($url = NULL)
{
if ($url === NULL)
{
$url = str_replace('?'.$_SERVER['QUERY_STRING'], '', $_SERVER['REQUEST_URI']);
$url = trim($url, '/');
}
foreach (Route::all() as $route)
{
/* #var $route Route */
if ($params = $route->matches($url))
{
$controller = 'controller_';
if (isset($params['directory']))
{
// Controllers are in a sub-directory
$controller .= strtolower(str_replace('/', '_', $params['directory'])).'_';
}
// Store the controller
$controller .= $params['controller'];
$action = Route::$default_action;
if (isset($params['action']))
{
$action = $params['action'];
}
if (!class_exists($controller))
return false;
if (!(method_exists($controller, 'action_' . $action) || method_exists($controller, '__call')))
return false;
return true;
}
}
return false;
}
which lets Wordpress do it's redirect for any page that may have moved e.g. /about/calendar to /calendar as long as you don't have an about controller and calendar action defined.
So there you have it. Any urls not defined within Wordpress will fall to your defined controller (or use your theme's 404 template).
Additional
This isn't required, but you could put your theme's header.php under your kohana views folder (application or in a module) and from any of your theme files
echo View::factory('header')
You could do the same thing with your footer (or any other files for that matter). In your header.php, you could also do this:
if (isset($title)) echo $title; else wp_title(YOUR_OPTIONS);
That way you could in your controller
echo View::factory('header')->set('title', 'YOUR_TITLE');
To keep urls consistent, you may have to take off the / from the end of Wordpress permalinks so /%year%/%monthnum%/%day%/%postname%/ becomes /%year%/%monthnum%/%day%/%postname%, etc
Please let me know if you need any more help integrating Wordpress and Kohana.
I've actually used wordpress for the CMS of a code igniter site. This is the method i used to pull page content, not blog content, but maybe you can change it up a little to fit your needs.
In my front controller I added the wordpress header file
require('/path/to/wp-blog-header.php');
This gives you access to the 2 functions you'll need
get_page() – Get the page data from the database
wpautop() – Automatically add paragraph tags to page content
To get page data
$page_data = get_page( 4 ); // Where 4 is the page ID in wordpress
If you get this error:
Fatal error: Only variables can be
passed by reference…
You have to do it like this
$page_id = 4;
$page_data = get_page( $page_id );
because of a bug in certain versions of php
Then in the view
<?= wpautop($page_data->post_content) ?>
Hope this helps
EDIT
I installed wordpress at /blog in the filesystem. So wordpress actually runs as a blog normally. I just use this method to grab the pages
This is going to be extremely difficult, because of the way WordPress works. Specifically, it uses global variables all over the place, and because Kohana is scoped, you will not be able to access those variables.
Long story short: what you want is nearly impossible. However, if you get it working (without hacking WP), I would be really interested to see how you did it.
See here: http://www.intuitivity.org/archives/8
I figured it out yesterday :)
Another solution is to keep both Wordpress and Kohana installations completely separate. Then you create a custom Wordpress theme that will pull the header and footer from Kohana (you can create a Kohana controller for that).
Once you have the header and footer in, the blog looks integrated to your website even though it's still a completely separate installation. The advantage is that there's nothing to hack to either Wordpress or Kohana to get it working.
There's some more details about this method in this blog post: Integrating Wordpress into a Kohana application
I always thought this would be relatively easy. That is, to use WordPress as your site's back-end (for the blog part, at least) and use Kohana for serving up posts and pages. If I'm not mistaking, all you would need to do is set up your models (post, comment, page) to gather their data from the WordPress database (with or without ORM) instead of a new one.