> For the complete documentation index, see [llms.txt](https://wplake.gitbook.io/advanced-views/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wplake.gitbook.io/advanced-views/templates/custom-ajax-and-rest-api.md).

# Custom Ajax & Rest API

## About the feature

Advanced Views has the `PHPController` feature for [*Layouts*](/advanced-views/display-content/php-controller.md) and [*Post Selections*](/advanced-views/query-content/php-controller.md), allowing extensive customization of components. In addition to passing extra arguments as mentioned in the linked guides, you can also add AJAX and REST API listeners to your components.

This feature builds on top of the built-in [WordPress Ajax](https://developer.wordpress.org/reference/hooks/wp_ajax_action/) and [REST API](https://developer.wordpress.org/rest-api/extending-the-rest-api/adding-custom-endpoints/), enabling you to create components that can send data and update themselves in the background without refreshing the page.

To use this feature, override the `get_ajax_response()` or `get_rest_api_response()` method inside the `Custom_Data` instance. The return value should be an array, which will be passed as `JSON` to the client.

On the client side, you need to send requests to the `admin-ajax.php` file for AJAX scenarios, or to `/wp-json` for REST API scenarios.

**Within the callback, you can use any WordPress functions**. Furthermore, you can employ [PHP-DI](/advanced-views/display-content/php-controller.md#php-di-support) to get direct access to your theme classes.

{% hint style="info" %}
Tip: Not sure about the difference between AJAX and REST API? If you don’t have specific limitations, we recommend using the REST API. It is much faster compared to the traditional `admin-ajax.php` as it skips loading unnecessary WordPress parts (while still making all necessary WordPress functions available, as it is called on the `init` action).
{% endhint %}

## Example of Rest API usage

### JavaScript code

For your Layout or PostSelection.&#x20;

> Use the `script.js` file of the target item if FS Mode is enabled

<pre class="language-javascript"><code class="lang-javascript"><strong>async function makeRequest(postId, value) {
</strong>// 1. todo use '/wp-json/advanced_views/v1/layout/' for Layout, 
// and put your Layout ID at the end

// 2. todo use '/wp-json/advanced_views/v1/card/' for Cards, 
// and put your Post Selection ID at the end

    await fetch('/wp-json/advanced_views/v1/{layout|post-selection}/{6630e2da1953e}', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify({
        // todo your arguments here
           'postId': postId,
            'value': 'value,
        }),
    }).then(response => response.json())
        .then((response) => {
            // todo process response, the variable already contains the parsed object 
            console.log('Request complete', response);
        })
        .catch(error => () => {
            console.error('Request error:', error)
        });
}
</code></pre>

### PHP Controller code

For your Layout or PostSelection.&#x20;

> Use the `controller.php` file of the target item if FS Mode is enabled.

```php
<?php

declare( strict_types=1 );

use Org\Wplake\Advanced_Views\Bridge\Controllers\Layout\Layout_Controller_Base;

return new class extends Layout_Controller_Base {

	/**
	 * @return array<string,mixed>
	 */
	public function get_rest_api_response( WP_REST_Request $request ): array {
		$request_arguments = $request->get_json_params();
		// todo process the request, based on the query arguments available inside the $input array

		// todo you can use the container if you need to access your theme classes
		// $this->get_container();

		return [
			'my_message'  => 'everything is fine',
			'my_variable' => 'my value',
		];
	}
};

```

```php
<?php

declare( strict_types=1 );

use Org\Wplake\Advanced_Views\Bridge\Controllers\Selection\Selection_Controller_Base;

return new class extends Selection_Controller_Base {

	/**
	 * @return array<string,mixed>
	 */
	public function get_rest_api_response( WP_REST_Request $request ): array {
		$request_arguments = $request->get_json_params();
		// todo process the request, based on the query arguments available inside the $input array

		// todo you can use the container if you need to access your theme classes
		// $this->get_container();

		return [
			'my_message'  => 'everything is fine',
			'my_variable' => 'my value',
		];
	}
};

```

### **Request Authentication**

The REST API is available to both authorized users and guests. However, for security reasons, by default REST API ignores the WordPress auth cookie, and treats the request as if it comes from an unauthorized user. E.g. `wp_get_current_user()->exists()` method inside the request will return `false`.

If you need to keep the user authorized inside the request, you must create a `wp_rest` nonce and pass it in the `X-WP-Nonce` header, as [it described](https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/) in the official WordPress Developer Documentation. In this cases WordPress will respect the user's auth cookie.

Below, we provide the auth example adopted for usage inside the Advanced Views Framework:

#### **1. Create and pass nonce to the template (in controller.php)**

```php
// ...
/**
 * @return array<string,mixed>
 */
public function get_variables(): array {
  return [
    "my_block_nonce" => wp_create_nonce( 'wp_rest' ),
  ];
}
// ...
```

#### **2. Define nonce as a JS window variable (in Twig or Blade template)**

```html
<!-- ... -->
<script>
window.my_block_nonce = "{{ my_block_nonce }}";
</script>
<!-- ... -->
```

#### **3. Use nonce in the request headers (script.js)**

<pre class="language-javascript"><code class="lang-javascript"><strong>// ...
</strong>await fetch('/wp-json/advanced_views/v1/{view|card}/{6630e2da1953e}', {
 method: 'POST',
 headers: {
  'Content-Type': 'application/json',
  'X-WP-Nonce': window.my_block_nonce,
},
// ...
</code></pre>

## Example of Ajax usage     &#x20;

### script.js

```javascript
async function makeAjax() {
    let response = await fetch('/wp-admin/admin-ajax.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
        },
        body: new URLSearchParams({
            'action': 'advanced_views',
            // todo put your View ID or comment if it's a View 
            '_layout-id': '6630e2da1953e', // you can learn ID from the shortcode
            // todo put your Card ID or comment if it's a Card 
            '_post-selection-id': '6630e2da1953e', // you can learn ID from the shortcode
            // todo your args here
            'myArg': 'myvalue',
        }).toString(),
    });

    let responseText = await response.text();
    let json = {};

    try {
        json = JSON.parse(responseText);
    } catch (e) {
        console.log("Error parsing JSON", responseText);
        return;
    }

    console.log('ajax complete', json);
}
```

### Layout's controller.php

```php
<?php

declare( strict_types=1 );

use Org\Wplake\Advanced_Views\Bridge\Controllers\Layout\Layout_Controller_Base;

return new class extends Layout_Controller_Base {
	public function get_ajax_response(): array {
		$myArg = sanitize_text_field( $_POST['myArg'] ?? '' );

		// todo your logic here
		// additionally, you can use $this->get_container()
		// to get PHP-DI instance and access to any of your theme classes

		return [
			'my_response' => 'Thank you for the feedback!',
		];
	}
};

```

### Post Selection's controller.php

```php
<?php

declare( strict_types=1 );

use Org\Wplake\Advanced_Views\Bridge\Controllers\Selection\Selection_Controller_Base;

return new class extends Selection_Controller_Base {
	public function get_ajax_response(): array {
		$myArg = sanitize_text_field( $_POST['myArg'] ?? '' );

		// todo your logic here
		// additionally, you can use $this->get_container()
		// to get PHP-DI instance and access to any of your theme classes

		return [
			'my_response' => 'Thank you for the feedback!',
		];
	}
};

```

### **Request Authentication**

Ajax is available to both authorized users and guests. Unlike the REST API, Ajax does not ignore the WordPress authentication cookie, so it sets up the current user out-of-the-box without requiring any extra actions. &#x20;


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://wplake.gitbook.io/advanced-views/templates/custom-ajax-and-rest-api.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
