# Ajax: get partial blade template

**URL:** https://discourse.roots.io/t/ajax-get-partial-blade-template/12656
**Category:** sage
**Tags:** sage9, blade
**Created:** 2018-06-11T12:44:43Z
**Posts:** 17

## Post 1 by @trainoasis — 2018-06-11T12:44:43Z

Hello.

I’m trying to define various modal (popup) templates in my new WP Sage environment and then get them via Ajax call based on the provided “type” ID.

For example, modal with “type” 1 would have a centered title, image on the left and text on the right. The one with “type” 2 would have a title on a different place, then text on left, image on right, and another row the other way around. Modal type is selected when adding a modal in backend (custom post type) - based on this, proper content fields appear and must be filled in.

What I’m trying now is this:

1. When you click a certain button with a given data attribute, Ajax call is made to WP Rest API, which gets all the content for the modal which will be opened. You also get modal type (1,2,3 …). This works as expected already. (data from ACF fyi).

2. Based on the given modal type, I’d like to fill in the existing modal already loaded on page (just the wrapper) with the modal template in views/ajax/modal1.blade.php (or modal2.blade.php etc.). I want to keep the modal as blade template because i includes certain files / components already and also it’s probably better to keep it that way, no ?

3. Now I insert the received HTML/strings to the template via Javascript to display it to the user, and I make the modal visible.

How do I go about compiling the ajax-received modal templates before getting it?  
“I should probably make a controller” I though, but there’s no actual ‘view’ for which this controller would work; it’s just for the partial templates for this modals.

Any suggestions/help appreciated. Perhaps I’m even complicating things.  
First time Sage user, hopefully, this is not a total misunderstanding of the concepts here :slight_smile:

Thanks!

---

## Post 2 by @mmirus — 2018-06-11T14:29:58Z

Hi @trainoasis,

Take a look at this thread and see if that gets you headed in the right direction:

