0

I'm looking for a way to open every/any link to a blog post in a lightbox/modal globally and without having to any extra classes or rel attribute to the link element. I know I can access this info from within the page or post itself, but is there a way, through some sort of AJAX call I presume, to get this data before the request for the content is actually made so that when I do retrieve the response content, I can either just display it normally in the same browser tab (in the case of a Page) or trigger a lightbox and populate it with the content instead.

At first I was thinking about using regular expression matching on the link element's href and if it matched something looking like a blog post URL, open the lightbox. that seems pretty hacky tho and is definitely not bulletproof.

This is what I've got so far...

JavaScript:

$('a:not([href^="#"])[href]').click(function(e) {
    e.preventDefault();
    var $this = $(this);
    var lnk = $this.attr('href');

    var jqxhr = $.post("/wp-content/themes/mist-child/php/get-post-type.php", {url: lnk});
    jqxhr.done(function(data) {
        if(data === 'post') {
            $.prettyPhoto.open(lnk + '?iframe=true&width=80%&height=80%');
        }
    });
});



get-post-type.php (/wp-content/themes/CHILD_THEME/php/...)

<?php
    require_once(rtrim($_SERVER['DOCUMENT_ROOT'], '/') . '/wp-load.php');


    $url = $_POST['url'];

    $postid = url_to_postid($url);
    echo(get_post_type($postid));
?>

The part where Posts get opened in the lightbox is working. It's a little slow - I'm guessing that loading wp-load.php adds quite a bit of overhead. is there any way to add my PHP somewhere in functions.php and call that function (with arguments) via AJAX?

I know it needs some work, but as far as a prototype goes, am I moving in the right direction? Please feel free to shoot this full of as many holes as you can find.

  • what is this in wordpress by calling "/wp-content/themes/mist-child/php/get-post-type.php"? Instead use default wp ajax url. <?php echo admin_url('admin-ajax.php');?> – Balas Aug 9 '18 at 23:59
  • Is there a reason why you don't want to handle this when links are rendered? Or add some sort of extra param to the links so you can identify it by URL pattern without making extra requests? – Milo Aug 10 '18 at 3:09
  • @milo - some of the links are from widgets or otherwise out of my control at the time of rendering – Daveh0 Aug 10 '18 at 3:23
  • If links are output via the API (as they should be), you should at least be able to filter that URL output with post_link and/or page_link filters. A possible solution is to add a rewrite endpoint, which you can append to whatever post type you want, and detect on the front end via javascript, without having to make that extra request. – Milo Aug 10 '18 at 4:02
  • @milo - interesting... I didn't even know that (filtering, etc) was "a thing" - very new to this type of development. I like the idea of not having the extra request. I'll try this as well as Balas's solution in the answer below, which does indeed seem to be the Wordpress Way of doing what I'm doing now. I'll report back with which one suits my needs better. – Daveh0 Aug 10 '18 at 17:57
1

The wordpress way solution is

 // put this in header.php
var ajax_url ="<?php echo admin_url('admin-ajax.php');?>"

// in js file
$('a:not([href^="#"])[href]').click(function(e) {
    e.preventDefault();
    var $this = $(this);
    var lnk = $this.attr('href');

    var jqxhr = $.post(ajax_url, {'action':'list_content', url: lnk});
    jqxhr.done(function(data) {
        if(data === 'post') {
            $.prettyPhoto.open(lnk + '?iframe=true&width=80%&height=80%');
        }
    });
});

// functions.php
add_action('wp_ajax_nopriv_list_content', 'list_content');
add_action('wp_ajax_list_content', 'list_content');

function list_content() {

    $url = $_POST['url'];

    $postid = url_to_postid($url);
    echo(get_post_type($postid));
    die();
}
  • Yup that is indeed the "Wordpress Way" that i was surely missing. For this situation, since I can detect the post_type on the server when the markup for those elements is being generated (@milo's suggestion), I no longer have to make any additional requests at all. See my answer posted below. Definitely good to know the "right" way to make that AJAX call now tho, so thx! – Daveh0 Aug 13 '18 at 9:40
0

Going with @milo's suggestion in the comments of the OP, I added a function to functions.php that rewrites URLs output by the API with a specific query string key/value when the post_type is post. This allows me to see this on the front end quite easily and take the appropriate action on the link depending on the absence/presence of said query string data. In this case, the frontend script finds all the elements "marked" as linking to posts (and not pages) and simply opens their href in a lightbox. SO much simpler than making several AJAX calls when the page is rendered to check the post_type for various links on the page.


functions.php

function append_query_string( $url, $post, $leavename=false ) {
    if ( $post->post_type == 'post' ) {
        $url = add_query_arg( 'blogLnk', '1', $url );
    }
    return $url;
}
add_filter( 'post_link', 'append_query_string', 10, 3 );


JavaScript

var blogLnks = [
    'a[hrf*="blogLnk=1"]',
    'a[rel="blogLnk"]'
];
var $blogLnks = $(blogLnks.join(','));
$blogLnks.click(function(e) {
    e.preventDefault();
    console.log('click - open me in lightbox');
    var $this = $(this);
    var qs = '?iframe=true&width=80%&height=90%';
    var lnk = $this.attr('href');

    $.prettyPhoto.open(lnk + qs);
});

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.