0

Trying to make a full-ajax navigation on my new portfolio, I read online on a few different blog that building the templates using JSON would be easier in order to treat the datas however I want.

It is not the regular procedure (with WP_Ajax... etc) and spent the day looking over the Internet... no answer. It is a very SEO friendly technique, also accessible (the website still work if javascript is not activated... etc). I am making this precision to make sure that you guys understand why I am trying to use this procedure and not the more conventionals one...

Inspired from those (french) article: http://boiteaweb.fr/la-navigation-avec-ajax-7743.html http://www.seomix.fr/ajax-wordpress/

I started to follow the recommended steps and to adapt them to fit with my theme and ideas.

As a quick summary: IMPORTANT: It is not using wp-ajax or admin-ajax techniques, I am using instead an alternative ajax-template-slug. During the AJAX request on the link, I am sending in the "MDXMLHTTPRequest".

function perform_ajax_request( url ) {
        $.ajax({
            url    : url,
            type   : 'POST',
            headers: {
                'X-Requested-With':'MDXMLHttpRequest'
            }
        }).done( function( data ) {
            var data = $.parseJSON( data );
            switch_content( current_template, data );
        }).error( function() {
            // Error
            alert( 'Unable to update the content, an error occured.' );
        });
    }

With the following function, Wordpress will understand that an AJAX request is being made and will ask to return the correct template (the shrinked in content one) i.e. the content of the post from a page displaying all the posts.

add_filter( 'template_include', 'md_template_include' );  
function md_template_include( $template ) {  
    if( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && $_SERVER['HTTP_X_REQUESTED_WITH']== 'MDXMLHttpRequest' ):  
        $pre = dirname( $template );  
        $suf = basename( $template );  
        $_template = $pre . '/ajax-' . $suf;  
        if( !file_exists( $_template ) )  
            $_template = $template;  
        $template = $_template;  
    endif;  
    return $template;  
}  

I think this part is pretty simple to understand... It is returning the prefixed ajax-template when function.php receive the header. Now, we have to construct the template, the ajax-single-project.php file in my case.

I am trying to make the server return a JSON array so that it is easier to manipulate using jQuery and to make the switch between templates.

However, the current code I made (see below, commented) return an error that is typical from a broken JSON array. Since it's the first time I'm trying JSON.. I am not sure if I forgot something or did something wrong...

<?php

$o = array();

$o[ 'title' ]      = wp_title( '|', true, 'right' ); //used to update the title of the browser window
$o[ 'type' ]       = 'single-project'; //type of the template

//The Localize script, is that ok here ?
wp_localize_script('my-ajax-request', 'current_template', array('the_current_template' => basename(get_page_template())));

//ob_start();
$article = '<div id="container" class="content-area project-content">';
$article .=     '<main id="main" class="site-main" role="main">';

                 // I couldn't make this part work with JSON... That's why I rewrote the whole thing instead of loading a template part
                /*while (have_posts() ) : the_post();
                    if ( $overridden_template = locate_template( 'content-single-project.php' ) ) {
                    // locate_template() returns path to file
                    // if either the child theme or the parent theme have overridden the template
                    load_template( $overridden_template );
                } else {
                    // If neither the child nor parent theme have overridden the template,
                    // we load the template from the 'templates' sub-directory of the directory this file is in
                    load_template( dirname( __FILE__ ) . '/template-parts/content-single-project.php' );
                }
                endwhile;*/

                while (have_posts()) : the_post();

$article .=                     '<article id="post-'.the_ID().'"'.post_class().'>';

$article .=                         $image0 = wp_get_attachment_image_src(get_field('project_hero'), 'full');
$article .=                         '<img class="project-hero" src="'.$image0[0].'" alt="'.get_the_title(get_field('project_hero')).'" />';

$article .=                         '<section class="project-head entry-header">';
$article .=                             '<div class="clearfix">';
$article .=                                 '<h3 class="project-title entry-title">';
$article .=                                     the_title();
$article .=                     '</h3>';
$article .=                                 '<ul class="project-infos clearfix entry-meta">';

                                if ( has_term('frontend', 'projectcat')) {
$article .=                                     '<li><i class="fa fa-desktop"></i><span>Frontend</span></li>';
                                }
                                else if ( has_term('design', 'projectcat')) {
$article .=                                     '<li><i class="fa fa-pencil"></i><span>Design</span></li>';
                                }
                                else if ( has_term('application', 'projectcat')) {
$article .=                                     '<li><i class="fa fa-code"></i><span>Application</span></li>';
                                }
                                else {
$article .=                                     '<li><span><i class="fa fa-question"></i>Category not specified</span></li>';
                                }

