2016-04-28 21 views
8

Tôi có container.twig bao gồm component.twig và truyền một đối tượng có tên 'mock'.Bao gồm một tệp tin twig và chuyển các biến từ một tệp riêng biệt?

Trong container.twig:

{% set mock = { 
    title : "This is my title" 
} 
%} 

{% include 'component.twig' with mock %} 

này đang làm việc tốt nhưng tôi muốn di chuyển dữ liệu giả để tập tin riêng của mình. Đây làm việc isnt:

Container.twig

{% include 'component.twig' with 'mock.twig' %} 

Trong mock.twig

{% set mock = { 
    title : "This is my title" 
} 
%} 

Im sử dụng ngụm-cành lá nhưng nó hoạt động như cành lá tiêu chuẩn trong hầu hết các khía cạnh. https://github.com/zimmen/gulp-twig

+0

Có một hoặc hai tệp trong khối mã thứ hai không? –

+1

@ 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

+0

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

Trả lời

2

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 }}{{ 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 :)

3

Vì quy tắc phạm vi của Twig (mà tôi giả định được nhân bản bằng phiên bản gulp), bạn không thể chuyển các biến từ mẫu con mà không tạo hàm trợ giúp. Điều gần nhất bạn có thể làm là sử dụng thừa kế để nhân rộng điều này.

Như vậy, tập tin mock.twig của bạn sẽ trở thành

{% set mock = { 
     title : "This is my title" 
    } 
%} 
{% block content %}{% endblock %} 

container.twig của bạn sẽ sau đó trở thành

{% extends 'mock.twig' %} 
{% block content %} 
    {% include 'component.twig' with mock %} 
{% endblock %} 

này đạt được mục tiêu của mình tách nội dung giả từ các mẫu cho nhiều nhất một phần và, sử dụng mở rộng động, bạn có thể làm điều gì đó như

{% extends usemock == 'true' 
    ? 'contentdumper.twig' 
    : 'mock.twig' %} 

với con tệp tentdumper.twig chỉ là một sơ khai như vậy

{% block content %}{% endblock %} 

và sau đó đặt biến usemock để xác định xem bạn có đang sử dụng dữ liệu giả hay không.

Hy vọng điều này sẽ giúp, mặc dù nó không thực sự giải quyết được vấn đề chính xác mà bạn đang gặp phải.

Các vấn đề liên quan