Skip to content

Commit

Permalink
Merge pull request #79 from BKWLD/feature/components
Browse files Browse the repository at this point in the history
Drop Laravel 4 and 5
  • Loading branch information
kylekatarnls committed Jan 22, 2020
2 parents b90a790 + dfaf02a commit 57875b8
Show file tree
Hide file tree
Showing 27 changed files with 488 additions and 919 deletions.
77 changes: 32 additions & 45 deletions README.md
Expand Up @@ -25,48 +25,27 @@ create it with: `composer create-project --prefer-dist laravel/laravel my-new-pr

Then run `composer require bkwld/laravel-pug`.

### Laravel 4 and 5

Errors are properly displayed through Ignition since Laravel 6.

In older versions, to get a line and offset in pug source files well formatted in standard
Laravel error display to debug errors, we recommend
you to implement the following in your **app/Exceptions/ExceptionHandler**:
## Usage

```php
<?php

namespace App\Exceptions;

use Bkwld\LaravelPug\ExceptionHandlerTrait;
use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;

class Handler extends ExceptionHandler
{
use ExceptionHandlerTrait;

/* ... */

/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $exception
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $exception)
{
return $this->filterErrorResponse($exception, $request, parent::render($request, $exception));
}

}
Route::get('/', function () {
return view('my-page');
});
```

Note: this will works for pure `.pug` file, not `.pug.blade` since the
error will happen in the blade engine.
Will now try to load `views/my-page.pug` first, or `views/my-page.blade.pug`
or fallback to the default blade engine loading `views/my-page.blade.php`.

## Usage
As with Blade, you can pass variables to your view:

```php
Route::get('/', function () {
return view('my-page', [
'user' => Auth::user(),
'messages' => ['Hello', 'Bye'],
]);
});
```

Any file with the extension `.pug` will be compiled as a pug template.
Laravel Pug also registers the `.pug.blade` which also compile blade code
Expand All @@ -77,16 +56,23 @@ in the same way as Blade templates; the compiled template is put in your
storage directory. Thus, you don't suffer compile times on every page load.

In other words, just put your Pug files in the regular views directory
and name them like `whatever.pug`. You reference them in Laravel like normal:
and name them like `whatever.pug`. You reference them in Laravel like normal
such as `view('home.whatever')` for `resources/views/home/whatever.pug`.

The Pug view files can work side-by-side with regular PHP views.

### Use Blade in Pug templates

This feature is designed for transition purpose, since every blade
features are available in pug, you would not need both.

To use Blade templating within your Pug, just name the files with
`.blade.pug` extensions.

* **Laravel 4** : `View::make('home.whatever')` for `app/views/home/whatever.pug`
* **Laravel >= 5** : `view('home.whatever')` for `resources/views/home/whatever.pug`
<details>
<summary>Read more</summary>

The Pug view files can work side-by-side with regular PHP views. To use Blade
templating within your Pug, just name the files with `.pug.blade` extensions.
This feature is designed for transition
purpose, since every blade features are available in pug, you would not
need both. And be aware that this mode will first render your template with
Be aware that this mode will first render your template with
pug, then give the output to render to blade, it means your template must
have a valid pug syntax and must render a valid blade template. This also
means blade directives are only available through pug text output, see the
Expand All @@ -109,6 +95,7 @@ if one === 1
div $one = 1
p=two
```
</details>

### Use in Lumen

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Expand Up @@ -6,7 +6,7 @@
"php": "^7.2",
"illuminate/support": "^6.0.0",
"illuminate/view": "^6.0.0",
"phug/component": "^1.1.0",
"phug/component": "^1.1.3",
"pug-php/pug": "^3.3.1",
"pug-php/pug-assets": "^1.0.1",
"pug/installer": "^1.0.0",
Expand Down
3 changes: 0 additions & 3 deletions config/config.php
Expand Up @@ -7,7 +7,4 @@
* @see https://www.phug-lang.com/#options
*/

// Required for extending layouts
'basedir' => resource_path('views'),
'debug' => env('APP_DEBUG', false),
];
6 changes: 4 additions & 2 deletions src/Install.php
Expand Up @@ -2,9 +2,11 @@

namespace Bkwld\LaravelPug;

use Composer\Script\Event;