$article .=                                     '<li><i class="fa fa-calendar"></i><span>'.the_field('project_year').'</span></li>';
$article .=                                     '<li><i class="fa fa-users"></i><span>'.the_field('project_client').'</span></li>';
$article .=                                 '</ul>';
$article .=                             '</div>';
$article .=                             '<div class="project-intro entry-content">';
$article .=                                 the_content();
$article .=                             '</div>';
$article .=                         '</section>';
$article .=                         '<section class="project-body entry-content">';
$article .=                             '<h4 class="project-subtitle">'.the_field('project_image_section_1_title').'</h4>';
                            $image1 = wp_get_attachment_image_src(get_field('project_image_section_1_images'), 'full');
$article .=                             '<img src="'.$image1[0].'" alt="'.get_the_title(get_field('project_image_section_1_images')).'" />';
$article .=                             '<h4 class="project-subtitle">'.the_field('project_image_section_2_title').'</h4>';
                            $image2 = wp_get_attachment_image_src(get_field('project_image_section_2_images'), 'full');
$article .=                             '<img src="'.$image2[0].'" alt="'.get_the_title(get_field('project_image_section_2_images')).'" />';
$article .=                             '<h4 class="project-subtitle">'.the_field('project_image_section_3_title').'</h4>';
                            $image3 = wp_get_attachment_image_src(get_field('project_image_section_3_images'), 'full');
$article .=                             '<img src="'.$image3[0].'" alt="'.get_the_title(get_field('project_image_section_3_images')).'" />';
$article .=                         '</section>';
$article .=                     '</article><!-- #post-## -->';

                endwhile;


$article .=     '</main><!-- #main -->';
$article .= '</div><!-- #primary -->';

$o['article']= $article;
//$o = ob_get_clean();

echo json_encode($o);
exit();

I think it is almost working and I am almost seeing the light, the output I get using FireBug network inspector (with a title object being null ??) shows that there is a whole lot of content not being putted into the JSON array (weird!) that's what I couldn't figure out:

Alstom Blue Book | Michel Didier1793class="post-1793 project type-project status-publish has-post-thumbnail
 hentry projectcat-frontend"Alstom Blue Book2014Web Relief<p>Lorem ipsum dolor sit amet, consectetur
 adipiscing elit. Praesent magna elit, lobortis id elementum in, vestibulum vitae tortor. Proin molestie
 purus sit amet rhoncus pharetra. Nulla feugiat orci nec mattis mollis. Integer id lorem imperdiet, egestas
 nunc ac, efficitur lectus. Aenean nec ullamcorper est. Duis non urna mi. Cras dictum pharetra justo
, ac tristique augue cursus id. Maecenas sollicitudin orci ac lectus laoreet suscipit. Maecenas bibendum
 egestas justo, id consectetur lectus pharetra id. Nulla finibus eu nunc sit amet bibendum. Aliquam erat
 volutpat.</p>
HomeArticleMapping{"title":null,"type":"single-project","article":"<div id=\"container\" class=\"content-area
 project-content\"><main id=\"main\" class=\"site-main\" role=\"main\"><article id=\"post-\">Array<img
 class=\"project-hero\" src=\"http:\/\/localhost:8888\/portfolio\/wp-content\/uploads\/2015\/05\/alstom_hero
.png\" alt=\"alstom_hero\" \/><section class=\"project-head entry-header\"><div class=\"clearfix\"><h3
 class=\"project-title entry-title\"><\/h3><ul class=\"project-infos clearfix entry-meta\"><li><i class
=\"fa fa-desktop\"><\/i><span>Frontend<\/span><\/li><li><i class=\"fa fa-calendar\"><\/i><span><\/span
><\/li><li><i class=\"fa fa-users\"><\/i><span><\/span><\/li><\/ul><\/div><div class=\"project-intro
 entry-content\"><\/div><\/section><section class=\"project-body entry-content\"><h4 class=\"project-subtitle
\"><\/h4><img src=\"http:\/\/localhost:8888\/portfolio\/wp-content\/uploads\/2015\/05\/alstom_01.png
\" alt=\"alstom_01\" \/><h4 class=\"project-subtitle\"><\/h4><img src=\"http:\/\/localhost:8888\/portfolio
\/wp-content\/uploads\/2015\/05\/alstom_02.png\" alt=\"alstom_02\" \/><h4 class=\"project-subtitle\"
><\/h4><img src=\"http:\/\/localhost:8888\/portfolio\/wp-content\/uploads\/2015\/05\/alstom_03.png\"
 alt=\"alstom_03\" \/><\/section><\/article><!-- #post-## --><\/main><!-- #main --><\/div><!-- #primary
 -->"}

Thank you for your time, your help, and your reading,

I tried to be really complete, hopefully my english will not cause any trouble with all those details...

Note: It is recommended by the writer of the original article to use wp_localize_script() to track in which template we are currently (and make the switch in different cases, from list to single... etc) I am not sure about this part and if I putted the wp_localize_script at the good place... If you guys are understanding the principle and knows if it is good, please let me know :)

