2012-10-18 28 views
6

Tôi cố tải một tệp mẫu base.html.twig đơn giản đã được di chuyển từ vị trí mặc định của symfony app/Resources/views/ đến vị trí tùy chỉnh theme/.Symfony2: Twig: Tệp mẫu mặc định ở vị trí tùy chỉnh

Mẫu tập tin chứa:

<!DOCTYPE html> 
    <html> 
    <head> 
    ... 
    </head> 
    <body> 
     {% block body %}{% endblock %} 
    </body> 
    </html> 

Mở rộng tập tin mẫu trên bởi bộ điều khiển Acme\Core\CoreBundle\Controller bằng cách sử dụng các mẫu điều khiển cụ thể

{% extends '::base.html.twig' %} 
    {% block body %} 
     Hello world! 
    {% endblock %} 

dẫn đến một lỗi nói Unable to find template "::base.html.twig" in "AcmeCoreCoreBundle:Default:index.html.twig"..

Làm cách nào để có thể nói cho symfony biết nơi tìm tệp mẫu trong không gian toàn cầu?

Xin cảm ơn trước.

+0

thể được thực hiện với các '\ Twig_Loader_Filesystem :: addPath ($ path, $ namespace = '__main __')' (xem [Nguồn] (https : //github.com/fabpot/Twig/blob/master/lib/Twig/Loader/Filesystem.php)) nhưng không chắc chắn nơi bạn sẽ gọi nó. Cũng đã có một cái nhìn tại cấu hình TwigBundle, nhưng không giống như có một tùy chọn cho nó ở đó. Nếu ai đó để mở rộng hơn nữa về điều này, nó có thể giúp đỡ. –

Trả lời

7

Do gợi ý của Adam, tôi có thể tự trả lời câu hỏi. Vì vậy, tôi muốn cung cấp câu trả lời của tôi nếu có ai quan tâm.

Cung cấp phần mở rộng cành (lớp Acme\DemoBundle\Twig\Extension\DemoExtension) mà bạn có thể sử dụng. Thay đổi hàm tạo thành

public function __construct(FilesystemLoader $loader) 
    { 
    $this->loader = $loader; 
    $this->loader->addPath('path/to/your/directory'); 
    } 

Bây giờ hãy yêu cầu symfony đăng ký tiện ích mở rộng. Chỉnh sửa config.yml tập tin của bạn (ví dụ app/config/config.yml) và thêm

services: 
    demo.twig.extension 
     class: Acme\DemoBundle\Twig\Extension\DemoExtension 
     tags: 
     - { name: twig.extension } 
     arguments: 
     - @Twig.loader 

Cuối cùng nhưng không kém phần thay đổi tập tin mở rộng cành lá của bạn và loại bỏ các :: từ mẫu mặc định của bạn namespace: {% extends 'base.html.twig' %}.

+1

Vui mừng gợi ý của tôi đã chỉ cho bạn đúng hướng và cảm ơn bạn đã chia sẻ. Giải pháp này là thanh lịch hơn là một trong những tôi ban đầu đã suy nghĩ về việc cung cấp. –

1

Từ một hành động mà bạn có thể nhận được 'twig.loader'-dịch vụ từ -container (dịch vụ):

$this->get('twig.loader')->addPath('path/to/your/directory'); 

Và sau đó bạn có thể sử dụng con đường này trong mẫu của bạn.

@besta đã làm điều đó với phần mở rộng cành, tiêm bộ nạp ghép vào bộ tạo. Nhưng trong tiện ích mở rộng, bạn có thể sử dụng môi trường:

class YourTwigExtension extends \Twig_Extension { 
... 
    public function initRuntime(\Twig_Environment $environment) { 
     $this->environment = $environment; 
     $this->environment->getLoader()->addPath(__DIR__ . '/Resources/views'); 
    } 
... 
} 
5

Tôi đã tìm ra giải pháp khác để triển khai nhanh hơn. Tôi đã thử câu trả lời được chấp nhận về câu hỏi này trước nhưng vẫn gặp phải vấn đề về đường dẫn.

Ngay trước khi tôi làm cho gọi mẫu tôi đã thêm đường dẫn đến container twig.loader như thế này:

$this->container->get('twig.loader')->addPath('../../../../theme/', $namespace = '__main__'); 

Bây giờ cành mẫu sẽ được trả lại từ một thư mục gọi là 'chủ đề' trong thư mục gốc. Tôi đã tìm thấy giải pháp này từ chính Fabien Pontencier (tác giả của Symfony và Twig) để trả lời một lỗi nhỏ ở đây: https://github.com/symfony/symfony/issues/1912

+0

tìm kiếm chính xác cái này! – Subdigger

11

Có một tính năng gốc để làm chính xác những gì bạn muốn một cách tốt đẹp. Về cơ bản bạn có thể thêm một không gian tên twig vào cấu hình cành trong ứng dụng/cấu hình.yml như thế này:

twig: 
    # ... 
    paths: 
     "%kernel.root_dir%/../vendor/acme/foo-bar/templates": foo_bar 

Điều này tạo ra một bí danh đến thư mục vendor/acme/foo-bar/templates và sau đó bạn có thể sử dụng nó để làm cho mẫu của bạn hoặc từ các bộ điều khiển:

return $this->render(
    '@foo_bar/template.html.twig', 
    $data 
); 

hoặc từ các mẫu cành lá khác

{% include '@foo_bar/template.html.twig' %} 

Nguồn: sổ nấu ăn chính thức http://symfony.com/doc/current/cookbook/templating/namespaced_paths.html

1

Giả sử bạn muốn điều này được thực hiện trên toàn cầu, loại công cụ này có nghĩa là phải được thực hiện trong một compiler pass.

Nó sẽ sạch hơn và hiệu quả như thế này:

<?php 

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; 
use Symfony\Component\DependencyInjection\ContainerBuilder; 

class CustomCompilerPass implements CompilerPassInterface 
{ 
    public function process(ContainerBuilder $container) 
    { 
     $loader = $container->getDefinition('twig.loader'); 
     $loader->addMethodCall('addPath', array('/path/to/views')); 
    } 
} 
+0

Điều này không có tác dụng, nó trở lại với '' Bạn đã yêu cầu một dịch vụ không tồn tại "twig.loader" '. Bạn cần sử dụng 'twig.loader.filesystem' – sschueller

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