Default variable value in blade Laravel - laravel

How do I set a default value to a variable in a blade partial?
So for example I have 2 variables:
softDelete
delete
witch I want by default to be true.
#if($softDelete)
<span data-toggle="tooltip" title="Publish">
<a href="#delete-{{ $id }}" class="btn btn-default btn-xs btn-flat">
<i class="fa fa-check"></i>
</a>
</span>
#endif
#if($delete)
<span data-toggle="tooltip" title="Delete">
<a href="#delete-{{ $id }}" class="btn btn-danger btn-xs btn-delete btn-flat details" data-toggle="modal" data-target="#delete_modal">
<i class="fa fa-trash"></i>
</a>
</span>
#endif
And when I send the view from controller to change the value for some of the variables, depending the case I need.
return view('platform.pages.blocks.property_table_actions',
[
'id' => $model->id,
'delete' => false
]);
I tried with a provider:
public function composeActionButtons()
{
view()->composer('platform.pages.blocks.property_table_actions', function ($view) {
$view
->with('softDelete', true)
->with('delete', true)
->with('view', true)
->with('edit', true);
});
}
but override the false values from controller.

Sometimes you may wish to echo a variable, but you aren't sure if the variable has been set. Basically, you want to do this:
{{ isset($name) ? $name : 'Default' }}
However, instead of writing a ternary statement, Blade allows you to use the following convenient short-cut:
{{ $name or 'Default' }}
from the laravel docs..
it should check with isset if the variable exists.. if not a default value is shown

I think you're approaching this task in the wrong way - personally. But if you insist, you could also just include a partial (I do this sometimes). Say in a variable, etc.
For example, something like this:
// in your view
#include('some.directory.for.partials', ['softDelete' => 'false']) // you can change this to any value
// partial can then run something like this:
#if(count($softDelete) || $softDelete)
...
#else
...
#endif
That said, I think you could probably just assign the variable in your controller when you're rendering your view. You're assigning a variable anyways. Why make things complicated with a view composer - when that logic could be in your controller? Just set 'delete' => false to true or what have you for each.

I found the best method to be this:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
class ViewComposerServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
$this->composeActionButtons();
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
//
}
/**
* Compose the Recent sidebar
*/
public function composeActionButtons()
{
view()->creator('platform.pages.blocks.property_table_actions', function ($view) {
$view
->with('softDelete', true)
->with('delete', true)
->with('view', true)
->with('edit', true);
});
}
}
and in controller:
return view('platform.pages.blocks.property_table_actions',
[
'id' => $model->id,
])
->with(['edit' =>false, 'softDelete' => false]);
View creators work almost exactly like view composers; however, they are fired immediately when the view is instantiated.
The callback that I defined with the Creator is called immediately after view() , which is before any ->with()s. This enables me to set a default value for the View and then override it when the View is called, if desired.

In Controller.php
function __construct() {
$softDelete= true;
$data = array('softDelete' => $softDelete);
view()->share($data);
}

Related

When rendering a model, how to use a blade template instead of json as default?

Is it possible to assign a blade template to a model?
Instead of doing this:
#php $contact = Contact::find(1); #endphp
#include('contact', ['contact' => $contact])
I'd like to just do:
#php $contact = Contact::find(1); #endphp
{{ $contact }}
But latter obviously just spits out the model in json.
It is possible with PHP's __toString() magic method: https://www.php.net/manual/en/language.oop5.magic.php#object.tostring
Let's make an example for default User.php model.
First, create a blade file for that model, lets create that as /resources/views/model/user.blade.php and a dummy component;
<h1>{{ $user->name }}</h1>
<p>{{ $user->created_at->diffForHumans() }}</p>
Now make this default __toString() for User model.
Add this to app/Models/User.php ;
/**
* #return string
*/
public function __toString(): string
{
return view('model.user', ['user' => $this])->render();
}
Now you can test it directly in your routes/web.php ;
Route::get('test', function () {
echo \App\Models\User::first();
});
Or try to echo it in any view as;
{!! $user !!}
You can't use {{ $user }} because you need that HTML tags, so you have to use it as {!! $user !!}

i am trying to show single data but it is showing" Trying to get property 'id' of non-object"

