Jump to content

Optimal way to call Page Data via JSON and AJAX


Neo
 Share

Recommended Posts

I have a site with a blog section (every blog post is a page), which I don't want to populate in the list view via the ordinary pagination.

Instead, I have written a bit of JS to load the blog posts after each other: in this case always 2 blog posts by the click of a button via $.getJSON(). So I use a JSON file to get my page data from Processwire.

On the ProcessWire site, I have written the following code on the top of my blog.php list view template:

<?php

  $json = array();

  $posts = wire('pages')->find('template=blog-post, sort=-blog_date');

  foreach($posts as $post) {

    $json[] = array(
      'link' => $post->url,
      'date' => $post->blog_date,
      'title' => $post->title
      //'preview' => substr($post->body, 0, 250)
    );

  }

  file_put_contents('posts.json', json_encode($json));

So this basically creates the posts.json file in http://example.com/My_Project/site/templates/posts.json every time the template is accessed. 

This works, the data is populated in the view.

However, I am not sure if this is the best way to approach this considering performance as the json file is created every time the page is requested.

Would appreciate your advice.

 

Link to comment
Share on other sites

So, basically you would just return the JSON-array without writing it to the file?

Something like 

return json_encode($json);

Using "echo" would directly print it to the page. 

However, in this case I guess I would have to provide the template location in my JS:

$.getJSON('http://localhost/My_Project/blog/',processPreview);

which actually does not work. It does not throw an error, but only works with the actual JSON-file specifically provided as a URL, i.e. http://localhost/My_Project/site/templates/posts.json

 

So I assume the JSON is not returned in the right way?

 

  • Like 1
Link to comment
Share on other sites

Setting the header in the template will return the page view in plain code:

header('Content-Type: application/json');

So I finally created a new template just for the JSON and didn't put the code directly in blog.php.

This works...

  • Like 1
Link to comment
Share on other sites

7 minutes ago, thetuningspoon said:

You can also put it at the very top of the same template file, as long as you do something like this:


if($config->ajax) {
	// Output your json
	exit;
}

 

Don't forget about $this->halt() rather than using exit/die

https://processwire.com/blog/posts/processwire-2.6.8-brings-new-version-of-reno-admin-theme-and-more/#new-this-gt-halt-method-for-use-in-template-files

  • Like 5
Link to comment
Share on other sites

  • 9 months later...
On 13.9.2016 at 10:32 PM, adrian said:

what about returning some json data from inside modules? the halt() method only applies to templatefiles.

is there a way to halt any other output inside the admin (inside a module) other than this?

echo json_encode($mydata);
die();

or is it fine to do so?

  • Like 1
Link to comment
Share on other sites

@bernhard, for module AJAX calls I have used a replace hook on ProcessModule::executeEdit. In my JS I send an AJAX request to the module's config page, and in the hook I check that the request is coming via AJAX and has the required GET/POST variable(s) and if so I use $event->replace = true and return my response.

  • Like 2
Link to comment
Share on other sites

thank you robin, this seems too complicated for my usecase.

i'm working on a datatables fieldtype and i came up with this solution:

  private function getAjaxData() {
    $config = $this->wire->config;
    $input = $this->wire->input;

    // if the field is set AND the request was done via ajax we return the data of the table
    // if it was only the field variable it could have been requested as single field in a modal
    if($config->ajax AND $input->get->field === $this->name) {
      echo $this->getJSON();
      die();
    }
  }

the data is requested via AJAX and the field is set. the further makes the field always load even if it is set to hidden+ajax - so i always get the json. don't think there's anything bad with this solution, but of course i'm happy to hear if im missing anything...

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...