Change the contents inside the <div> from the "Sort Messages by Category" menu without loading the page
My first post is here on this website, and I'm looking for a guide for my first custom Wordpress theme. I am extremely new to jQuery / AJAX, and at that moment my brain hurts, because this whole process was one learning curve after the next. Therefore, please forgive my inability to see between the lines and understand what is or may already be there. There are some results on this subject when I search, but I cannot translate these examples into working results for my situation ...
I want to sort my displayed messages into categories in the "News" section ... There is a submenu in the <div id="#container"> submenu ... I want the links in the submenu to change the content in my <div id="contentbox-news"> ...
i.e. “latest news”, “latest construction projects”, “press releases”, etc.
Here is the code from "page-news.php" and the original link HFX Cars and Coffee
<div id="news_submenu_container"><!-- begin submenu placement --> <ul id="news_submenu"> <li>VIEW</li> <li><a href="#" onClick="get_posts_all();">ALL</a></li> <li><a href="#" onClick="get_posts_news();">NEWS</a></li> <li><a href="#" onClick="get_posts_builds();">BUILDS</a></li> <li><a href="#" onClick="get_posts_pr();">PR</a></li> </ul> </div><!-- end submenu placement --> <script> function get_posts_all() { var posts_all_var = '<?php echo "Insert Wordpress Loop here identified by Category-ID" ?>'; document.getElementById("contentbox-news").innerHTML = posts_all_var; return false; } function get_posts_news() { var posts_news_var = '<?php echo "Huh?" ?>'; document.getElementById("contentbox-news").innerHTML = posts_news_var; return false; } function get_posts_builds() { var posts_builds_var = '<?php echo "Cant get loop to work" ?>'; document.getElementById("contentbox-news").innerHTML = posts_builds_var; return false; } function get_posts_pr() { var posts_pr_var = '<?php echo "DAMNIT!" ?>'; document.getElementById("contentbox-news").innerHTML = posts_pr_var; return false; } </script> Now I understand that JavaScript and PHP do not work together the way I thought ... Obviously, I need to use the method through AJAX ... I found this article on PHP AJAX and MySQL , however it is too advanced for me, it is difficult for me to understand him and create a working example for yourself ...
But now, starting with yesturday, I have created new code that still leads me, I can echo PHP ... it's about that.
function get_posts_builds() { var posts_builds_var = '<?php query_posts('cat=6'); while (have_posts()): the_post(); the_content(); endwhile; ?>'; document.getElementById("contentbox-news").innerHTML = posts_builds_var; return false; } Once I replaced the PHP echo with this PHP wordpress loop, it doesn't seem to do the trick for me and it doesn't break.
You really need to use AJAX for this. Wordpress has its own ajax request processing method , which you can use to do this by following the few steps described below. I will try to show some practical recommendations of WP on this issue, since it can be faster / easier / more dirty way to achieve this (maybe even through a plugin), this will help you in creating a theme for Wordpress / plugins for you. Feel free to follow the docs links to better understand how this works.
1. Creating a category menu
In your sample code, the menu is static, although it is better to use a dynamic menu. One solution might be to use get_the_category_list , but this does not allow you to fully control category links. I would suggest defining a new navigation menu like this (the following code go to your functions.php theme):
add_action('after_setup_theme', 'add_categories_menu'); function add_categories_menu() { register_nav_menu('categories_menu', __('Categories Menu', 'your-theme-slug')); } Then in your template, replace the static menu with the following to display the new menu:
<?php wp_nav_menu(array('theme_location' => 'categories_menu')); ?> Now, to add categories to your menu, go into your Wordpress administration, go to Appearance> Menu, create a new menu, select the category menu topic for it, and add categories to it.
The last step for this, we will add a filter to add the onclick attribute to the menu links that will send the slug category to the js function called showPostsFromCategory() , which we will define later.
This happens in your .php functions:
function add_onclick_attr_categories_menu($atts, $item, $args) { if($args->theme_location == 'categories_menu' && $item->object == 'category') { $category = get_category($item->object_id); if($category !== null) { $atts['onClick'] = 'showPostsFromCategory("' . $item->slug . '")'; } } return $atts; } add_filter('nav_menu_link_attributes', 'add_onclick_attr_categories_menu', 10, 3); You may ask why we save the category link in the menu item? This is for SEO and accessibility purposes: for a browser without javascript (for example, for reading from a screen) or a search finder, category pages will still be available.
2. Preparing AJAX Themes
In Wordpress, all AJAX requests must be sent to wp-admin/admin-ajax.php with an action parameter that will identify the request in order to catch it in functions.php using wp_ajax_nopriv_my_action (for non-registered users) and wp_ajax_my_action (for registered users) .
So, one small step before moving on is to make this path ( wp-admin/admin-ajax.php ) available in your JavaScript. First, create the js file that we will use for the AJAX process in your theme folder, let its name be ./js/categories-ajax.js . Then add the following to your functions. Php to enqueue this new script and make the path accessible through script localization :
add_action('wp_enqueue_scripts', 'ajax_categories_enqueue_scripts'); function ajax_categories_enqueue_scripts() { wp_register_script('categories_ajax', get_stylesheet_directory_uri() . '/js/categories-ajax.js', array('jquery'), '', true); wp_localize_script('categories_ajax', 'ls', array( 'ajax_url' => admin_url('admin-ajax.php') )); wp_enqueue_script('categories_ajax'); } With this, the admin-ajax.php path will be available in your JS using ls.ajax_url .
3. Run ajax request
It's time to create the showPostsFromCategory() function. Therefore, write in your new categories the file ajax.js. Personally, to avoid any possible conflict with jQuery in my plugins / themes, I like to always encapsulate jQuery code in JavaScript closure and make functions accessible through global vars this:
(function($){ showPostsFromCategory = function(category_slug) { // code function... }; })(jQuery); var showPostsFromCategory; So, I assume that the function code is inside the closure.
Basically, now we need to configure the $.post admin-ajax.php request, which will send the following parameters:
action: AJAXactionid to let Wordpress know which function to call later. We will call itdynamic_categories.category: the slug category that was clicked on the menu.
Thus, the function code will look like this:
showPostsFromCategory = function(category_slug) { $.post(ls.ajax_url, {action: 'dynamic_categories', category: category_slug}, function success(data) { $('#your-post-content-wrapper').html(data); // Update the page with the new posts -- change this ID to the correct one }); return false; // this is to cancel the link click, so the page isn't being redirected } It is very simple, you may want to add some error handling and a loader later. Here we simply replace the actual records with an AJAX return, which we consider HTML. Nothing more is being done on the JS side, so let's now work on the PHP side.
4. Receive messages for the requested categories
First add the following lines to functions.php to attach the get_categories_posts () function to the wp_ajax_dynamic_categories and wp_ajax_nopriv_dynamic_categories .
add_action('wp_ajax_dynamic_categories', 'get_categories_posts'); add_action('wp_ajax_nopriv_dynamic_categories', 'get_categories_posts'); Now we need to do the following in the function:
- Check if the slug category is valid and it has messages related to the message, or showing an error message.
- Receive messages related to the category identified by the path sent by the JS script.
Scroll through the messages and show them using part of the template . To do this, create a template in the theme folder that will contain only the necessary HTML / PHP to display the one message. You can see an example of such a template in the default Wordpress theme (twentysixteen) in
template-parts/content.php. Make the same file in your theme - perhaps it already exists.
You will also need to update your archive template to use part of the template. It is very simple, remove the code used to display the column inside and replace it with:<?php get_template_part('template-parts/content'); ?>
Thus, the entire function code will look like this:
function get_categories_posts() { // Check if the category slug provided is ok and if it have posts if(!isset($_POST['category'])) { die('<p class="error">' . __('No category parameter provided', 'your-theme-slug') . '</p>'); } $category_slug = sanitize_text_field($_POST['category']); $category = get_category_by_slug($category_slug); if(!$category) { die('<p class="error">' . sprintf(__('Category %s not found', 'your-theme-slug'), $category_slug) . '</p>'); } $posts = get_posts(array( 'category' => $category->term_id, 'posts_per_page' => -1 // get all posts )); if(empty($posts)) { die('<p class="error">' . sprintf(__('The category %s is empty', 'your-theme-slug'), $category->name) . '</p>'); } // Loop through the posts and display them foreach ($posts as $post) { setup_postdata($post); get_template_part('template-parts/content'); } die(''); } And it's all! You now have dynamic navigation for your message categories.
For reference: sanitize_text_field , get_category_by_slug , get_posts , setup_postdata and get_template_part .
Please note that this does not support pagination. If you need this, check out this answer I made on this.