**after clicking "read more" i want to show a single post**
<a href="{{ URL::to('single/blog/'.$post->id) }}" class="btn btn-primary
float-right">Read More →</a>
** **the route is****
Route::get('single/blog/{id}','Web\Site\HomeController#show');
**the controller is**
public function show($id)
{
$posts = Post::findOrFail($id);
return view('site.home.singleblog',compact('posts'));
}
****the single section is****
#foreach($posts as $post)
<img class="img-responsive" src="{{asset("uploads/posts/$post->id/image/$post->image") }}" alt=""
{{ $post->name }}
{{$post->description}}
#endforeach
Your variable $posts is a single Post instance from Post::findOrFail($id) (where $id is coming from a route parameter, so a single value). You don't want to be iterating an instance of a Model. Use it in your view like a single model instance not a collection.
public function show($id)
{
view('site.home.singleblog', [
'post' => Post::findOrFail($id),
]);
}
Then in the view just remove the #foreach and #endforeach.
Try this:
{{ $post['name'] }} {{$post['description']}}
If you fetched $posts successfully, it should work. The error says $post is not an object but you are using object syntax to get value by key. So use array syntax.

Laravel send email to address from database

In my index view I show all the users and there is a button that will change the user status to active and not active. The code looks like this:
#foreach($users as $user)
<tr>
<td>{{$user->name}}</td>
<td>{{$user->surname}}</td>
<td>{{$user->email}}</td>
<td>
#if($user->is_active == 0)
{!! Form::model($user, ['method' => 'PUT', 'action'=>['AdminUserController#activateuser', $user->id]]) !!}
{!! Form::submit('Activate', ['class'=>'btn btn-primary']) !!}
{!! Form::close() !!}
#else
{!! Form::model($user, ['method' => 'PUT', 'action'=>['AdminUserController#activateuser', $user->id]]) !!}
{!! Form::submit('De-Activate', ['class'=>'btn btn-danger']) !!}
{!! Form::close() !!}
#endif
</td>
<td>{{$user->cell}}</td>
<td><button class="btn btn-primary">View Property</button></td>
<td><button class="btn btn-danger">Delete</button></td>
</tr>
#endforeach
So when I click on activate/deactivate button I trigger my activateuser function of the controller. After activation, an email is sent.
The controller looks like this:
public function activateuser(Request $request, $id){
$user = User::findOrFail($id);
if($user->is_active == 0){
$user->update([$user->is_active = 1]);
Mail::send(new activateUser());
}
else{
$user->update([$user->is_active = 0]);
}
return redirect()->back();
}
At the moment the email is going to myself and my Mailabçe looks like this:
public function build()
{
return $this->view('emails.activateuser')->to('wosleybago#gmail.com');
}
What I want instead is to send the email to the email address from the user email in the database table.
How can I do that?
So, someho I should get the $user->email
I usually want my emails have all the information in itself, so I pass User instance or whatever instance that holds data required to compose the mail.
So the Mailable has __construct(..) like this:
/**
* #var \App\User
*/
public $user; // since this is a public property its going to be available in view of mailable as $user
__construct(App\User $user) {
$this->user = $user;
// further more I set the to(), this is what you are after
$this->to($user->email, $user->name);
// and subject
$this->subject('You are activated!');
}
...
And now all you need to do in the controller is the following:
Mail::send(new activateUser($user));
As mentioned above, $user is available in the mail-view so you can use it there as well:
Hi, {{ $user->name }},
...
Note: change the activateUser to ActivateUser to follow PSR-2
Class names MUST be declared in StudlyCaps.
I also use queued mails so I set the $timeout and $tries properties right on the Mailable class.
Sending email is described in Doc: https://laravel.com/docs/5.6/mail#sending-mail
Put this code inside activateUser() function
Mail::to($user)->send(new YourMailableName());
Do not forget to import Mail and YourMailableName using "use" keyword.
Or you can use user email instead object
Mail::to($user->email)->send(new YourMailableName());
And remove ->to('wosleybago#gmail.com') from your Mailable/
You should pass User Email in when creating new activateUser instance, like so
Mail::send(new activateUser($user->email));
And then use this attribute later.
Sending Email to particular a person is quite simple. My suggestion would be as follows:
Use Queue to send mail later as it will take some time to respond from controller to view.
In existing code you can get the email of the current user and send it using a helper to() that comes with mail functionality of laravel.
You can code it like this.
if($user->is_active == 0){
$user->update([$user->is_active = 1]);
Mail::to($user->email)->send(new MailableClassInstance);
}

