How to overdrive FLASH MESSAGE default of cakePHP - cakephp

For $this->Session->setFlash('this is message','flash_error'); you
only need to create flash_error.ctp in the elements folder to have a different look.
But what is with $this->Session->setFlash('this is message')? How do I modify the standard layout? I don't want to modify it with css or javascript.

Laheab answer is right. But you can override it using the AppController beforeRender function. In your app/app_controller.php write this function :
function beforeRender(){
if ($this->Session->check('Message.flash')) {
$flash = $this->Session->read('Message.flash');
if ($flash['element'] == 'default') {
$flash['element'] = 'flash_error';
$this->Session->write('Message.flash', $flash);
}
}
}
It will override the 'default' flash element with 'flash_error'. Then in app/views/elements create flash_error.ctp

The HTML for flash messages is output in the flash method of the SessionHelper class. I find the easiest way to achieve what you're trying to do is to override the core SessionHelper class. To do this
Copy lib/Cake/View/Helper/SessionHelper.php to app/View/Helper/SessionHelper.php
Cake will now use the SessionHelper class in your app as opposed to it's own. Now you can update the flash method to output the HTML you want. On line 136, you'll see this:
$out = '<div id="' . $key . 'Message" class="' . $class . '">' . $message . '</div>';
As an example, if I'm using Twitter Bootstrap, I'll update this line to be:
$out = '<div class="alert fade in"><a class="close" data-dismiss="alert" href="#">×</a>' . $message . '</div>';

According to CakePHP book entry on flash():
<?= $session->flash(); ?>
in a view file outputs:
<div id='flashMessage' class='message'>My Message</div>
So there is nothing to override but the CSS for this id in cake.generic.css.
Hope I understood the question correctly. =)

You cannot override default HTML for a flash message. What I did is: created the following function in app_controller:
protected function _f($message, $url=false) {
$this->Session->setFlash($message,'message');
if($url) $this->redirect($url);
}
Created my own message.ctp template in views/elements.
Then used the _f function inc all controllers like this:
$this->_f('This is a flash message','/page_to_redirect/');

Have you tried to create a default.ctp in elements folder?
That might be what you wanted?

Related

Create links to tagged list from an array of tags

I just followed a tag tutorial (https://book.cakephp.org/3.0/en/tutorials-and-examples/cms/tags-and-users.html) on the Red Velvet Cookbook. I was successful in adding tagging to my website. Though I feel it needs a couple more things. The comma separated list of tags is just that, a list. I would prefer a list of links. The links would obviously link to a list of posts that are tagged with the same tag. This list already exists thanks to the tutorial. The url looks like http://localhost:8765/story/tagged/cats/
I have fiddled with the html helper to try and create links but I am unsure how to do this with an array. Any leads or help would be greatly appreciated.
This is the line in my template that shows the list of tags
<p><b>Tags:</b> <?= h($story->tag_string) ?></p>
This is the function that gets the tag_string
class Story extends Entity
{
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* #var array
*/
protected $_accessible = [
'*' => false,
'tag_string' => true
];
protected function _getTagString()
{
if (isset($this->_properties['tag_string'])) {
return $this->_properties['tag_string'];
}
if (empty($this->tags)) {
return '';
}
$tags = new Collection($this->tags);
$str = $tags->reduce(function ($string, $tag) {
return $string . $tag->name . ', ';
}, '');
return trim($str, ', ');
}
}
In your $story entity you have tags property, which you already used in computed field tag_string. To get separated tags, you need to iterate over it in a template, eg:
<ul>
<?php foreach($story->tags as $tag): ?>
<li><?= $tag->title ?></li>
<?php endforeach; ?>
</ul>
Assuming you have a method in your StoriesController named tagged, which accepts one parameter: tag title, you can construct link using HtmlHelper for each tag:
<ul>
<?php foreach($story->tags as $tag): ?>
<li>
<?= $this->Html->link($tag->title, [
"controller" => "Stories",
"action" => "tagged",
$tag->title
], [
"class" => "your-tag-link-class" //second array is for properties, in case you would like to add eg class for these links to style them using css.
]) ?>
</li>
<?php endforeach; ?>
</ul>

dynamically returning views by a foreach loop

I have a foreach loop that runs by my database:
<div id="nav" >
#foreach(\App\Categories::whereNull('parent_id')->get() as $category)
<a id="link1" href="{{ route('showCategory' , $category->id) }}" ><div class="link">{{ $category->name }}</div></a>
#endforeach
</div>
I want foreach link that adds by that it knows his path to the blades dynamically.
What should I do here?
My web.php:
Route::get('/category/{category}', 'PagesController#showCategory')->name('showCategory');
My controller:
public function showCategory(Categories $category) {
}
I'm guessing that you want to create a link for each category which goes to a page that displays more information about the selected category.
Your blade file in which you create the links for all the categories seems fine to me, but I'd recommend changing your route file to this:
Route::get('/category/{id}', 'PagesController#showCategory')->name('showCategory');
Then for your showCategory function, you would need something like this:
public function showCategory($id) {
$category = Categories::find($id);
// i used categories.show here, change it to whatever view you use
return view('categories.show')->with('category', $category);
}
Then in your categories.show view, you can access the properties of the category like so:
$category->id; // or whatever you want to display
As per OP's request: the first 5 categories in the database that lead to their pages:
In your controller:
public function myFunction()
{
$categories = Categories::all()->take(5)->get();
return view('your.view')->with('categories', $categories);
}
In your blade view (assuming that the view for the category is at: /category/id):
#foreach($categories as $category)
{{$category->name}}
#endforeach

Removing 'src' attribute from output of $html->image() in CakePHP

I am using CakePHP 1.2. I am trying to use jQuery Lazy (http://jquery.eisbehr.de/lazy/example_basic-usage) from CakePHP. Reading the documentation at https://book.cakephp.org/1.2/en/The-Manual/Core-Helpers/HTML.html#image, it shows how
<?php echo $html->image('cake_logo.png', array('alt' => 'CakePHP'))?>
produces the following output:
<img src="/img/cake_logo.png" alt="CakePHP" />
I need to produce this output:
<img class="lazy" data-src="/img/cake_logo.png" />
How can I do that using $html->image() in CakePHP 1.2? The problem is that in the syntax image(string $path, array $htmlAttributes = array()), the first parameter is mandatory and in the output it produces the src=... attribute of img. I need to have an output with <img... /> that does not contain the src=... attribute. How could I achieve that using $html->image() in CakePHP?
Via the built-in HTML helper it's not possible without modifying the tag template. So if you need lazy loading on all images, then you could for example change the image tag template to something like:
<img class="lazy" data-src="%s" %s/>
However this would clash with using the class attribute. So alternatively you could extend the HTML helper and implement a custom image() method (or an additional method). Here's a quick & dirty example, which should be pretty self-explantory:
function image($path, $options = array())
{
$defaults = array(
'class' => null
);
$options += $defaults;
$options['class'] = 'lazy ' . $options['class'];
$originalTemplate = $this->tags['image'];
$this->tags['image'] = '<img data-src="%s" %s/>';
$imageHtml = parent::image($path, $options);
$this->tags['image'] = $originalTemplate;
return $imageHtml;
}
See also
Cookbook > Core Helpers > HTML > Changing the tags output by HtmlHelper
Cookbook > Developing With CakePHP > Helpers > Creating Helpers

Echoing html link mailto

I'm using Ckeditor on a field of a CakePHP form.
No problems saving the information on the database the problem is when I echo the content of that field. If the field as a link of the type mailto I get a denied: in the beginning of the href attribute.
For example:
name#domain.com
To echo the field value I'm using:
echo $data['Ent']['text'];
you can use :
<?php echo $this->Html->link($v['mail'],'mailto:'.$v['mail'],array('target' => '_blank'));?>
Dont know why Ckediter is doing that but you can remove it using jquery
<a id="link1" href="denied:mailto:name#domain.com">name#domain.com</a>
<script>
$(document).ready(function (){
$("#link1").attr("href","mailto:name#domain.com");
});
</script>

Calling function in view of cakephp

I have one team array and want that team name every where to show team name.It is possible to built a global function which can return team name and I call that function from my view means ctp file.
please try this for west:
<?php
// controller name like app,users
// action name like getdata should be in controller
// and you can send parameter also
$output = $this->requestAction('controllerName/actionName/'.$parameter);
?>
There are multiple approaches to this. What I cannot tell from your description is exactly what you are looking for. If it is simply to create an array of items that is accessible in your views, I would put it in app_controller.php
var $teams = array('team1', 'team2', 'team3');
beforeFilter() {
$this->set('teams', $this->teams);
}
Then in your view, you can access the array by the variable: $teams
If you only want to call teams on certain views, it may not be a good idea to set this variable for EVERYTHING. You can get around it by setting up a function in app controller.
function get_teams_array() {
$teams = array('team1', 'team2', 'team3');
return $teams;
}
Then put together an element that will call this function:
views/elements/team.ctp
<?php
$teams = $this->requestAction(
array('controller' => 'app', 'action' => 'teams'),
array('return')
);
/** process team array here as if it were in the view **/
?>
Then you can just call the element from your view:
<?php echo $this->element('team'); ?>
You can add in your /app/config/bootstrap.php file something like:
Configure::write('teams', array('team1', 'team2'));
Then everywhere you can get that array with:
$teams = Configure::read('teams');
and use it.
In CakePHP 3.*, you can use Helpers.
https://book.cakephp.org/3.0/en/views/helpers.html#creating-helpers
1 - Create your helper inside src/View/Helper:
/* src/View/Helper/TeamHelper.php */
namespace App\View\Helper;
use Cake\View\Helper;
class TeamHelper extends Helper
{
public function getName($id)
{
// Logic to return the name of them based on $id
}
}
2 - Once you’ve created your helper, you can load it in your views.
Add the call $this->loadHelper('Team'); inside /src/View/AppView.php:
/* src/View/AppView.php */
class AppView extends View
{
public function initialize()
{
parent::initialize();
$this->loadHelper('Team');
}
}
3 - Once your helper has been loaded, you can use it in your views:
<?= $this->Team->getName($id) ?>

Resources