2014-01-09 17 views
3

在我的包中,我有一個Resources/public/images/image.jpg文件。獲取指定包中的圖像路徑

該圖像通過http://localhost/bundles/mybundle/images/image.jpg

我怎樣才能從控制器這/bundles/mybundle前綴是訪問?
我希望能夠生成公共文件的路徑,而不用硬編碼/bundles/mybundle前綴。在SRC

{% image '@AcmeFooBundle/Resources/public/images/example.jpg' %} 
    <img src="{{ asset_url }}" alt="Example" /> 
{% endimage %} 

或直接:

+0

嘗試修剪成數組的段。然後用它與數組索引。 – ankur140290

回答

4

我想創建一個服務,它會做到這一點

創建服務

這樣做的主要職責:

從控制器,你可以得到相同的方式完整路徑類,是得到任何捆綁的默認網絡路徑爲任何資源。
assets:install命令定義,對於每個束的相對路徑預期是/bundles/foobar/對於給定的FooBarBundle

的Acme \ FooBundle \ WebPathResolver

use Symfony\Component\HttpKernel\Bundle\BundleInterface; 

class WebPathResolver 
{ 
    /** 
    * Gets the prefix of the asset with the given bundle 
    * 
    * @param BundleInterface $bundle Bundle to fetch in 
    * 
    * @throws \InvalidArgumentException 
    * @return string Prefix 
    */ 
    public function getPrefix(BundleInterface $bundle) 
    { 
     if (!is_dir($bundle->getPath().'/Resources/public')) { 
      throw new \InvalidArgumentException(sprintf(
       'Bundle %s does not have Resources/public folder', 
       $bundle->getName() 
      )); 
     } 

     return sprintf(
      '/bundles/%s', 
      preg_replace('/bundle$/', '', strtolower($bundle->getName())) 
     ); 
    } 

    /** 
    * Get path 
    * 
    * @param BundleInterface $bundle Bundle to fetch in 
    * @param string   $type  Which folder to fetch in (image, css..) 
    * @param string   $resource Resource (image1.png) 
    * 
    * @return string Resolved path 
    */ 
    public function getPath(BundleInterface $bundle, $type, $resource) 
    { 
     $prefix = $this->getPrefix($bundle); 

     return sprintf('%s/%s/%s', $prefix, $type, $resource); 
    } 
} 

聲明它在你service.yml

沒什麼特別的,但是通常的服務

@ AcmeFooBundle /資源/配置/ services.yml

services: 
    acme_foo.webpath_resolver: 
     class: Acme\FooBundle\WebPathResolver 

使用

然後你可以用它在你的控制器這樣

的Acme \ FooBundle \控制器\ BarController :: bazAction

$bundle = $this->get('http_kernel')->getBundle('AcmeFooBundle'); 
$path = $this->get('acme.webpath_resolver')->getPath($bundle, 'image', 'foo.png'); 

echo $path; // Outputs /bundles/acmefoo/image/foo.png 
+0

謝謝,它運作良好! – hsz

+0

但是爲什麼要將包名稱作爲參數傳遞,因爲它可以被自動檢索? (請參閱我的答案)可以使用'getCurrentBundle()'函數或類似這樣的服務來改進它,不是嗎? – COil

+0

@COIL我解釋了你的答案的一些注意事項。爲此添加一個'getCurrentBundle'方法會添加一個'Request'依賴項。 (我希望你的意思是*「getCurrentControllerBundle」*) – Touki

1

您在模板中使用的資產,這樣

<img src="{{ asset('@AcmeFooBundle/Resources/public/images/example.jpg') }}" alt="Example" /> 

在css文件,你需要使用相對路徑。

$this->container->get('templating.helper.assets')->getUrl('@AcmeFooBundle/Resources/public/images/example.jpg'); 
+0

好的,謝謝 - 但我怎樣才能得到控制器的結果路徑? – hsz

+0

@hsz我已經編輯了我的帖子,但是我沒有看到爲什麼你需要它在控制器中。 –

+0

它返回'/ @ AcmeFooBundle/Resources/public/images/example.jpg' – hsz

0

你可以使用類似的東西,但假設路徑是小寫包名。

$controller = $request->attributes->get('_controller'); 
    $regexp = '/(.*)\\\Bundle\\\(.*)\\\Controller\\\(.*)Controller::(.*)Action/'; 
    preg_match($regexp, $controller, $matches); 
    $imagePath = '/bundles/'. strtolower($matches[2]). '/images/image.jpg'; 
+0

該解決方案有幾個問題。 1.你依賴於像'Foo \ Bundle \ Anything \ Controller \ BarController'這樣的控制器命名空間,這是錯誤的。一個包可能被命名爲'Foo \ Bar \ FoobarBundle',那麼你的模式將不匹配。此外,一個控制器[可以定義爲一個服務](http://symfony.com/doc/current/cookbook/controller/service.html),並且沒有任何東西強迫你用Controller控制器加後綴, action'。 2.你期望定義的請求變量可能不存在(例如:在'Console'中的用法) – Touki

+0

OK好吧,我明白了,但我在這裏假設所有的bundle和動作名稱對於給定的項目是一致的,通常情況下。 – COil