Why error messages doesn't Appear in Laravel views?

I want to pass custom validation messages to my view using a custom request when storing a role.
I have create a new Request called StoreRoleRequest
<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;
use Illuminate\Contracts\Validation\Validator;
class StoreRoleRequest extends Request
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'required'
];
}
protected function formatErrors(Validator $validator)
{
return $validator->errors()->all();
}
public function messages()
{
return [
'name.required' => 'the name of the Role is mandatory',
];
}
}
And then pass this custom Request to my store function in the RoleController like this:
public function store(StoreRoleRequest $request)
{
Role::create($request->all());
return redirect(route('role.index'));
}
I have a view that show the create role form where the validation seems to work properly but without showing me error even if i call them into the view like this:
{!! Former::open()->action(route('role.store')) !!}
#if (count($errors->all()))
<div class="alert alert-danger">
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</div>
#endif
{!! Former::text('name')->label('Groupe name') !!}
{!! Former::text('display_name')->label('Displayed name') !!}
{!! Former::text('description')->label('Description') !!}
{!! Former::actions( Button::primary('Save')->submit(),
Button::warning('Clear')->reset() ,
Button::danger('Close')->asLinkTo('#')->withAttributes(['data-dismiss' => 'modal'])
)!!}
{!! Former::close() !!}
Has anyone an idea why the errors doesn't appear into the view ? am I looping something inside the custom Request ?
EDIT
NB: Even in the login and the registration form the errors doesn't appear anymore.
In this case i have change my middlware that was pointed to web ['middleware' => ['web'] to this:
Route::group(['middleware' => []], function ()
{
// other routes
Route::resource('role', 'RoleController');
});
and all my errors displayed perfectly.
have you locate the root cause about this issue ?
After your question update it seems, you have newer version of Laravel application (don't confuse it with Laravel framework).
To verify this, open file app/Providers/RouteServiceProvider.php and verify method what's the content of map method. In case it launches mapWebRoutes it means that you have 5.2.27+ application which applies web group middleware automatically.
In case web middleware is applied automatically you shouldn't apply web middleware in your routes.php file because it will cause unexpected behaviour.
So you should either remove web middleware from your routes.php in case you have mapWebRoutes defined in your RouteServiceProvider class or you can modify your RouteServiceProvider class to not apply web group middleware automatically. It's up to you which solution you choose.
Just for quick reference:
RouteServiceProvider for Laravel application 5.2.24
RouteServiceProvider for Laravel application 5.2.27
Try to ask if errors exists by this way:
#if($errors->any())
// Your code
#foreach($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
// More code
#endif
Also remove the formatErrors function from the request... You don't need it...
The function messages() is responsible for returning your custom messages...
Regards.

Auth::check() worked in controller but not working in view?

I used Auth::attempt() to log user:
if (Auth::attempt(['email' => $email, 'password' => $password], true)) {
return redirect('/');
}
else{
return 'wrong email or pass';
}
Then I reload browser and call function:
if (Auth::check()) {
return 1;
}
And this return 1;
But when I call:
#if (\Illuminate\Support\Facades\Auth::check())
echo '<label style="width: 20%;color: #ff3f41;margin-left: 10px;">login</label>';
#else
echo '<label style="width: 20%;color: #ff3f41;margin-left: 10px;">nothing</label>';
#endif
This print nothing.
Any helps. Thanks.
instead of
#if (\Illuminate\Support\Facades\Auth::check()) ...
try to use
#if(Auth::Check())
This should work. you dont need to call method by its full path in Blade template
#if(Auth::Check())
<label style="width: 20%;color: #ff3f41;margin-left: 10px;">login</label>
#else
<label style="width: 20%;color: #ff3f41;margin-left: 10px;">nothing</label>
#endif
No need namespace in view Because it is defined in Facades, Check it in config/app.php
And if you use brackets and echo in blade You need to wrap them in <?php tag //code echo 'something' ?>
Laravel way!
If you need to echo something in View use {{ }} or {!! !!} The difference {{ }} escape HTML tags, {!! !!} doesn't escape HTML
goto App/Providers/AppServiceProvider.php in boot(){ } section write this line view()->share('key', 'my name is Rome');
using this you will be able to globally access "key" variable value in all off your templates
eg: see below
<?php
namespace App\Providers;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
view()->share('key', 'my name is Rome');
}
}

Resources