EDIT The problem seems to come from some Wordpress encoding.

Where I have

$article .=                                                     '<div class="project-intro entry-content">';
$article .=                                                             the_content();
$article .=                                                     '</div>';

If I replace by

        $article .= '<div class="project-intro entry-content">'.get_the_content().'</div>';

The post content is correctly putted in place in the JSON string and not outside of it. I guess the_content()is breaking the JSON string, as well as the_ID(), wp_title().. etc. Any suggestion ?

  • 1
    Where is switch_content() (js) and current_template (js) defined? To me it looks like if there's only 50% of the needed code for this (overly complicated) solution available in the question. – kaiser May 31 '15 at 0:05
  • current_templateis passed from wp_localize_script. It's at the end of the js file, current_template = template. The glitch didn't seem to come from any of it, but comes from the parsing, that's why I didn't put the rest of the code, just what was concerning JSON... switch_content() is another function coming after function perform_ajax_request , I didn't put it since no code (if I do a try with a console.log() or alert() ) is getting executed after the JSON parsing. – JetXS May 31 '15 at 1:41
  • 1
    Please try to come up with a reproducable example. – kaiser May 31 '15 at 11:24
  • Please see the edit at the bottom of the post :) It doesn't seem to be a JS problem... – JetXS May 31 '15 at 14:44
0

Replacing all the specific the_content() functions, or the_ID... etc by the getters equivalent seems to fix the problem. Here the solution:

<?php

$o = array();

$o[ 'title' ] = wp_title( '|', false, 'right' );
$o[ 'type' ] = 'single-project';

//ob_start();
$article = '<div id="container" class="content-area project-content">';
    $article .= '<main id="main" class="site-main" role="main">';

        while (have_posts()) : the_post();

        $article .= '<article id="post-'.get_the_ID().'"'.get_post_class().'>';

            $article .= $image0 = wp_get_attachment_image_src(get_field('project_hero'), 'full');
            $article .= '<img class="project-hero" src="'.$image0[0].'" alt="'.get_the_title(get_field('project_hero')).'" />';

            $article .= '<section class="project-head entry-header">';
                $article .= '<div class="clearfix">';
                    $article .= '<h3 class="project-title entry-title">';
                        $article .= get_the_title();
                    $article .= '</h3>';
                    $article .= '<ul class="project-infos clearfix entry-meta">';

                        if ( has_term('frontend', 'projectcat')) {
                            $article .= '<li><i class="fa fa-desktop"></i><span>Frontend</span></li>';
                        }
                        else if ( has_term('design', 'projectcat')) {
                            $article .= '<li><i class="fa fa-pencil"></i><span>Design</span></li>';
                        }
                        else if ( has_term('application', 'projectcat')) {
                            $article .= '<li><i class="fa fa-code"></i><span>Application</span></li>';
                        }
                        else {
                            $article .= '<li><span><i class="fa fa-question"></i>Category not specified</span></li>';
                        }

                        $article .= '<li><i class="fa fa-calendar"></i><span>'.get_field('project_year').'</span></li>';
                        $article .= '<li><i class="fa fa-users"></i><span>'.get_field('project_client').'</span></li>';
                    $article .= '</ul>';
                $article .= '</div>';
                $article .= '<div class="project-intro entry-content">'.get_the_content().'</div>';
            $article .= '</section>';
            $article .= '<section class="project-body entry-content">';
                $article .= '<h4 class="project-subtitle">'.get_field('project_image_section_1_title').'</h4>';
                $image1 = wp_get_attachment_image_src(get_field('project_image_section_1_images'), 'full');
                $article .= '<img src="'.$image1[0].'" alt="'.get_the_title(get_field('project_image_section_1_images')).'" />';
                $article .= '<h4 class="project-subtitle">'.get_field('project_image_section_2_title').'</h4>';
                $image2 = wp_get_attachment_image_src(get_field('project_image_section_2_images'), 'full');
                $article .= '<img src="'.$image2[0].'" alt="'.get_the_title(get_field('project_image_section_2_images')).'" />';
                $article .= '<h4 class="project-subtitle">'.get_field('project_image_section_3_title').'</h4>';
                $image3 = wp_get_attachment_image_src(get_field('project_image_section_3_images'), 'full');
                $article .= '<img src="'.$image3[0].'" alt="'.get_the_title(get_field('project_image_section_3_images')).'" />';
            $article .= '</section>';
        $article .= '</article><!-- #post-## -->';

    endwhile;


$article .='</main><!-- #main -->';
$article .='</div><!-- #primary -->';

$o['article']= $article;
//$o = ob_get_clean();

echo json_encode($o);
exit();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.