Page 2 displays the same posts as page 1. What could be the problem?
Below is code from index.php It is used to sort posts by simply clicking on a link such as sort by: "price" or "random".
Pagination
<?php
previous_posts_link();
next_posts_link();
?>
Loop
<?php
$sort= $_GET['sort'];
if($sort == "A")
{
$order= "orderby=rand&posts_per_page =2";
}
if($sort == "B")
{
$order= array (
'meta_key'=>'price',
'orderby'=>'meta_value_num',
'order'=>'DESC',
'posts_per_page' => 2
);
}
?>
random
price
<?php $loop = new WP_Query($order); ?><?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
<h2><?php the_title(); ?></h2>
<?php the_excerpt(); the_meta ();?>
<?php endwhile; wp_reset_query();?>
Yourt problem is using a custom query. Why aren't you using the main query. It is totally unnecessary and a waste of resources to run another query here.
As this code is on index.php, which will be your homepage, you can simply make use of the default loop, and use pre_get_posts to alter your main query before it is run. Doing it this way doesn't require extra unnecessary database queries, and it is much cleaner
So, delete the custom query in your index.php, and replace it with the following code. This is all that you are going to need (and don't abuse the php tags :-))
<?php while (have_posts() ) : the_post(); ?>
<h2><?php the_title(); ?></h2>
<?php the_excerpt(); the_meta ();
endwhile;
previous_posts_link();
next_posts_link();
?>
Now, in functions.php, add the following
function my_custom_query($query){
if ( $query->is_home() && $query->is_main_query() ) {
$sort= $_GET['sort'];
if($sort == "A"){
$query->set( 'orderby', 'rand' );
$query->set( 'posts_per_page', '2' );
}
if($sort == "B"){
$query->set( 'meta_key', 'price' );
$query->set( 'orderby', 'meta_value_num' );
$query->set( 'order', 'DESC' );
$query->set( 'posts_per_page', '2' );
}
}
}
add_action( 'pre_get_posts', 'my_custom_query' );
If you, for some reason, need to run a custom query, remember to add the paged variable to your arguments. You can have a look at these parameters in WP_Query
$paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
$loop = new WP_Query( array( 'paged' => $paged ) );
This isn't enough though. You need to set the $max_pages parameter as well in next_posts_link( $label , $max_pages ); for pagination to work correctly. You'll need to something like this
next_posts_link( 'Older Entries', $loop->max_num_pages );
If you want to use a custom WP_Query and still want pagination to work, you must pass in the paged argument.
// what page is this? default to 1.
$paged = ( get_query_var('page') ) ? get_query_var('page') : 1;
// "A" args
$order = "orderby=rand&posts_per_page=2&paged={$paged}";
// "B" args
$order = array (
'meta_key'=>'price',
'orderby'=>'meta_value_num',
'order'=>'DESC',
'posts_per_page' => 2,
'paged' => $paged,
);
Related
I recently added an Ajax-powered load more button that loads additional blog posts to my wordpress site. I used the tutorial listed here: https://rudrastyh.com/wordpress/load-more-posts-ajax.html, and it works, but I've ran into another problem.
I have a session variable that counts the current post number. I show 10 posts per page and the counter works for the initial 10. Then I call the next 10 with ajax and instead of counting to 11, 12, 13 etc, it goes back to 1. There's clearly a problem with passing the end value (10) from the template, to the ajax handler in functions. Anyone know what could be wrong? Everything works if I don't use ajax - it's really frustrating.
Template PHP
<?php $_SESSION['the_counter'] = 0; ?>
<?php
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
$args = array(
'posts_per_page' => 10,
'paged' => $paged
);
$my_query = new WP_Query($args);
if($my_query->have_posts()): while($my_query->have_posts()) : $my_query->the_post();
get_template_part( 'template-parts/post/content', get_post_format() );
endwhile;
else:
get_template_part( 'no-results', 'home' );
endif;
if ( $my_query->max_num_pages > 1 ){
echo '</a><div class="misha_loadmore">More posts</div>';
}?>
</div>
<script>var posts_myajax = '<?php echo json_encode( $my_query->query_vars ) ?>',
current_page_myajax = 1,
max_page_myajax = <?php echo $my_query->max_num_pages ?>
</script>
<script src="/loadmore.js"></script>
<?php $my_query = null;
wp_reset_postdata();?>
Ajax Handler in functions.php
function misha_loadmore_ajax_handler(){
$args = json_decode( stripslashes( $_POST['query'] ), true );
$args['paged'] = $_POST['page'] + 1; // we need next page to be loaded
$args['post_status'] = 'publish';
query_posts( $args );
if( have_posts() ) :
// run the loop
while( have_posts() ): the_post();
// look into your theme code how the posts are inserted, but you can use your own HTML of course
// do you remember? - my example is adapted for Twenty Seventeen theme
get_template_part( 'template-parts/post/content', get_post_format() );
// for the test purposes comment the line above and uncomment the below one
// the_title();
endwhile;
endif;
die; }
add_action('wp_ajax_loadmore', 'misha_loadmore_ajax_handler');
add_action('wp_ajax_nopriv_loadmore', 'misha_loadmore_ajax_handler');
Load More JS
jQuery(function($){
$('.misha_loadmore').click(function(){
var button = $(this),
data = {
'action': 'loadmore',
'query': misha_loadmore_params.posts, // that's how we get params from wp_localize_script() function
'page' : misha_loadmore_params.current_page
};
$.ajax({
url : misha_loadmore_params.ajaxurl, // AJAX handler
data : data,
type : 'POST',
beforeSend : function ( xhr ) {
button.text('Loading...'); // change the button text, you can also add a preloader image
},
success : function( data ){
if( data ) {
button.text( 'More posts' ).prev().before(data); // insert new posts
misha_loadmore_params.current_page++;
if ( misha_loadmore_params.current_page == misha_loadmore_params.max_page )
button.remove(); // if last page, remove the button
// you can also fire the "post-load" event here if you use a plugin that requires it
// $( document.body ).trigger( 'post-load' );
} else {
button.remove(); // if no data, remove the button as well
}
}
});
});});
And this is the session code I have on the top of my blog post content template file. It increments the count by 1 for every post.
$counter = $_SESSION['the_counter'];
$counter++;
$_SESSION['the_counter'] = $counter;
At the bottom of the file, I include:
echo insert_counter($the_counter);
At a glance, I'm betting sessions aren't being set. Try adding this to your functions.php file.
add_action('init', function() {
if (!session_id()) {
session_start();
});
This will ensure that sessions are loading on every page. It's worth mentioning that sessions aren't the best way to persist data. I would recommend replacing the session with a cookie.
i need to put my $product->get_image in ajax but i don t know how to do
i want to put my $product->get_image(...) to $details = Array("..., "img"=>"$imgL");
here s my code
<?php
define('WP_USE_THEMES', false);
require_once('wp-load.php');
global $qode_options_theme16;
global $wp_query;
$sku=$_POST['id'];
$args = array('post_type' => 'product','meta_value' => $sku);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) {
$i=0;
while ( $loop->have_posts() ) : $loop->the_post(); global $product;
$imgL=$product->get_image( $size = 'shop_large', $attr = array(), $placeholder = true );
$prix = $product->get_price();
$nom = $product->get_formatted_name();
endwhile;
}
$details = Array("prix"=>"$prix", "nom"=>"$nom", "sku"=>"$sku", "img"=>"$imgL");
echo json_encode($details);
?>
thanks in advance
Please call the code like this:
$imgL=$product->get_image( 'shop_large', array(), true );
In wordpress, when a post category (or tag) is clicked, all posts that match the clicked category (or tag) is returned, because of <?php the_content(); ?>
In my case, every post has an image in it, so how can I only fetch the images when a category (or tag) is clicked? I'm not familiar what code I need to use.
Update: I'm trying not to use plugins. My apologies for not mentioning that earlier. What I'm trying to achieve is something like The Sartorialist - All posts have images, click on any category (or tag) associated with any post and only images are fetched.
Update 2: I tried this:
<?php
$args = array(
'post_type' => 'attachment',
'numberposts' => -1,
'post_status' => null,
'post_parent' => $post->ID
);
$attachments = get_posts( $args );
if ( $attachments ) {
foreach ( $attachments as $attachment ) {
echo '<li>';
echo wp_get_attachment_image( $attachment->ID, 'full' );
echo '</li>';
}
}
?>
The only weird thing is, and I'm trying to figure out, another image from the media library also shows up, without it being in any of my posts.
I also found this plugin which is very close to what I want, but unfortunately it has to be in a separate page, not the in category page.
You can achieve this with something like this:
<?php
function getImage($num) {
global $more;
$more = 1;
$link = get_permalink();
$content = get_the_content();
$count = substr_count($content, '<img');
$start = 0;
for($i=1;$i<=$count;$i++) {
$imgBeg = strpos($content, '<img', $start);
$post = substr($content, $imgBeg);
$imgEnd = strpos($post, '>');
$postOutput = substr($post, 0, $imgEnd+1);
$postOutput = preg_replace('/width="([0-9]*)" height="([0-9]*)"/', '',$postOutput);;
$image[$i] = $postOutput;
$start=$imgEnd+1;
}
if(stristr($image[$num],'<img')) { echo ''.$image[$num].""; }
$more = 0;
}
?>
source
How can i use flash messenger in zend freamwork 2? Session documentation is not yet. Anyone know it? But session libraries are there.
Update :
Zend Framework new release added FlashMessenger View Helper , found in path /library/Zend/View/Helper/FlashMessenger.php
FlashMessenger.php
Old answer :
I have written a custom view helper, for printing flash messages
In /module/Application/Module.php
public function getViewHelperConfig()
{
return array(
'factories' => array(
'flashMessage' => function($sm) {
$flashmessenger = $sm->getServiceLocator()
->get('ControllerPluginManager')
->get('flashmessenger');
$message = new \My\View\Helper\FlashMessages( ) ;
$message->setFlashMessenger( $flashmessenger );
return $message ;
}
),
);
}
Create a custom view helper in /library/My/View/Helper/FlashMessages.php
namespace My\View\Helper;
use Zend\View\Helper\AbstractHelper;
class FlashMessages extends AbstractHelper
{
protected $flashMessenger;
public function setFlashMessenger( $flashMessenger )
{
$this->flashMessenger = $flashMessenger ;
}
public function __invoke( )
{
$namespaces = array(
'error' ,'success',
'info','warning'
);
// messages as string
$messageString = '';
foreach ( $namespaces as $ns ) {
$this->flashMessenger->setNamespace( $ns );
$messages = array_merge(
$this->flashMessenger->getMessages(),
$this->flashMessenger->getCurrentMessages()
);
if ( ! $messages ) continue;
$messageString .= "<div class='$ns'>"
. implode( '<br />', $messages )
.'</div>';
}
return $messageString ;
}
}
then simple call from layout.phtml , or your view.phtml
echo $this->flashMessage();
Let me show example of controller action
public function testFlashAction()
{
//set flash message
$this->flashMessenger()->setNamespace('warning')
->addMessage('Mail sending failed!');
//set flash message
$this->flashMessenger()->setNamespace('success')
->addMessage('Data added successfully');
// redirect to home page
return $this->redirect()->toUrl('/');
}
In home page, it prints
<div class="success">Data added successfully</div>
<div class="warning">Mail sending failed!</div>
Hope this will helps !
i have written a post about this some time ago. You can find it right here
Basically you use it just the same like earlier.
<?php
public function commentAction()
{
// ... display Form
// ... validate the Form
if ($form->isValid()) {
// try-catch passing data to database
$this->flashMessenger()->addMessage('Thank you for your comment!');
return $this->redirect()->toRoute('blog-details'); //id, blabla
}
}
public function detailsAction()
{
// Grab the Blog with given ID
// Grab all Comments for this blog
// Assign the view Variables
return array(
'blog' => $blog,
'comments' => $comments,
'flashMessages' => $this->flashMessenger()->getMessages()
);
}
Then in your .phtml file you do it like this:
// details.phtml
<?php if(count($flashMessages)) : ?>
<ul>
<?php foreach ($flashMessages as $msg) : ?>
<li><?php echo $msg; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
Obviously this isn't all too handy, as you have to do this for every single .phtml file. Therefore doing it within the layout you have to do it at best like the following:
<?php
// layout.phtml
// First get the viewmodel and all its children (ie the actions viewmodel)
$children = $this->viewModel()
->getCurrent()
->getChildren();
$ourView = $children[0];
if (isset($ourView->flashMessages) && count($ourView->flashMessages)) : ?>
<ul class="flashMessages">
<?php foreach ($ourView->flashMessages as $fMessage) : ?>
<li><?php echo $fMessage; ?></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
If you need further description, please see my blog, but i guess the code itself is pretty clear (apart frmo the layout.phtml example). Alternatively you're always free to write your own view helper to have it look a little cleaner inside your view-templates.
How to grab Flashmessenger’s messages in a View Helper – sharing code as requested by Sam.
The View helper should implement the ServiceManagerAwareInterface interface and related methods. The plugin will now have access to a Service Manager which we can use to get the Service Locator and ultimately access to the Flash Messenger.
I’ve not touched this code since I initially wrote it – so there may be a more elegant way of doing this.
protected function getMessages()
{
$serviceLocator = $this->getServiceManager()->getServiceLocator();
$plugin = $serviceLocator->get('ControllerPluginManager');
$flashMessenger = $plugin->get('flashmessenger');
$messages = $flashMessenger->getMessages();
// Check for any recently added messages
if ($flashMessenger->hasCurrentMessages())
{
$messages += $flashMessenger->getCurrentMessages();
$flashMessenger->clearCurrentMessages();
}
return $messages;
}
And calling getMessages() from within the plugin should return an array of messages that can be passed to a partial and rendered.
Add code below to the view to render error messages:
<?php echo $this->flashmessenger()
->setMessageOpenFormat('<div class="alert alert-danger"><ul%s><li>')
->setMessageCloseString('</li></ul></div>')
->render('error')
; ?>
In previous request, make sure you created an error message by running code below in your controller:
$this->flashmessenger()->addErrorMessage('Whops, something went wrong...');
I have a photo gallery I'm developing using WP as a means for content management. I'm relying heavily on some jQuery plugins to manage the UI styling and manipulation (via sorting). My problem is there are too many damn posts! 737, and each has a thumbnail which is displayed on the page. This inevitably bogs down any browser. Especially since the sorting plugin "clones" the images when it sorts them.
The posts are built using a Wp_query script;
<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$post_per_page = 15; // (-1 shows all posts) SETS NUMBER OF IMAGES TO DISPLAY!
$do_not_show_stickies = 1; // 0 to show stickies
$args=array(
'post_type' => array ('post'),
'orderby' => 'rand',
'order' => 'ASC',
'paged' => $paged,
'posts_per_page' => $post_per_page
);
$pf_categorynotin = get_post_meta($wp_query->post->ID, true);
if($pf_categorynotin){
$args['tax_query'] = array(
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => $pf_categorynotin,
'operator' => 'NOT IN'
)
); //category__in
}
$temp = $wp_query; // assign orginal query to temp variable for later use
$wp_query = null;
$wp_query = new WP_Query($args);
//Begin LOOP #1
if( have_posts() ) :
echo '<ul id="applications" class="applications pf_item3">';
$r = 0;
while ($wp_query->have_posts()) : $wp_query->the_post();
$post_cat = array();
$post_cat = wp_get_object_terms($post->ID, "category");
$post_cats = array();
$post_rel = "";
for($h=0;$h<count($post_cat);$h++){
$post_rel .= $post_cat[$h]->slug.' ';
$post_cats[] = $post_cat[$h]->name;
}
$r++;
echo'<li data-id="id-'. $r .'" data-type="'.$post_rel.'" >';
if (get_post_meta($post->ID, 'port_thumb_image_url', true)) { ?>
<a class="tozoom" href="<?php echo get_post_meta($post->ID, 'port_large_image_url', true); ?>" rel="example4" title="<?php echo $post->post_title; ?>">
<img src="<?php echo get_post_meta($post->ID, 'port_thumb_image_url', true); ?>" class="portfolio_box" alt="<?php the_title(); ?>" width="199px" height="134px" /></a>
<?php } ?>
</li>
<?php endwhile ?>
</ul>
and the items are sorted by their html5 tags with a menu in the sidebar.
You can see it working here;
http://marbledesigns.net/marbledesigns/products
Right now it randomly loads 15 posts and displays them. I want to be able to reload posts based on my selection from the menu (via categories) and then update the list of images without refreshing the page. I want to be able to change not only which posts from which category are displayed, but also the posts per page as well.
I think AJAX is the way to do this, but I don't want to undo a whole bunch of code in the menu in order to get it working. Right now the menu is styled radio buttons. Isn't there a way I can take the same input from that form and update the parameters of the loop?
Looking for an efficient solution! Please help!
I'm going to abandon this method for reasons of time restriction. I've decided to use AJAX as a way to pull the list form the linked page and display it on the current one.
I followed this tutorial,
http://www.deluxeblogtips.com/2010/05/how-to-ajaxify-wordpress-theme.html
changed a couple names in the ajax.js script and it worked great!