Vấn đề
Twig bối cảnh không bao giờ được lưu trữ trong các mẫu đối tượng, vì vậy đây sẽ rất khó khăn để tìm một cách sạch để đạt được điều này. Ví dụ, mã Twig sau:
{% set test = 'Hello, world' %}
sẽ biên dịch để:
<?php
class __TwigTemplate_20df0122e7c88760565e671dea7b7d68c33516f833acc39288f926e234b08380 extends Twig_Template
{
/* ... */
protected function doDisplay(array $context, array $blocks = array())
{
// line 1
$context["test"] = "Hello, world";
}
/* ... */
}
Như bạn thấy, bối cảnh kế thừa không được đưa vào phương pháp doDisplay bằng cách tham khảo, và không bao giờ được lưu giữ trong đối tượng chính nó (như $this->context = $context
). Tính năng này cho phép các mẫu có thể sử dụng lại được và thân thiện với bộ nhớ.
Giải pháp 1: sử dụng các biến toàn cầu
Tôi không biết nếu bạn nhận thức được Global Variables trong cành. Bạn có thể làm một loạt các hacks với họ.
Cách sử dụng đơn giản nhất là tải tất cả các hình cầu trong môi trường cành cây của bạn.
$loader = new Twig_Loader_Filesystem(__DIR__.'/view');
$env = new Twig_Environment($loader);
$env->addGlobal('foo', 'bar');
$env->addGlobal('Hello', 'world!');
Sau đó, bạn có thể sử dụng {{ foo }}
và {{ Hello }}
toàn bộ ứng dụng của bạn.
Nhưng có 2 vấn đề ở đây:
Khi bạn đang cố gắng để tải biến từ các tập tin cành lá, tôi giả sử bạn có rất nhiều biến thể khởi tạo tùy thuộc vào tính năng của bạn và không muốn để tải mọi thứ mọi lúc.
bạn đang tải các biến từ tập lệnh PHP chứ không phải từ Twig và câu hỏi của bạn muốn nhập biến từ tệp twig.
Giải pháp 2: sử dụng một phần mở rộng Twig
Bạn cũng có thể tạo ra một phần mở rộng lưu trữ cung cấp một chức năng save
để tồn tại bối cảnh của một số mẫu ở đâu đó, và một hàm restore
sáp nhập bối cảnh này được lưu trữ trong một số khác.
proof_of_concept.php
<?php
require __DIR__.'/vendor/autoload.php';
class StorageTwigExtension extends Twig_Extension
{
protected $storage = [];
public function getFunctions() {
return [
new Twig_SimpleFunction('save', [$this, 'save'], ['needs_context' => true]),
new Twig_SimpleFunction('restore', [$this, 'restore'], ['needs_context' => true]),
];
}
public function save($context, $name) {
$this->storage = array_merge($this->storage, $context);
}
public function restore(&$context, $name) {
$context = array_merge($context, $this->storage);
}
public function getName() {
return 'storage';
}
}
/* usage example */
$loader = new Twig_Loader_Filesystem(__DIR__.'/view');
$env = new Twig_Environment($loader);
$env->addExtension(new StorageTwigExtension());
echo $env->render('test.twig'), PHP_EOL;
cành lá/variables.twig
{% set foo = 'bar' %}
{% set Hello = 'world!' %}
{{ save('test') }}
cành lá/test.twig
{% include 'variables.twig' %}
{{ restore('test') }}
{{ foo }}
Lưu ý: nếu bạn chỉ muốn nhập biến mà không thực sự render gì bên trong cành lá/variables.twig, bạn cũng có thể sử dụng:
{% set tmp = include('variables.twig') %}
{{ restore('test') }}
{{ foo }}
Cuối cùng lưu ý
Tôi không quen với cành lá Javascript cổng, nhưng có vẻ như bạn vẫn có thể mở rộng nó, đó là đi của bạn :)
Có một hoặc hai tệp trong khối mã thứ hai không? –
@ A.L Chúng là các tệp riêng biệt, tôi đã cập nhật câu hỏi của mình. – Evans
Bạn có thể giải thích tại sao bạn muốn làm điều này không? Có thể xem tài liệu [include] (http://twig.sensiolabs.org/doc/tags/include.html) một tên mẫu không được mong đợi. Có lẽ bạn có thể giải quyết nó với một chức năng tùy chỉnh cành. – DarkBee