> [@How can I return a view from an ajax call](https://discourse.roots.io/t/how-can-i-return-a-view-from-an-ajax-call/12595/4):
>
> Hey @frkparent - I think what you will need to do is render the Blade template using PHP in your AJAX hook, and then return the result. You can render a Blade template in PHP using App\template(). Something like this: add\_filter('wp\_ajax\_load\_posts', function () { echo App\template('partials.post-preview'); wp\_die(); }); If you need to pass data from the controller to the partial, take a look at @MWDelaney’s post here: [Shortcodes that use Blade templates and get Controller data](https://discourse.roots.io/t/shortcodes-that-use-blade-templates-and-get-controller-data/9946).

---

## Post 3 by @trainoasis — 2018-06-11T14:45:07Z

Hey @mmirus, thanks for your time.

I saw that and it actually seemed helpful indeed at first, but I’m a bit at a loss : what ajax url to call to get the appropriate data? How do I expose a certain URL (my controller that has a public static method inside which returns Template(…)). Certainly not just “…/views/ajax/modal1.blade.php” or something like that? This of course just gets the actual data within.

Still did not wrap my head around this 100% it seems!

---

## Post 4 by @mmirus — 2018-06-12T19:17:26Z

Hey @trainoasis,

I think your best bet is to do a wp\_ajax call. [https://codex.wordpress.org/AJAX\_in\_Plugins](https://codex.wordpress.org/AJAX_in_Plugins)

The action you hook onto that call should prepare any data your partial needs and then call `Template()` passing in the partial path and the data. See [the thread I linked to above](https://discourse.roots.io/t/how-can-i-return-a-view-from-an-ajax-call/12595/4?u=mmirus) and @MWDelaney’s [post about passing data.](https://discourse.roots.io/t/shortcodes-that-use-blade-templates-and-get-controller-data/9946)

The action could be a static method on a controller (the app controller, for example).

Does that help get you any further in the process?

---

## Post 5 by @trainoasis — 2018-06-13T07:12:58Z

That indeed helped a lot, thanks.

Got it working by using a separate controller for ajax stuff (to store ajax calls in the future also).

Just as a reference or help to someone else, what I did:

In setup.php:

```
/**
 * Ajax stuff
 */
add_action( 'wp_ajax_get_modal', 'Ajax::getModalTemplateHTML' ); 
add_action( 'wp_ajax_nopriv_get_modal', 'Ajax::getModalTemplateHTML' );
```

In a new file called ajax.php under app/controllers/:

```
namespace App;

use Sober\Controller\Controller;

class Ajax extends Controller
{
	public static function getModalTemplateHTML($popup_type = 1) {
		if(isset($_POST['popup_type'])) {
			$popup_type = (int)$_POST['popup_type'];
		}
		echo Template('ajax.modal'.$popup_type, ['data' => 'stuff']);
    	wp_die();
	}
}
```

And lastly in common.js (or any other) got the data via $.ajax:

```
$.ajax({
            url: GLOBAL_OBJECT.ajax_url,
            method: 'POST',
            data: { action: 'get_modal', popup_type: data.popup_type },
          }).done(function (data) {
            console.warn("FILL THE DATA IN THE MODAL WITH what you got from ajax");
        $('#modal-content').html(data); // this way I get a modal template; now I can fill it with the data provided by a previous ajax to the REST API :) 
      });
```

If there’s a better/more correct approach to this, please do let me know :slight_smile:

---

## Post 6 by @mmirus — 2018-06-13T15:12:50Z

Glad you got it working, and thanks for sharing.

Speculatively, another way of accomplishing this would be to move your code out of controllers and `setup.php` and put it in `app/ajax.php`.

The reasons I explored this:

1. Using a controller here that’s run via separate actions unrelated to how the controller normally functions feels a little strange / out of place to me. Moving it out of there makes it clear that the ajax controller isn’t run as part of the normal template loading process like the other controllers are.
2. Currently if you want to add more AJAX hooks you would need to edit `setup.php` every time on top of your `ajax.php` file. Moving the `add_action` calls to it make it a little more self-contained.

But at the end of the day if your current setup is working and fits with how you want to organize your theme I don’t know if there’s any real advantage to doing it this way.

Here’s how you would set this up…

Create `app/ajax.php` and put your AJAX-related code in there:

```
<?php

namespace App;

class Ajax
{
    public function __construct()
    {
        add_action('wp_ajax_get_modal', [$this, 'myMethod']);
        add_action('wp_ajax_nopriv_get_modal', [$this, 'myMethod']);
    }

    public function myMethod()
    {
        echo 'AJAX response here';
        wp_die();
    }
}

new Ajax();
```

Add ‘ajax’ to the array of files loaded by Sage in `functions.php`:

```
/**
 * Sage required files
 *
 * The mapped array determines the code library included in your theme.
 * Add or remove files to the array as needed. Supports child theme overrides.
 */
array_map(function ($file) use ($sage_error) {
    $file = "../app/{$file}.php";
    if (!locate_template($file, true, true)) {
        $sage_error(sprintf(__('Error locating <code>%s</code> for inclusion.', 'sage'), $file), 'File not found');
    }
}, ['helpers', 'setup', 'filters', 'admin', 'ajax']);
```

Your JS shouldn’t need to change.

---

## Post 7 by @trainoasis — 2018-06-14T07:14:27Z

Hello @mmirus.

That’s indeed a nicer approach there! Using it now and it feels much cleaner and better organised, which is the whole point of using Sage :smiley:.

Thanks for your help, very much appreciated, love Sage so far! Gotta move to Bedrock too!

---

## Post 8 by @Jiannis_Sotiropoulos — 2019-01-02T15:35:49Z

Hi,

What data should I pass to populate the template with its content?

if I understand correctly, the “partials/content-single” is used within the loop. I’m having an ajax call, which properly echos the template but of course without any content.

`echo template("partials.content-single");`

I tried passing the post Object data, but didn’t help:

```
$data = get_post( 50 );	
echo template("partials.content-single", $data);
```

my content-single.blade:

```
<div class="entry-content">
	<div class="heading">{!! get_the_title() !!}</div>

	   @foreach (SingleBookCategoryPost::acf()->modules as $module)
	   		<div class="module_{{$loop->index+1}} module_id_{{$module->id}}" >
	   			
	   			@if ($module->id === "a")
	   				<img src="{{$module->image}}" />
				
				@endif
	   		
	   		</div>
	   @endforeach
		
	     

  </div>

    <footer>
  <div class="navigation">{!! next_post_link() !!}</div>

  </footer>
```

any thoughts?

---

## Post 9 by @trainoasis — 2019-01-02T22:05:10Z

Hey @Jiannis_Sotiropoulos.

If you are passing data (whatever you wish actually) you have to properly use it in your used template, and also take care of what you are passing to the template on the first place.

So $data in your case is an Object (came from get\_post()).  
If you pass an array `get_post(50, ARRAY_A)` (check docs) then you can immediately use the keys as variables in your template.

So for example you could access `$ID` or `$post_author` etc.

Let me know if this is works for you.

---

## Post 10 by @Jiannis_Sotiropoulos — 2019-01-03T11:30:22Z

Hey,

thanks! I thought as much :slight_smile:

I was wondering which $data can I pass to use the template as is (e.g. get\_the\_title() is not working neither is the custom Controller “SingleBookCategoryPost”).

Is it possible or should I create another template?

---

## Post 11 by @trainoasis — 2019-01-04T00:10:00Z

Heya,

indeed, `get_the_title()` needs [setup\_postdata()](https://codex.wordpress.org/Function_Reference/setup_postdata) called prior or another way of initialising the main query loop.

If you use it, then you should probably use [wp\_reset\_postdata()](https://codex.wordpress.org/Function_Reference/wp_reset_postdata) as well.

Also, you usually don’t need to use returning functions, since Blade echoes stuff for you.  
So `{!! get_the_title() !!}` could become `{{ the_title() }}` or `{!! the_title() !!}` if you need html data visible.

---

## Post 12 by @Jiannis_Sotiropoulos — 2019-01-04T15:18:41Z

thanks! I installed barba.js to get my ajax calls running :stuck_out_tongue:

---

## Post 13 by @raltamirano — 2019-07-03T18:03:16Z

Hi @Jiannis_Sotiropoulos! I was wondering if you could walk us/me through how you set up barbra.js in Sage 9.0? I’m somewhat new to Sage (I’ve used sage 5.0 for a while and moving to 9.0 with blade) and would love to know how you set it up.

---

## Post 14 by @Jiannis_Sotiropoulos — 2019-07-05T05:40:33Z

Hi there !

i basically edited main.js like this:

```
import 'jquery';
import './autoload/**/*'
import Router from './util/Router';
import common from './routes/common';

const routes = new Router({
 common
 });

   jQuery(document).ready(() => routes.loadEvents());
```

so now the main.js runs only once.

the common.js sets up barba and initializes all other templates. Basically adding all Barba code in the init method:

```
import Barba from 'barba.js/dist/barba.min';
    import Router from '../util/Router';
    import home from './home';
    import singlePost from './singlePost';
    import templateAbout from './templateAbout';

    export default {

    init() {

    Barba.Dispatcher.on('transitionCompleted', function() {
    // reload home, or singlePost JS
    var routes = new Router({ home, singlePost, templateAbout});
    routes.loadEvents();
    	});

Barba.Pjax.start();
	Barba.Prefetch.init();
    },

    finalize() {

    },
    };
```

Hope this helps :slight_smile:

---

## Post 15 by @cspicuzza — 2019-07-06T05:20:55Z

Thanks for posting your example :grinning:

---

## Post 16 by @dangelion — 2021-05-26T09:13:27Z

Hi @trainoasis @mmirus and to all

on Sage 10 there isn’t `Template` function, used in the code here:

`echo Template('ajax.modal'.$popup_type, ['data' => 'stuff']);`

What should we use on Sage 10?

---

## Post 17 by @slowrush — 2021-08-03T12:12:22Z

> [@dangelion](#):
>
> on Sage 10 there isn’t `Template` function, used in the code here:
> 
> `echo Template('ajax.modal'.$popup_type, ['data' => 'stuff']);`
> 
> What should we use on Sage 10?

There are a couple ways AFAIK, but I’d usually do something like this:

```
echo \Roots\view("ajax.modalr.{$popup_type}", ['data' => 'stuff']);
```
