Laravel: call static function inside blade template - php

I found very strange situation. I have a collection with some results and I wanna grab for each of that results the saved in cache information. For that I have a Cache class, which has one static function get(). Unfortunately I am not receiving anything when I call it in the foreach loop of my Blade template.
#foreach($prognoses as $sport_prognose)
<?php
$pr = Cache::get(Config::get('variables.cache.prediction'), ['id' => $sport_prognose['id']]);
print_r($pr);
die();
?>
#endforeach
If I call the same function inside the Controller is display me the needed information, but not as in the example above.
Why is that ?

You can use cache() and config() and other global helpers instead of facades to avoid this kind of problem.

Inside the blade template, you can write something like this:
{{ $pc::getProducts($ship->products) }}
Notice the use of variables. Obviously getProducts is a static method inside the controller, and $ship->products is a variable coming from an array. Let's make it simple: suppose $ship->products is 1, and getProducts is this:
static function getProducts($id) { echo "id is $id; }
If you ran this script, you'd get an error because the template lacks the value of $pc. How do you get around this? You need to pass the value of $this to the template:
return View::make('shipping.index')->with(['pc' => $this, 'shipping' => $shippings);
Here shipping.index is the template, and pc is getting a value of $this, which allows $pc to get accceess to getProducts inside the blade template.

Related

Can someone explain how Laravel shares variables with view?

In Laravel controller function you can return view with array of variables you like to share with the current view. Something like this:
public function index() {
return view('index')->with(['name' => 'John doe']);
}
Then you can use the name inside the with() function as $name in your view.
Can someone explain how it been done please? I would like to do something similar by myself.
We can pass individual pieces of data to the view using the 'with' method.
When passing information in this manner, the data should be an array with key / value pairs. Inside your view, we can then access each value using its corresponding key, such as
<?php echo $key; ?>
Laravel include the view file inside a function which makes all defining variables scope within a function.
Just before including files laravel calls PHP's builtin function extract(array) which declare all the variable in the scope.
extract create variables out of array making key as variable name and value as variable value.

Passing data to views without "with()" in view composers

I love the way of passing data to views in Laravel. But I don't use the "with" methode, I prefer to pass all my data as the second argument in the view helper function:
$data = [
'name' => Auth::User() -> name
]
return view('dashboard', $data);
Now it's very easy to use my data in the view:
Hello {{ $name }}
There's no need to do
Hello {{ $data['name'] }}
But here is my problem:
I want to do the same in a view composer. But the only way I have seen to pass data to views with view composers is this:
public function compose(View $view)
{
$data = [
'name' => Auth::User() -> name
]
$view -> with('data', $data);
}
But this requires me to do
Hello {{ $data['name'] }}
in my view, which I don't want. I want to use the short syntax. So is there a way to pass it like I described above? As second argument of the view function?
Thanks
Just step through each part of your array with a foreach loop:
foreach($data as $key => $value) { $view->with($key, $value); }
In answer to your question about just calling the view function an passing values, the answer is no, you can't do it that way.
Think about what you're doing in your first example. When you call view('template', $data), you're calling a helper function defined in the Laravel core. What is that function doing? It's instantiating a view, probably by calling View::make()->with(). In other words, behind the scenes it's doing the thing you want to avoid.
Now how would that work with a view composer? I imagine it would go something like this:
In your controller, you call view('template', $somedata).
You now have a view object with $somedata included.
On the way to rendering the HTML page, Laravel calls your view composer, passing along the view object you created a moment ago.
Then you call view($newdata) (or something like that - I'm not clear on what the syntax would be) and it would attach the new data to the existing view object. But this is not something that the Laravel developers have done. That's not to say it couldn't be done, it is just not a use case that they considered.
What you can do is step through your new data in the view composer and add the individual values to the existing view, like this:
foreach ($newdata as $key => $value) {
$view->with($key, $value);
}

Laravel4 get section array in Controller/Router layer from a Blade template

I need your help.
I've just found out that the class \Illuminate\View\Environment has a protected array $sections and a method to get it getSections() but it returns an empty array.
Here's how I tried to get it:
$view = View::make('pages');
$env = $view->getEnvironment();
$env->make('pages');
print($env->getSections());
And the result is Array( )
Where did I go wrong? Any suggestion will be appreciated.
That's because when you call $env->make('pages'), the view isn't immediately processed. It's only processed when the render method on the $view object is called, which is done automatically when you return it as a response, via the __toString() method. The problem, though is that just after the page is rendered, still inside the render method, the $sections variable is cleared, using the flushSections method. So you actually never have access to it.
You could try to fool it if you call the incrementRender method before making the view, then make and render the view, get the sections and then finally decrementRender() and flushSections(), but this could bring unexpected results. Something like this:
// Fool it
$env->incrementRender();
$env->make('pages')->render();
$sections = $env->getSections();
// Clear it
$env->decrementRender();
$env->flushSections();

Clean way of passing variable to partial view

I'm looking for a clean way to pass variables to partial views. Consider the following example code:
In my controller I do:
$this->view->articles = $arrayWithArticles;
$this->render('articles.phtml');
In my articles.phtml view I do:
foreach($this->articles as $article) {
// show article
$this->render('comments.phtml');
}
In another controller I do:
$this->view->products = $arrayWithProducts;
$this->render('products.phtml');
In my products.phtml view I do:
foreach($this->products as $product) {
// show product
$this->render('comments.phtml');
}
As you can see I use the same (partial) view comments.phtml to display comments about written articles as well as products. The 'comments' I want to display are in $article->comments and $product->reviews. The partial view will need these to display them.
What would be a clean way to pass them to the partial view. I really don't want to do:
$this->comments = $article->comments;
$this->render('comments.phtml');
Because this would potentially become a pain to keep track off (i.e. setting the same view variables in both the controller as in the view).
Is there a clean solution to pass variables to partial views?
Well, I think adding a parameter to your render() method would be sufficient. Maybe something like...
$this->renderSubView($fileName, $data);
Then in renderSubView() you could do whatever it is that you need to do with the array and return the rendered partial view. This way you don't need to redeclare the variable in view, just pass the data appropriate for that specific partial when it is being rendered.

Set view variables in controller for partials in Zend Framework?

Is there any way to set variables for the partial in the controller level?
Because everytime I need variables inside a partial I always have to pass them:
<?php
echo $this->partial('travels/_steps.phtml',
array('searchHotel' => $this->searchHotel,
'actionName' => $this->actionName))
?>
I would really just like actionName to be available on all partials - for instance.
You could extend the Zend_View_Helper_Partial class to a class that keeps that variable in scope. You would need to override the cloneView() function:
public function cloneView()
{
$view = parent::cloneView();
$view->actionName = $this->view->actionName
return $view;
}
You could use $this->render() instead. With it, you wouldn't need to pass the view variables every time.
Hope that helps,
You could also just sent the current view as a parameter to the partial:
<?php
echo $this->partial('travels/_steps.phtml', array('parentView' => $this));
Then, in the partial:
<?php
$view = $this->parentView;
echo $view->searchHotel, $view->actionName;
In my humble opinion, you're doing exactly what you're supposed to do - passing just those variables you'll need in the partial.
If this causes you pain, perhaps you might consider that you're using partials unnecessarily.
Or, put another way, if you want to have some variable available in all partials then perhaps the partial is not where you should be using those variables.
Maybe have a look at Placeholders and rethink how you go about rendering your views.

Categories