I'm trying to integrate a Query Expansion software with Wordpress, but the wordpress search engine is an AND searcher (returns those contents that contain all the words in your query, and therefore the more extensive is the query the fewer results returns).
For that reason when i use the query with the expansion features, the Searcher returns me less results.
I would like to modify the Search's behavior, and turn it into something more like an OR searcher.
Example:
For the query " iot, internet of things", I would want those posts which contents "iot", or "internet of things, or both of them.
I've reading through this document (https://codex.wordpress.org/Class_Reference/WP_Query) and i tried to use something like this:
add_action( 'template_redirect', 'hooks_setup' , 20 );
function hooks_setup() {
if (! is_home() ) //<= you can also use any conditional tag here
return;
add_action( '__before_loop' , 'set_my_query' );
add_action( '__after_loop' , 'set_my_query', 100 );
}
function set_my_query() {
global $wp_query, $wp_the_query;
switch ( current_filter() ) {
case '__before_loop':
//replace the current query by a custom query
//Note : the initial query is stored in another global named $wp_the_query
$wp_query = new WP_Query( array(
'post_type' => 'post',
'post_status' => 'publish',
//others parameters...
) );
break;
default:
//back to the initial WP query stored in $wp_the_query
$wp_query = $wp_the_query;
break;
}
}
But I don't know which parameters i need to set in wp_query. How can I achieve this?
To answer what parameters you need to set, you have to read through the same page you mentioned. Parameters for various items (post types or categories) are defined on this page and when you want to change it all you have to do is modify the parameters.
If you dont know what query you want to do I think its hard for people to help. If you are getting less results, you can open query a bit further or obtain results in 2 queries. Read through the page and you will find its common when people want to obtain different types of data and not everything is in the loop.
Also read through this to understand more about the loop and how to reset the query and do a new one then you can obtain two result sets and use them or combine them when and where you want.
Just to give you an example for string search in posts with s as parameter from the same page Prepending a term with a hyphen will exclude posts matching that term. Eg, 'pillow -sofa' will return posts containing 'pillow' but not 'sofa' (available since Version 4.4).
Related
I am new to php, please help.
I am using this shortcode to show total number of published posts (400), it works fine. If I change ('post') to ('page') it shows total number of published pages (100) just as fine. I am trying to show total number of posts and pages (500) using one shortcode. Is it possible to add the two results and display as one total result?
function published_posts($atts) {
return wp_count_posts('post')->publish;
}
add_shortcode('posts_count', 'published_posts');
Yes, what you're attempting to do is possible. Simply assign the value of wp_count_posts() for both posts and pages to variables and then add them together in the return statement.
Example:
function published_posts( $atts ) {
$post_count = wp_count_posts( 'post' )->publish;
$page_count = wp_count_posts( 'page' )->publish;
return $post_count + $page_count;
}
add_shortcode( 'posts_count', 'published_posts' );
While this will work, I'm not convinced it's the most efficient approach you could take. It's making two trips to the database for information which could be retrieved in one. That being said, wp_count_posts() won't accept an array of post types so you'd likely have to code something from scratch.
I have read many tutorials about passing multiple variables to a post/page in wordpress, using add_rewrite_endpoint. I am currently passing 2 variables, calendar_year / calendar_month . It works good for both but separately each one. Using both like (http://myserver/mysite/availability/calendar_year/2016/calendar_month/10/) only gets the year and if I pass them on reverse, only gets the month. Availability page shows correct (No 404 error), but it fails taking the last parameter when there are the two of them. Here is my code for add_rewrite_endpoint
function booking_calendar_add_endpoints() {
add_rewrite_endpoint('calendar_year', EP_ALL);
add_rewrite_endpoint('calendar_month', EP_ALL);
}
add_action('init','booking_calendar_add_endpoints');
And this is how I get it and use it:
global $wp_query;
$year_var = $wp_query->get( 'calendar_year' );
$month_var = $wp_query->get( 'calendar_month' );
I am sure I am missing something. Does anyone have a solution for it? Thanks.
I have created two plugins. Plugin A gets the latest posts, all of them. It has an option that can remove posts by entering their ID, this is accessible via the shortcode or directly in functions.php. This works.
Plugin B gets the most popular posts using an internal analytics systems. I have a variable called $most_popular_ids which contains all of the post ID's of the highest viewed posts for that particular category. So $most_popular_ids changes depending on which page it is on. This works.
These are displayed side by side on the main pages of the website. So ideally I would like them to not show duplicate posts.
What I finally need to do is pass $most_popular_ids from plugin B to plugin A or to functions.php. This will allow me to exclude all of the most popular posts from the latest posts.
Obviously making the variable global only works in the scope of the file so that won't work. I tried creating a $_SESSION but you can't do that in Wordpress as far as I know. Most of the stuff in the plugins can't be redeclared so my include attempts didn't work either :\
Can anyone help me?
You can use sessions in WordPress, but it would probably be easier to use the wp_cache_set() and wp_cache_get() functions
For example, in Plugin B you would do something like:
wp_cache_set('mykey_most_popular_ids', $most_popular_ids);
Then in Plugin A or your functions file you can do:
$most_popular_ids = wp_cache_get('mykey_most_popular_ids);
Obviously you'd need to make sure the function in Plugin B sets the cache entry before trying to get it in Plugin A of the functions file
Here's an approach using filters. In plugin A, implement a filter that allows to set the post__not_in param of the query:
$query_args = array();
$post__not_in = apply_filters( 'check_for_most_popular_ids', false );
if( $post__not_in && is_array( $post__not_in ) )
$query_args['post__not_in'] = $post__not_in;
$query = new WP_Query( $query_args );
In plugin B, hook into the filter and pass the most popular IDs:
add_filter( 'check_for_most_popular_ids', 'send_most_popular_ids', 10, 1 );
function send_most_popular_ids( $post__not_in = false )
{
$most_popular_ids = get_most_popular_ids(); // returns array of IDs OR false
if( $most_popular_ids )
return $most_popular_ids;
return $post__not_in;
}
I would like to add/inject/append extra results into the WordPress search results.
At the moment WordPress only allows you to "adjust" the query that is being executed on its own database, but doesn't allow you to modify (or in WordPress lingo, filter) the results array.
I.e: If in WordPress I search for the term 'potato' all posts related to this term come back. I want to include results that I've obtained via a different service into the WordPress results set.
Just to clarify, I'm getting my results from a 3rd party API call. Not from the WordPress database.
Does anyone have an idea on how I can do this?
Edit: Preferably this needs to happen in my WordPress plugin without having to change search templates.
You can use pre_get_posts to add/edit your search result without changing things is search template.
To exclude pages
To exclude pages in your search results. It is possible to create an action hook that limits the search results by showing only results from posts.
The following example demonstrates how to do that:
function search_filter($query) {
if ( !is_admin() && $query->is_main_query() ) {
if ($query->is_search) {
$query->set('post_type', 'post');
}
}
}
add_action('pre_get_posts','search_filter');
Include Custom Post Types in Search Results
function search_filter($query) {
if ( !is_admin() && $query->is_main_query() ) {
if ($query->is_search) {
$query->set('post_type', array( 'post', 'movie' ) );
}
}
}
add_action('pre_get_posts','search_filter');
Include Custom / API Results
function search_filter() {
if ( is_search() ) {
// Do your API call here
// Save retrieved data in your wordpress
// This will also help to you avoid api call for repeated queries.
$post_id = wp_insert_post( $post, $wp_error ); // wp_insert_post() // Programatically insert queries result into your wordpress database
array_push( $query->api, $post_id );
}
}
add_action('pre_get_posts','search_filter');
function have_posts_override(){
if ( is_search() ) {
global $wp_query;
$api_post = $wp_query->api;
foreach ($api_post as $key) {
// This will enable you to add results you received using API call
// into default search results.
array_push($wp_query->posts, $key);
}
}
}
add_action( 'found_posts', 'have_posts_override' );
Reference:
Exclude_Pages_from_Search_Results
Include_Custom_Post_Types_in_Search_Results
The question might be old, but I had a similar problem and someone in the future maybe as well, so I'll post my (better) solution.
As said above, it would have been the cleanest solution to save the api query results in the wp_posts-table (as a custom post type maybe) and perform a normal WP-Search on them.
But in my case I had to deal with another table which cached some external data and link it to IDs of existing posts and I could not change this structure.
Therefore the Solution of Abhineet Verma (search_filter + pre_get_posts) seemed useful at first, but in the end it was not suitable for me. I was able to add additional posts to the query result, but they don't fit into the normal pagination of the results. For example, If you want to display 10 results per page and use the solution above and get twenty results from the api, you would have 30 results per page: the ten normal results, which belong to the page plus all twenty on every page. It also breaks some pagination-plugins.
So I finally solved the problem as follows. I used the filter posts_search to extend the sql-query:
add_filter('posts_search', function($sql) {
if (!$sql) {
return $sql;
}
global $wpdb;
$sqst = "select id from {$wpdb->prefix}mytable ... bla bla -> query to my custom table, wich return a bunch of IDs";
$sqlr = "AND (({$wpdb->prefix}posts.ID in ($sqst)) or (1 = 1 $sql))";
return $sqlr;
});
It looks a little bit strange but works very good. Maybe it will help someone sometimes!
so currently i'm using pods to create some individual pages for a log, filled with custom stuff.
now i want to use the comments-system for each of this pages e.g.:
mydomain.com/podpages/page1
mydomain.com/podpages/page2
mydomain.com/podpages/page3
this are not pages created with wordpress so simply adding <?php comments_template(); ?> is not working.
any ideas how to solve this problem?
thanks in advance
please leave a comment if something is unclear :)
When a comment is stored in the WordPress database, the ID of the post (or page) the comment relates to is also stored.
Trouble is, you're trying to save comments using WordPress, but for a page that it doesn't actually know about.
So, how about we create a WordPress page for each real page, but merely as a representation, so that your real pages and WordPress have a common ground for working with each other.
So, the plan here is to;
Load WordPress in the background on each of the 'real' pages.
See if a WordPress page representation already exists for the 'real' page
If it doesn't, create it, then and there
Trick WordPress into thinking we're actually viewing the representation
Carry on using all of WP's functions and 'template tags' as you would normally
This code should be somewhere at the beginning of the template file used to render your 'real' pages;
include ('../path/to/wp-load.php');
// remove query string from request
$request = preg_replace('#\?.*$#', '', $_SERVER['REQUEST_URI']);
// try and get the page name from the URI
preg_match('#podpages/([a-z0-9_-]+)#', $matches);
if ($matches && isset($matches[1])) {
$pagename = $matches[1];
// try and find the WP representation page
$query = new WP_Query(array('pagename' => $pagename));
if (!$query->have_posts()) {
// no WP page exists yet, so create one
$id = wp_insert_post(array(
'post_title' => $pagename,
'post_type' => 'page',
'post_status' => 'publish',
'post_name' => $pagename
));
if (!$id)
do_something(); // something went wrong
}
// this sets up the main WordPress query
// from now on, WordPress thinks you're viewing the representation page
}
UPDATE
I can't believe I was this stupid. Below should replace current code inside outer if;
// try and find the WP representation page - post_type IS required
$query = new WP_Query(array('name' => $pagename, 'post_type' => 'page'));
if (!$query->have_posts()) {
// no WP page exists yet, so create one
$id = wp_insert_post(array(
'post_title' => $pagename,
'post_type' => 'page',
'post_status' => 'publish',
'post_name' => $pagename,
'post_author' => 1, // failsafe
'post_content' => 'wp_insert_post needs content to complete'
));
}
// this sets up the main WordPress query
// from now on, WordPress thinks you're viewing the representation page
// post_type is a must!
wp(array('name' => $pagename, 'post_type' => 'page'));
// set up post
the_post();
P.S I think using the query_var name over pagename is better suited - it queries the slug, rather than the slug 'path'.
You'll also need to either place an input inside the form with name redirect_to and a value of the URL you'd like to redirect to, or, filter the redirect with a function hooked onto comment_post_redirect, returning the correct URL.
add
require('/path/to/wp-blog-header.php');
to include the wp files. this should give you all the functions/data you need.
Can you create pages in wordpress which display your log data? You might need a new template for this. WordPress will then have something to connect the comments to.
Do you need to use WordPress for this? If not, maybe something in this SO question helps: Unobtrusive, self-hosted comments function to put onto existing web pages
Just supply the wordpress-comment-part with a new ID - start with something your usual posts will never reach (100.000+ is your pages i.e.)
I don't know exactly if in wordpress it's a function (saveComment i.e.), but if it is so, just use it in your page with he custom ID.
You will nevertheless have to insert the Comments-form yourself.
And don't forget to modify the query that gets the news-entires that IDs over 100.000 are not entries.
Or you can write your own template that displays the standard-Worpress-stuff with IDs < 100.000, or else your pages.
Summed up, it should not be very difficult.
p.s.: If you just want to use the wordpress-login, then use any comment-system or make your own (it's an 1hour-thing) and authenticate / use the worpress-session.