I am working on a Laravel project and I am very new to it. For now, I want to use blade templates to render views but I want it to search for views in different directories like <custom_dir>\views instead of default resources/views.
The <custom_dir> will be dynamic (it can be a variable).
Any ideas? I was thinking of a custom service provider and then extend the default function which renders views in Laravel inside it. But not sure how to implement it.
Edit:
I have user this link to extend the default functionality of include function in blade template engine. But this overrides the include functionality. I want to change the path and then call the default blade functionality
You could probably append the path to the configuration:
1) Statically, by modifying file config/view.php
'paths' => [
realpath(base_path('resources/views')),
//more paths here
],
2) Dynamically at runtime:
$paths = config('view.paths');
$paths[] = $newPathToAdd;
config(["view.paths" => $paths ]);
I suggest you use this in moderation otherwise you will just end up with a mess of directories with no real specified purpose.
You can create custom directories in resources\views directory and use them with something like this:
return view($customDirectory.'.index');
Where index is a template inside custom directory.
Related
I am using a module called Facebook which has a view helper called shareUrl. This view helper gets the Facebook share URL for any URL.
However, I have recently added another module called Twitter which also has a view helper called shareUrl.
In Zend Framework version 2 or 3, within views, how can I call one shareUrl view helper versus the other?
Just to clarify, the code in my view looks like the following:
$facebookShareUrl = $this->shareUrl('https://www.example.com/');
$twitterShareUrl = $this->shareUrl('https://www.example.com/');
I would like $facebookShareUrl and $twitterShareUrl to store the return values of two different view helpers.
If you've got two helpers with the same name, only one is available as it is registered under the given name within the servicemanager (viewhelpermanager). If you switch them around with loading the modules in your application.config.php you can change the default. But that is not a real solution to your problem.
So there are multiple ways to get the right viewhelper you need.
1) The best way is to setup an alias for the registered viewhelpers using their FQCN. See some example code where we create aliases that can be used in the viewherlpers like $this->facebookShareUrl('exmaple.com')
return [
'view_helpers' => [
'aliases' => [
'facebookShareUrl' => FacebookModule\Helper\ShareUrlHelper::class,
'twitterShareUrl' => TwitterModule\Helper\ShareUrlHelper::class,
],
]
]
2) Get the helper by its FQCN using the viewhelpermanager in the view itself, using the PhpRenderer instance. Within a view.phtml file
$viewHelperManager = $this->getHelperPluginManager();
$facebookShareUrlHelper = $viewHelperManager->get(FacebookModule\Helper\ShareUrl::class);
$twitterShareUrlHelper = $viewHelperManager->get(TwitterModule\Helper\ShareUrl::class);
I'm trying to send a variable to a twig file which is not in the typical location, Usually I'm loading views by specifying their path through the Bundle but the file I want to send a variable to is not, hierarchically, on the same level as the other twig templates.
I've a controller which looks like the following:
public function fooAction(Request $request)
{
*//Query*
return $this->render('Bundle:file.html.twig', array('varToSend' => $queryResult));
}
I'm pretty sure the Bundle:file.html.twig is wrong but I don't know how else to specify the relevant path in twig.
Twig you would get from container would not work with arbitrary paths, but you can initialize your own twig:
$twig = new \Twig_Environment(new \Twig_Loader_String());
$rendered = $twig->render(
file_get_contents('/path/to/your/file.html.twig'),
array('varToSend' => $queryResult)
);
If you need this in more than one place, consider making it a Symfony service in order to not initialize Twig Environment every time.
Note that renderer in this case won't have any of Symfony's Twig Extensions, you'll have to add them manually.
If possible, try to avoid this, and put templates into app/Resources/views or src/AppBundle/Resources/views directories.
You have to use a path like that :
return $this->render('Bundle:Something:file.html.twig', array(
'varToSend' => $queryResult
));
And put your file in this folder :
src/Bundle/Resources/views/Something/file.html.twig
My website is divided into separate modules. Every module has it's own specific css or js files.
Yii's assetManager creates a folder when I first open a page that uses my assets.
Unfortunately if I change something in my files Yii 1.x does not reload my css or js files.
I have to manually delete the web/assets folder. It is really annoying when you are developing the app.
This works when I add a module to the backend folder, but not when I'm creating a module in the vendor folder with my own namespace.
In Yii2 you can append a timestamp to the URLs of assets like this...
return [
// ...
'components' => [
'assetManager' => [
'appendTimestamp' => true,
],
],
];
This won't force the assets to reload on every request but whenever an asset file is changed the URL will change because of the timestamp & that will force the asset to be re-published.
You can set forceCopy = true.
class Assets extends AssetBundle{
public function init()
{
parent::init();
$this->publishOptions['forceCopy'] = true;
}
}
With respect to Yii1.x With assetManager you can do this by setting 'forceCopy' attribute to true in your config file
... copy the asset files and directories even if they already published
before. This property is used only during development stage
See forceCopy documentation here for more info.
Alternatively you can use linkAssets which will not copy the files but create an soft link between your asset files and yours assets directory. You cannot of course use both.
For the second part of the question I am assuming this is in Yii 2.x, you are supposed to use AssetBundles, you can register any namespace bundle from anywhere, you simply register it in the view with some like this
use vendor\myVendorName\myPackageName\assets\AppAsset;
AppAsset::register($this);
In my Laravel 4 application's root directory, I have a folder themes. Inside the themes folder, I have default and azure.
How can I access view from this themes/default folder in a specific route.
Route::get('{slug}', function($slug) {
// make view from themes/default here
});
My directory structure:
-app
--themes
---default
---azure
I need to load views from localhost/laravel/app/themes/default folder. Please explain this.
This is entirely possible with Laravel 4. What you're after is actually the view environment.
You can register namespace hints or just extra locations that the finder will cascade too. Take a look here
You'd add a location like so:
View::addLocation('/path/to/your/views');
It might be easier if you namespace them though, just in case you have conflicting file names as your path is appended to the array so it will only cascade so far until it finds an appropriate match. Namespaced views are loaded with the double colon syntax.
View::addNamespace('theme', '/path/to/themes/views');
return View::make('theme::view.name');
You can also give addNamespace an array of view paths instead of a single path.
Here I am not accessing my project from public folder. Instead of this I am accessing from project root itself.
I have seen a forum discussion about Using alternative path for views here. But I am little confused about this.The discussed solution was,
You'd add a location like,
View::addLocation('/path/to/your/views');
Then add namespace for theme,
View::addNamespace('theme', '/path/to/themes/views');
Then render it,
return View::make('theme::view.name');
What will be the value for /path/to/ ?
Can I use the same project in different operating system without changing the path?
Yes, we can do this using the following,
Put the following in app/start/global.php
View::addLocation(app('path').'/themes/default');
View::addNamespace('theme', app('path').'/themes/default');
Then call view like the default way,
return View::make('page');
This will render page.php or page.blade.php file from project_directory/app/themes/defualt folder.
I've developed a theme package for laravel 5 with features like:
Views & Asset seperation in theme folders
Theme inheritence: Extend any theme and create Theme hierarcies
Try it here: igaster/laravel-theme
\View::addLocation($directory); works fine but the new right way to do it is using loadViewsFrom($path, $namespace) (available on any service provider).
How is it possible to set up a shared view script path for partials to create global partials within the Zend Framework?
We know that you can call partials between modules
e.g - echo $this->partial('partial_title','module_name');
but we need to set up a partial folder in the root ( i.e below modules) so that it can be accessble by all views.
It has been suggested to set up a shared view script path, how is this done?
Zend_View has a method called addScriptPath, so in a Zend_Controller_Action subclass you could do something like:
$this->view->addScriptPath("/path/to/your/view/scripts/");
Now when you call render or partial or partialLoop, that path will be included in the paths.
I have got a solution. We can do this by specifying the location of the view:
Calling partial as above form Module/Controller page
Method 1:
$this->view->addScriptPath("/ModuleConatinerDirectory/ModuleName/view/scripts/");
Then load using:
$message = $this->view->partial('templates/default.phtml','contact',array('var'=> 'var');
For the second option, please read the following:
http://framework.zend.com/issues/browse/ZF-6201
Now my doubt is, whether it is possible on setting it directly on Bootstrap file for all my Modules ? If so, how can I set this for two modules Module1 and Module2
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper( 'viewRenderer' );
$viewRenderer->setViewBasePathSpec( '/some/absolute/path/to/templates/:module/' );