class Install
{
public static function publishVendor($event)
public static function publishVendor($event): void
{
$currentDirectory = getcwd();

Expand All @@ -13,7 +15,7 @@ public static function publishVendor($event)
}

if (file_exists('artisan')) {
/** @var \Composer\Script\Event $event */
/** @var Event $event */
$io = $event->getIO();

$cmd = 'php artisan vendor:publish --provider="'.ServiceProvider::class.'"';
Expand Down
10 changes: 6 additions & 4 deletions src/PugBladeCompiler.php
Expand Up @@ -5,9 +5,8 @@
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Facades\Blade;
use Illuminate\View\Compilers\BladeCompiler;
use Illuminate\View\Compilers\CompilerInterface;

class PugBladeCompiler extends BladeCompiler implements CompilerInterface
class PugBladeCompiler extends BladeCompiler implements PugHandlerInterface
{
use PugHandlerTrait;

Expand All @@ -24,7 +23,10 @@ public function __construct(array $pugTarget, Filesystem $files, array $config,
$this->construct($pugTarget, $files, $config, $defaultCachePath);
}

protected function enableBladeDirectives()
/**
* Copy custom blade directives.
*/
protected function enableBladeDirectives(): void
{
/** @var \Illuminate\View\Compilers\BladeCompiler $blade */
$blade = Blade::getFacadeRoot();
Expand All @@ -45,7 +47,7 @@ protected function enableBladeDirectives()
*
* @return void
*/
public function compile($path = null)
public function compile($path = null): void
{
$app = Blade::getFacadeApplication();

Expand Down
5 changes: 2 additions & 3 deletions src/PugCompiler.php
Expand Up @@ -4,9 +4,8 @@

use Illuminate\Filesystem\Filesystem;
use Illuminate\View\Compilers\Compiler;
use Illuminate\View\Compilers\CompilerInterface;

class PugCompiler extends Compiler implements CompilerInterface
class PugCompiler extends Compiler implements PugHandlerInterface
{
use PugHandlerTrait;

Expand All @@ -32,7 +31,7 @@ public function __construct(array $pugTarget, Filesystem $files, array $config,
*
* @return void
*/
public function compile($path)
public function compile($path): void
{
$this->compileWith($path);
}
Expand Down
56 changes: 32 additions & 24 deletions src/PugException.php
Expand Up @@ -5,11 +5,19 @@
use Facade\Ignition\Exceptions\ViewException;
use Illuminate\View\Engines\CompilerEngine;
use Phug\Util\Exception\LocatedException;
use Phug\Util\SourceLocation;
use Phug\Util\SourceLocationInterface;
use Throwable;

class PugException extends ViewException
{
/**
* Wrap a given raw error/exception in a relocated PugException.
*
* @param CompilerEngine $context current $this context (the engine that compiled the template)
* @param Throwable $previous the raw error/exception
*
* @throws Throwable throw $previous if it cannot be located in the template.
*/
public function __construct(CompilerEngine $context, Throwable $previous)
{
$message = $previous->getMessage();
Expand All @@ -18,31 +26,10 @@ public function __construct(CompilerEngine $context, Throwable $previous)
$file = $previous->getFile();
$line = $previous->getLine();

if ($compiler instanceof PugCompiler || $compiler instanceof PugBladeCompiler) {
if ($compiler instanceof PugHandlerInterface) {
$print = 'error-'.md5_file($file).'-'.$line.'-'.md5($previous->getTraceAsString());
$cachePath = storage_path('framework/views/'.$print.'.txt');
$location = null;

if (file_exists($cachePath)) {
list($path, $line, $offset, $offsetLength) = unserialize(file_get_contents($cachePath));
$location = new SourceLocation($path, $line, $offset, $offsetLength);
} else {
$pug = $compiler->getPug();
$error = $pug->getDebugFormatter()->getDebugError(
$previous,
file_get_contents($file),
$file
);

if ($error instanceof LocatedException && ($location = $error->getLocation())) {
file_put_contents($cachePath, serialize([
$location->getPath(),
$location->getLine(),
$location->getOffset(),
$location->getOffsetLength(),
]));
}
}
$location = $this->getLocation($compiler, $cachePath, $file, $previous);

if ($location) {
$file = $location->getPath();
Expand All @@ -52,4 +39,25 @@ public function __construct(CompilerEngine $context, Throwable $previous)

parent::__construct($message, $code, 1, $file, $line, $previous);
}

protected function getLocation(PugHandlerInterface $compiler, string $cachePath, string $file, Throwable $previous): ?SourceLocationInterface
{
if (file_exists($cachePath)) {
return unserialize(file_get_contents($cachePath));
}

$location = null;
$pug = $compiler->getPug();
$error = $pug->getDebugFormatter()->getDebugError(
$previous,
file_get_contents($file),
$file
);

if ($error instanceof LocatedException && ($location = $error->getLocation())) {
file_put_contents($cachePath, serialize($location));
}

return $location;
}
}
87 changes: 87 additions & 0 deletions src/PugHandlerInterface.php
@@ -0,0 +1,87 @@
<?php

namespace Bkwld\LaravelPug;

use Illuminate\Filesystem\Filesystem;
use Illuminate\View\Compilers\CompilerInterface;
use InvalidArgumentException;
use Phug\CompilerInterface as PhugCompiler;
use Pug\Pug;

interface PugHandlerInterface extends CompilerInterface
{
/**
* Common pug compiler constructor.
*
* @param array $pugTarget
* @param Filesystem $files
* @param array $config
*/
public function construct(array $pugTarget, Filesystem $files, array $config, $defaultCachePath = null);

/**
* Lazy load Pug and return the instance.
*
* @return Pug
*/
public function getPug();

/**
* Returns cache path.
*
* @return string $cachePath
*/
public function getCachePath();

/**
* Get an option from pug engine or default value.
*
* @param string $name
* @param null $default
*
* @return mixed|null
*/
public function getOption($name, $default = null);

/**
* @param string $cachePath
*/
public function setCachePath($cachePath);

/**
* Determine if the view at the given path is expired.
*
* @param string $path
*
* @return bool
*/
public function isExpired($path): bool;

/**
* Return path and set it or get it from the instance.
*
* @param string $path
*
* @throws InvalidArgumentException
*
* @return string
*/
public function extractPath($path): ?string;

/**
* Returns the object the more appropriate to compile.
*/
public function getCompiler(): PhugCompiler;

/**
* Compile the view at the given path.
*
* @param string $path
* @param callable|null $callback
*
* @throws InvalidArgumentException
*
* @return void
*/
public function compileWith($path, callable $callback = null): void;
}

0 comments on commit 57875b8

Please sign in to comment.