Extending Zend View Helper Placeholder - php

I was reading the manual about basic placeholder usage, and it has this example:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
// ...
protected function _initSidebar()
{
$this->bootstrap('View');
$view = $this->getResource('View');
$view->placeholder('sidebar')
// "prefix" -> markup to emit once before all items in collection
->setPrefix("<div class=\"sidebar\">\n <div class=\"block\">\n")
// "separator" -> markup to emit between items in a collection
->setSeparator("</div>\n <div class=\"block\">\n")
// "postfix" -> markup to emit once after all items in a collection
->setPostfix("</div>\n</div>");
}
// ...
}
I want to accomplish almost exactly that, but I'd like to conditionally add more class values to the repeating divs, at time of rendering if possible, when all the content is in the placeholder. One thing I specifically want to do is add the class of "first" to the first element and "last" to the last element. I assume that I'll have to extend the Zend_View_Helper_Placeholder class to accomplish this.

The string set with setSeparator() is what will be used to implode elements in a container. Either set it to an empty string or just leave out the call to setSeparator() and insert the separating divs along with your other content:
<?php $this->placeholder('sidebar')->captureStart(); ?>
<?php if($userIsAdmin === TRUE) { ?>
<div class="block admin-menu">
<h4>User Administration</h4>
<ul>
<li> ... </li>
<li> ... </li>
</ul>
</div>
<?php } ?>
<div class="block other-stuff">
<h4>Non-Admin Stuff</h4>
<ul>
<li> ... </li>
<li> ... </li>
</ul>
</div>
<?php $this->placeholder('sidebar')->captureEnd() ?>

Related

How to show only one data in blade that coming from collection in Laravel?

im new at Laravel, so i have following problem:
I have db with issue table, that contains 15 names of diseases with it's description. This is my model
class Issue extends Model
{
use HasFactory;
use SoftDeletes;
protected $guarded = false;
public function gender() {
return $this->belongsTo(BodyPart::class);
}
}
And here's controller:
use App\Http\Controllers\Controller;
use App\Models\Issue;
class IndexController extends Controller
{
public function __invoke()
{
$eye_issues = Issue::all();
return view('app.issues.man.eyes.index', compact('eye_issues'));
}
}
And finally below my blade file:
<main>
<section id="schedule" class="section-with-bg">
<ul class="nav nav-tabs" role="tablist" data-aos="fade-up" data-aos-delay="100">
#foreach($eye_issues as $issue)
#if($issue->body_part_id == 2 and $issue->gender_id == 1)
<li class="nav-item">
<a class="nav-link" href="#issue-{{ $issue->id }}" role="tab"
data-bs-toggle="tab">{{ $issue->issue }}</a>
</li>
#endif
#endforeach
</ul>
<div class="tab-content row justify-content-center" data-aos="fade-up" data-aos-delay="200">
#foreach($eye_issues as $issue)
#if($issue->body_part_id == 2 and $issue->gender_id == 1)
<div role="tabpanel" class="col-lg-9 tab-pane fade show active" id="issue-{{ $issue->id }}">
<div class="row schedule-item justify-content-center">
<div class="col-md-10" style=text-align:center>
<h4>{{ $issue->description }}</h4>
Test yourself
</div>
</div>
</div>
#endif
#endforeach
</div>
</div>
</section>
</main>
So problem is, after loading the page, navigation tabs should show all disease names (as it does) and the description section must be empty and show according description of disease that selected from nav-tabs and change description if disease is changed from nav-tabs. But after loading page, in the description section, there are all disease description, even nav-tabs selected to none onload. Only after selecting all diseases from nav-tabs, page works properly.
P.S I use MySQL if case u wanted to know. i tried to use all JS and CSS hide and show functions and other methods from internet, but no one works, and i guess it depends only on laravel it self. if you dont understand what i mean, comment it, i'll leave link for demo video of the issue

Using different child views in #each directive with the same parent layout

I'm using Blade templates in Laravel 5.3. I want to render two lists - one of 'friends' and one of 'acquaintances'. The header and footer of the list is the same in both cases, but items rendered in the friends list have different formatting and fields from those rendered in the acquaintances list.
Here are two methods in my controller:
public function showFriends() {
return view('reports.friends', ['profiles' => $friends]);
}
public function showAcquaintances() {
return view('reports.acquaintances', ['profiles' => $acquaintances']);
}
Here are my blade templates:
// reports/acquaintances.blade.php
<div>Some generic header HTML</div>
<div class="container">
#each('reports.acquaintance', $profiles, 'profile')
</div>
<div>Some generic footer HTML</div>
// reports/acquaintance.blade.php
<div class="media">
<div>Some HTML formatting specific to acquaintance item</div>
{{ $profile->name }}
{{ $profile->job }}
</div>
// reports/friends.blade.php
<div>Some generic header HTML</div>
<div class="container">
#each('reports.friend', $profile, 'profile')
</div>
<div>Some generic footer HTML</div>
// reports/friend.blade.php
<div class="media">
<div>Some HTML formatting specific to friend item</div>
{{ $profile->name }}
{{ $profile->birthday }}
</div>
This doesn't seem to be a very efficient way to achieve what I want because the I've had to create two identical parent templates for my lists: friends.blade.php and acquaintances.blade.php. What I really need is the ability to have a generic parent template and then somehow to specify in my controller which template I want to use to render the list items. Is this possible? Is there another, more elegant way to implement this? I'm just starting to get my head around Blade and any pointers would be very appreciated.
You could break it into a generic persons_list and two custom items. Then use a conditional inside of the list:
public function showFriends() {
return view('reports.persons_list', ['profiles' => $friends, 'type' => 'friends']);
}
public function showAcquaintances() {
return view('reports.persons_list', ['profiles' => $acquaintances, 'type' => 'acquaintances']);
}
And blade:
// reports/persons_list.blade.php
<div>Some generic header HTML</div>
<div class="container">
#if ($type == 'friends')
#each('reports.friend', $profiles, 'profile')
#else
#each('reports.acquaintance', $profiles, 'profile')
#endif
</div>
<div>Some generic footer HTML</div>

Using Plates in PHP

I'm new to using Plates template library for PHP. I have a few questions about how to use it.
I'm looking through the docs I don't see a way to set a global layout. Is there not a way to do that?
I'm using it inside of Codeigniter. Ideally, I'd like to set the layout in the MY_Controller file for most of the site and change when needed in a controller extending MY_Controller; for instance, setting the main site layout and then for the admin panel setting the admin layout in the Auth_Controller that all of the other admin controllers extend.
Changing the layout of a particular set of templates I'd have to go through and edit all of those files. This doesn't seem ideal. Or even just passing a sidebar data for a particular layout has to be done by passing the sidebar data to each template and from each template to the layout in every file. This seems very redundant. Am I missing something?
To clarify Plates is the template system/library, http://platesphp.com/
Example of what I'm talking about.
The admin layout has a sidebar of all the admin URLs. This comes from a config file that's loaded and it has it's own template/view file.
I call the template and pass the data from the controller
// I created a library file that extends the Plates library so it can be easily loaded from the CI loader class
$data['sidebar_data'] = array(
'navigation'=>'Navigation',
'assets'=>'Assets',
'config'=>'Config'
);
$data['controller_name'] => 'Users';
$this->plates->render('admin/whatever_page', $data);
Inside of the template file/current page
<?php $this->layout('layouts/admin', ['title' => $controller_name, 'sidebar_data' => $sidebar_data])
// stuff for this page
?>
Inside of the sidebar navigation template that gets loaded in the admin layout file
<ul class="menu vertical">
<?php foreach($sidebar_data as $url => $label):?>
<li>
<?= $label ?>
</li>
<?php endforeach; ?>
</ul>
Then the layout
// there's a HEAD method in here that has the $title variable
<header class="row expanded collapse">
<div class="column">
<div class="top-bar">
<div class="top-bar-left">
<ul class="menu">
<li>
<strong>Site Name</strong>
</li>
</ul>
</div>
<div class="top-bar-right">
<ul class="menu dropdown align-right" data-dropdown-menu>
<li>
<?= $current_user ?></a>
</li>
<li class="divider"> | </li>
<li>
<?= $this->insert('auth/logout_form') ?>
</li>
</ul>
</div>
</div>
</div>
</header>
<section id="content">
<div class="left-panel">
<?= $this->insert('adminnav', ['sidebar_data' => $sidebar_data])?>
</div>
<div class="main-panel">
<?= $this->section('content')?>
</div>
</section>
<div id="adminmodal" class="reveal" data-reveal>
<button class="close-button" type="button" data-close aria-label="Close modal">
<span aria-hidden="true">×</span>
</button>
<div class="modal-body"></div>
</div>
<script type="text/javascript">$(document).foundation()</script>
<?= $this->insert('_blocks/googleanalytics')?>
Having to pass the same data from every controller method to the controller's view/template then from that to the layout/other templates is very redundant.
Convert the array to json
for example:
$this->plates->render('admin/whatever_page', ["data" => json_encode($data)]);

Laravel 4.2 Custom Pagination Button - Adding a ID with each button for AJAX call

I am using this tutorial for creating a custom pagination in Laravel 4.2.
I am getting this code-
<ul class="pagination">
<li class="disabled">
<span>«</span>
</li>
<li class="active">
<span>1</span>
</li>
<li>
2
</li>
<li>
»
</li>
</ul>
for pagination buttons.
But I need to add some AJAX and some JS call with ID's.
So, I want this kind of code for this buttons-
<ul class="pagination">
<li class="disabled" id="prev">
<span>«</span>
</li>
<li class="active" id="page[1]">
<span>1</span>
</li>
<li id="page[2]">
2
</li>
<li id="next">
<span>»</span>
</li>
</ul>
Is it possible?
Please help me.
Thanks in advance for helping.
i will give a simpler approach....
put this in anywhere in views folder. let's say you put it (and named it) as partials/pagination.blade.php
put the following code in pagination.blade.php (modify it to match your view)
#if ($paginator->getLastPage() > 1)
<ul class="pagination">
<li>Previous</li>
#for ($i = 1; $i <= $paginator->getLastPage(); $i++)
<li>{{ $i }}</li>
#endfor
<li>Next</li>
</ul>
#endif
Note: above code is a sample. change the layout to suit your need.
i prefer a tags while writing links.
while calling the paginator, use the following,
{{$paginator->links('partials.pagination')}}
No need to go through all those complicated process.
but more of a chance is, whatever you are trying to do, can be done purely with javascript.
You can extend the lluminate\Pagination\Presenter class and implement its abstract methods. For example (Put it in app/extension folder):
class CustomPresenter extends Illuminate\Pagination\Presenter {
public function getActivePageWrapper($text)
{
$url = $this->paginator->getUrl($this->paginator->getCurrentPage());
$query = parse_url($url, PHP_URL_QUERY);
parse_str($query, $params);
return '<li id="page['.$params['page'].']" class="active">'.$text.'</li>';
}
public function getDisabledTextWrapper($text)
{
return '<li class="disabled">'.$text.'</li>';
}
public function getPageLinkWrapper($url, $page, $rel = null)
{
$query = parse_url($url, PHP_URL_QUERY);
parse_str($query, $params);
$id = $params['page'];
return '<li id="page['.$id.']">'.$page.'</li>';
}
}
Add an entry in composer > autoload > classmap section like this:
//...
"app/tests/TestCase.php",
"app/extensions"
To use the Custom Presenter:
At first, create a view (custom-presenter.php) in app/views directory. Then, replace pagination option in the app/config/view.php configuration file with the new view's name, like this:
'pagination' => 'custom-presenter'
Finally, the following code would be placed in your custom presenter view:
<ul class="pagination">
<?php echo with(new CustomPresenter($paginator))->render(); ?>
</ul>
For prev and next use this JavaScript (I've used jQuery) and include this in you template:
<script>
$(function(){
$('ul.my-custom-pagination>li:first').attr('id', 'prev')
$('ul.my-custom-pagination>li:last').attr('id', 'next')
});
</script>
Above JS code will set the id=prev and id=next, otherwise there will be duplicate ids for first two lis and last two lis. At last, run composer dump from terminal. This an output of this implementation:
<ul class="pagination my-custom-pagination">
<li id="prev">«</li>
<li id="page[1]">1</li>
<li id="page[2]">2</li>
<li id="page[3]" class="active">
3</li><li class="disabled" id="next">»
</li>
</ul>
Read more on the manual.

PHP/Laravel/Bootsrap fetch data

I've got an tiny little problem. I've got a table in database called 'player_skills'. It contains columns like this (example):
player_id | skill_id | value | count
15 0 10 12
15 1 10 51
...
15 8 10 12
The player_id is actually an id of the player which is column 'id' under 'players' table.
Also there are eight skills. Value is the default value (which is irrelevant in this case). The count is the value (the value of the players skill).
Basically, what I want is to pull data into a Bootstrap tabs (example):
<div class="tabbable tabs-left">
<ul class="nav nav-tabs">
<li class="active">Section 1</li>
<li>Section 2</li>
<li>Section 3</li>
...
</ul>
<div class="tab-content">
<div class="tab-pane active" id="?skill0">
<p>I'm in Section A.</p>
</div>
<div class="tab-pane" id="?skill1">
<p>Howdy, I'm in Section B.</p>
</div>
<div class="tab-pane" id="?skill2">
<p>What up girl, this is Section C.</p>
</div>
</div>
</div>
I want to order it (from the highest to the lowest,( also I have an 'group_id' column in every player, so I don't want it to include a player which has an group_id equals to three) but for every skill). Also I have one skill that's located in the 'players' table (column called 'experience') and I've done it like this:
public function highscores()
{
$players = Player::orderBy('experience','desc')->get();
return View::make('aac.highscores')->with('players', $players);
}
It works just fine, but I need it in tabs to change for every skill.
Your need is really well covered by Laravel. First, you have to declare a many to many relationship between skills and players like this (read more : http://laravel.com/docs/eloquent#many-to-many) :
class Skill extends Eloquent {
public function players() {
return $this->belongsToMany('Player', 'player_skills', 'skill_id', 'player_id')
->withPivot('value', 'count');
}
}
Then you can get all your skills from your database with the players linked with the with method. This method is not obligatory (you can use all instead) but eager loading is a good practice here (read more : http://laravel.com/docs/eloquent#eager-loading) :
class SkillController extends BaseController {
public function index()
{
$skills = Skill::with('players')->get();
return View::make('skill.index', array('skills' => $skills));
}
}
Finally just can iterate over your skills array and over the players arrays inside each skill (read more about blade templating : http://laravel.com/docs/templates#blade-templating) :
<!-- index.blade.php -->
<div class="tabbable tabs-left">
<ul class="nav nav-tabs">
#foreach ($skills as $skill)
<li>{{ $skill->name }}</li>
#endforeach
</ul>
<div class="tab-content">
#foreach ($skills as $skill)
<div class="tab-pane active" id="?{{ $skill->id }}">
#foreach ($skills->players as $player)
<p>{{ $player->name }} : {{ $player->pivot->count }} points !</p>
#endforeach
</div>
#endforeach
</div>
</div>
If you want to order your players by skill count you can use the sortBy function like that (read more : http://laravel.com/docs/eloquent#collections) :
$orderedPlayers = $skill->players->sortBy(function($player) {
return $player->pivot->count;
});
Ask if something is not clear.

Categories