Skip to content

Instantly share code, notes, and snippets.

@JeffreyWay
Last active November 6, 2024 14:26
Show Gist options
  • Save JeffreyWay/8526696b6f29201c4e33 to your computer and use it in GitHub Desktop.
Save JeffreyWay/8526696b6f29201c4e33 to your computer and use it in GitHub Desktop.
Laravel middleware for working with pjax.
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Symfony\Component\DomCrawler\Crawler;
class PjaxMiddleware
{
/**
* Handle an incoming request.
*
* @param Request $request
* @param Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$response = $next($request);
if (! $request->pjax() || $response->isRedirection()) {
return $response;
}
$this->filterResponse($response, $request->header('X-PJAX-CONTAINER'))
->setUriHeader($response, $request);
return $response;
}
/**
* Prepare the PJAX-specific response content.
*
* @param Response $response
* @param string $container
* @return $this
*/
protected function filterResponse(Response $response, $container)
{
$crawler = new Crawler($response->getContent());
$response->setContent(
$this->makeTitle($crawler) .
$this->fetchContents($crawler, $container)
);
return $this;
}
/**
* Prepare an HTML title tag.
*
* @param Crawler $crawler
* @return string
*/
protected function makeTitle($crawler)
{
$pageTitle = $crawler->filter('head > title')->html();
return "<title>{$pageTitle}</title>";
}
/**
* Fetch the PJAX-specific HTML from the response.
*
* @param Crawler $crawler
* @param string $container
* @return string
*/
protected function fetchContents($crawler, $container)
{
$content = $crawler->filter($container);
if (! $content->count()) {
abort(422);
}
return $content->html();
}
/**
* Set the PJAX-URL header to the current uri.
*
* @param Response $response
* @param Request $request
*/
protected function setUriHeader(Response $response, Request $request)
{
$response->header(
'X-PJAX-URL', $request->getRequestUri()
);
}
}
@jesseleite
Copy link

@JeffreyWay Why not package this up?

@davidthingsaker
Copy link

If anyone needs this for Lumen, I have modified @JeffreyWay's version above here just needed tweaking as I found Lumen doesnt have symfony's CssSelector Component.

Copy link

ghost commented Dec 11, 2015

Thanks for this code. Greetings From Chile.

@JacobBennett
Copy link

Copy link

ghost commented May 21, 2016

Thanks for this code @JeffreyWay

@andervilo02
Copy link

andervilo02 commented Mar 31, 2017

To use this, I only have to register on kernel.php and use like other middleware?

I'm face problems using pjax. Google Chrome Console Log only return: 500 Internal Server Error

I register this middleware in kernel and include the pjax.js asset, but not works.

This is my request and response header: http://prntscr.com/er0cu0

You know to solve this problem?

@ngrcode
Copy link

ngrcode commented Sep 1, 2018

hi I have problem with this middleware and this is my error after adding this file
The current node list is empty.

@ngrcode
Copy link

ngrcode commented Sep 4, 2018

and this is my middleware
#<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Symfony\Component\DomCrawler\Crawler;
class PjaxMiddleware
{
/**
* Handle an incoming request.
*
* @param Request $request
* @param Closure $next
* @return mixed
/
public function handle($request, Closure $next)
{
$response = $next($request);
if (! $request->pjax() || $response->isRedirection()) {
return $response;
}
$this->filterResponse($response, $request->header('X-PJAX-CONTAINER'))
->setUriHeader($response, $request);
return $response;
}
/
*
* Prepare the PJAX-specific response content.
*
* @param Response $response
* @param string $container
* @return $this
/
protected function filterResponse(Response $response, $container)
{
$crawler = new Crawler($response->getContent());
$response->setContent(
$this->makeTitle($crawler) .
$this->fetchContents($crawler, $container)
);
return $this;
}
/
*
* Prepare an HTML title tag.
*
* @param Crawler $crawler
* @return string
/
protected function makeTitle($crawler)
{
$pageTitle = $crawler->filter('head > title')->html();
return "<title>{$pageTitle}</title>";
}
/
*
* Fetch the PJAX-specific HTML from the response.
*
* @param Crawler $crawler
* @param string $container
* @return string
/
protected function fetchContents($crawler, $container)
{
$content = $crawler->filter($container);
if (! $content->count()) {
abort(422);
}
return $content->html();
}
/
*
* Set the PJAX-URL header to the current uri.
*
* @param Response $response
* @param Request $request
*/
protected function setUriHeader(Response $response, Request $request)
{
$response->header(
'X-PJAX-URL', $request->getRequestUri()
);
}
}

@ngrcode
Copy link

ngrcode commented Sep 4, 2018

which version of crawler are u using?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment