digitaltrix / scythe-view

将刀片模板渲染为 PSR-7 响应对象。

v0.9.3 2018-04-03 21:29 UTC

This package is auto-updated.

Last update: 2024-09-12 06:01:12 UTC


README

发音 [sahyth] - 古英语中用于手工切割的弯曲刀

Build Status

这是 Laravel Blade 的简单实现,用于将视图中的 Blade 语法渲染为 PSR-7 响应对象。它没有依赖项,并且与 Slim 框架 3 配合得很好。

如果你不熟悉 Blade 作为视图渲染器,它主要的优点是它的 轻量级,它本质上是一个简单的 PHP 包装器。语法的行为与 PHP 程序员预期的行为一致,因此对于熟悉 PHP 的人来说,理解 Blade 所需的思维转换非常少。

此实现的目标不是功能兼容性,这超出了本项目范围。它提供了一些有用的方法和通过回调添加自定义指令的能力。如果您需要完整的兼容性,您可以通过 philo/laravel-blade 使用完整的 Laravel Blade 包。

注意:当前不支持的功能 @verbatim @component @hasSection @auth * @guest *

这些可以通过指令回调添加以适应您的框架

目录

安装

使用 Composer 安装

composer require dijitaltrix/scythe-view

入门指南

与 Slim 3 一起使用

将 Scythe 添加到容器中,传递所需的参数 views_pathcache_path

$container['view'] = function($c) {
    return new \Dijitaltrix\Views\Scythe([
        'views_path' => 'path/to/views',
        'cache_path' => 'path/to/cache',
    ]);
}

假设您将 views_path 设置为 app/src/views,您可以使用它如下

// app/routes.php
$app->get('/hello/{name}', function ($request, $response, $args) {
    return $this->view->render($response, "hello", $args);
});

// app/src/views/hello.blade.php
<h1>Hello {{ $name }}</h1>

您可以使用下文中的方法添加命名空间和指令。

与任何 PSR-7 项目一起使用

$view = new \Dijitaltrix\Views\Scythe([
    'views_path' => 'path/to/views',
    'cache_path' => 'path/to/cache',
]);

$response = $view->render(new Response(), "/path/to/template", $data);

语言参考

注释

{{-- Upon rendering all this will be removed --}}

可以使用 @php @endphp 标记来打开和关闭 PHP 标签

变量

除了 echo raw 外,所有变量显示函数都将使用 htmlentities() 对输出进行转义。例如:!!$danger !!}

echo

显示 $name 的内容

{{ $name }}
// <?php echo htmlentities($name); ?>

echo raw

在显示用户生成数据时请谨慎使用此功能

{!! $name !!}
// <?php echo $name; ?>

echo 默认值

如果 $name 未设置,则显示 '匿名'。

{{ $name or 'Anonymous' }}
// <?php (isset($name)) ? htmlentities($name) : 'Anonymous'; ?>

set

设置变量的值

@set($muppet, 'Kermit')
// <?php $muppet = 'Kermit'; ?>

unset

从作用域中删除变量

@unset($muppet)
// <?php unset($muppet); ?>

isset

检查变量是否已设置

@isset($muppet)
<p>He is here</p>
@endisset

has

检查变量是否已设置并且具有值

@has($muppet->name)
<p>Muppet name is set and is not empty</p>
@endhas

变量操作

Twig 拥有一些非常棒的字符串修改器,我们也有这些 ;). 以下所有示例都包含在 htmlentities() 中

upper

将字符串转换为大写

@upper($name)
<!-- KERMIT -->

lower

将字符串转换为小写

@lower($name)
<!-- kermit -->

ucfirst

将字符串转换为小写,然后首字母大写

@ucfirst($name)
<!-- Kermit -->

ucwords

将字符串转换为小写,然后每个单词首字母大写

@ucwords($name)
<!-- Kermit The Frog -->

format

这是 sprintf 函数的包装器,以帮助您的肌肉记忆,您也可以将其称为 @sprintf

@format("There were %s in the %s", "dogs", "yard")
<!-- There were dogs in the yard -->

wrap

@wrap("This is a really long line that should wrap somewhere otherwise it may shatter the internet into pieces!")
<!-- 
This is a really long line that should wrap somewhere otherwise it may
shatter the internet into pieces!
-->

<!-- With an optional limit -->
@wrap("This is a really long line that should wrap somewhere otherwise it may shatter the internet into pieces!", 25)

<!--
This is a really long
line that should wrap 
somewhere otherwise
it may shatter the
internet into pieces!
-->

控制结构

if

Scythe 支持所有可能的 if 结构组合

@if (true)
<p>This will always show</p>
@endif
@if (true)
<p>This will always show</p>
@else
<p>This will never show</p>
@endif
@if ($i == 1)
<p>i is equal to one</p>
@elseif ($i == 2)
<p>i is equal to two</p>
@else
<p>i is something else entirely</p>
@endif

unless

如果不是某物,那么是什么?

@unless($bank > 1000000)
<p>Keep on working</p>
@endunless

switch

@switch($i)
    @case(1)
        <p>i is equal to one</p>
        @break
    @case(2)
        <p>i is equal to two</p>
        @break
    @default
        <p>i is something else entirely</p>
@endswitch

循环

for

@for ($i = 0; $i < 11; $i++)
    Currently reading {{ $i }}
@endfor

foreach

@foreach ($muppets as $muppet)
    <p>Say howdy to {{ $muppet->name }}</p>
@endforeach

forelse

@forelse ($muppets as $muppet)
    <p>Say howdy to {{ $muppet->name }}</p>
@empty
    <p>Sadly no muppets can be with us today</p>
@endforelse

while

@while (true)
    <p>One Infinite Loop</p>
@endwhile

each

foreach 循环的一个更紧凑版本,它添加了 @include 命令

@each('muppets/profile', $muppets, 'muppet')

// @foreach ($muppets as $muppet)
//   @include('muppets/profile')
// @endforeach

它还支持在没有任何记录时显示视图以生成 forelse 结构

@each('muppets/profile', $muppets, 'muppet', 'muppets/profile-missing')

// @forelse ($muppets as $muppet)
//   @include('muppets/profile')
// @empty
//   @include('muppets/profile-missing')
// @endforelse

循环变量

提供循环助手,这与Blade的$loop助手完全相同。

尚未实现

继承

扩展

调用父模板以插入部分

@extends('muppets/cast/list')

部分

部分定义了要插入父模板的内容区域

@section('title', 'Muppets cast listing')

@section('head')
<h1>Muppets cast listing</h1>
@endsection

父模板

可以使用@parent指令在模板之间合并部分。

<!-- parent.blade.php -->
@section('sidebar')
    <h3>This is the sidebar content</h3>
@show

<!-- child.blade.php -->
@section('sidebar')
    @parent
    <ul>
        <li>This is a list item</li>
        <li>And so is this</li>
        <li>Another item in the list</li>
    </ul>
@endsection

将显示为

<h3>This is the sidebar content</h3>
<ul>
    <li>This is a list item</li>
    <li>And so is this</li>
    <li>Another item in the list</li>
</ul>

替换或yield

用子模板部分定义的内容替换

<title>@replace('title')</title>
<!-- OR -->
<title>@yield('title')</title>
<!-- <title>Muppets cast listing</title> -->

包含

包含另一个blade模板,所有变量都将可用于包含的模板

@section('body')
<ul>
@foreach ($muppets as $muppet)
    @include('muppets/cast/member')
@endforeach
</ul>
@endsection

指令

定义自己的占位符,通过回调插入内容

// output a string
$view->addDirective('/@hello/i', 'Hello world');

// output the result of a callback
$view->addDirective('/@hello/i', function(){
    return 'Hello world';
});
//TODO pass parameters from directive to callback

堆栈

从子模板推送至堆栈,然后它们将被附加到父模板中的@stack指令

// child.blade.php
@extends('parent')

@section('title', 'The title')

@push('head')
<link rel="stylesheet" href="/css/child.css" type="text/css" media="screen">
@endpush

@push('scripts')
<script src="child.js"></script>
<script type="text/javascript">
    alert('Some alert');
</script>
@endpush

// parent.blade.php
<html>
<head>
    @stack('head')
</head>
<body>
    @yield('body')
    @stack('scripts')
</body>
</html>
    

方法

除了Blade语法外,渲染实例还提供以下方法

addDirective($placeholder, $callback)

$view->addDirective('@rand', function() {
    if (rand(1,10) > 5) {
        throw new Exception("This is pointless");
    }
});

addNamespace($name, $path)

命名空间允许您在默认的views_path之外添加视图路径。用于外部包或帮助将代码组织成模块。

// add the namespace name first, followed by the path to the root of the namespace
$view->addNamespace("admin", "/src/Admin/views");

// namespaces are referenced with '::'
// for example
$view->exists('admin::user/dashboard');

// this will load the file at src/Admin/views/user/profile.blade.php
$view->render($response, 'admin::user/profile', $args);

exists($template)

exists()函数将返回true,如果模板文件在视图路径中,否则返回false

$view->exists('admin/dashboard')

// Namespaces are specified as follows
$view->exists('admin::user/dashboard')

renderString($string, $data=[])}

renderString()函数将解析字符串,将任何blade命令转换。

$blade = "<h1>{{ $title }}</h1>";

$view->renderString($blade, ['title'=>'The Muppet Show']);

// <h1>The Muppet Show</h1>

做还是不做

组件和插槽

没有计划引入此功能,使用@include作为替代。

@inject

没有计划实现此功能,我认为允许视图拉取它喜欢的任何数据类等不是好的实践。数据和依赖应在“领域”中生成,并注入到视图响应中,因此视图应该已经拥有所需的一切。

因为模板最终渲染为纯PHP,所以当然可以在PHP标签之间的任何代码中执行。

自定义if语句

可以通过自定义指令添加类似的功能