Is there a way to configure CakePHP for it to work well with Twitter Bootstrap?
I realize this question has already been asked here, but the answer wasn't really complete.
There are also quite a few tutorials out there, but they are all either outdated or just not working, example: Build a PHP application using CakePHP and (twitter) Bootstrap, Part 1.
Thanks!
Assuming that the css file is included in your layout in your view for forms you can use the follwoing:
<?php echo $this->Form->create('User', array(
'inputDefaults' => array(
'div' => 'control-group',
'label' => array('class' => 'control-label'),
'between' => '<div class="controls">',
'after' => '</div>',
'class' => 'span3',
'error' => array('attributes' => array('wrap' => 'div', 'class' => 'alert alert-error'))
) ));
echo $this->Form->input('password',array(
'after' => '<span class = \'help-inline\'>Minimum of 5 characters.</span></div>'));
?>
I found this method to work perfectly with cake2.0 and bootstrap 2.0
This will produce the following
<div class="control-group required error">
<label for="UserPassword">Password</label>
<div class="controls">
<input name="data[User][password]" class="span3 form-error" type="password" value="" id="UserPassword">
<span class="help-inline">Minimum of 5 characters.</span></div>
<div class="alert alert-error">You must provide a password.</div>
</div>
The html above is after the form has been submitted and an error has been returned.
IMHO, the best Twitter Bootstrap plugin (+ recommended by one of the Cake devs in the bug tracker) is:
https://github.com/slywalker/TwitterBootstrap
What's handy about this one is that it uses Cake 2's aliasing for the helpers so you don't need to change any of your view code.
So the regular $this->Html-> and $this->Form-> in all your old code will output Bootstrap markup. Awesome.
Here's a newer one:
http://drawrdesign.com/twitter-bootstrap-for-cakephp
Github page:
https://github.com/Rhym/cakeStrap
Checkout our Twitter Bootstrap Helper
https://github.com/loadsys/twitter-bootstrap-helper
Lets make it simple and update this. The fastest and easiest way to do this is as follows and is current as of v:2.9
Download the 3 folders for the bootstrap here:
http://twitter.github.io/bootstrap/getting-started.html
Then unpack them and move:
css/bootstrap.css
css/bootstrap.min.css
css/bootstrap-responsive.css
css/bootstrap-responsive.min.css
-TO-
app/webroot/css/
-THEN MOVE-
js/bootstrap.js
js/bootstrap.min.js
-TO-
app/webroot/js/
-THEN MOVE-
img/glyphicons-halflings-white.png
img/glyphicons-halflings.png
-TO-
app/webroot/img/
***IT'S VERY IMPORTANT THAT YOU DONT PUT THESE FILES IN THE ROOT OF YOUR SITE(I will explain later...)!!!
Then, in the code editor of your choice(I prefer Netbeans) open the file:
app/View/Layouts/default.ctp
It should look like:
<?php
/**
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* #copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* #link http://cakephp.org CakePHP(tm) Project
* #package app.View.Layouts
* #since CakePHP(tm) v 0.10.0.1076
* #license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
$cakeDescription = __d('cake_dev', 'CakePHP: the rapid development php framework');
?>
<!DOCTYPE html>
<html>
<head>
<?php echo $this->Html->charset(); ?>
<title>
<?php echo $cakeDescription ?>:
<?php echo $title_for_layout; ?>
</title>
<?php
echo $this->Html->meta('icon');
echo $this->Html->css('cake.generic');
echo $this->fetch('meta');
echo $this->fetch('css');
echo $this->fetch('script');
?>
</head>
<body>
<div id="container">
<div id="header">
<h1><?php echo $this->Html->link($cakeDescription, 'http://cakephp.org'); ?></h1>
</div>
<div id="content">
<?php echo $this->Session->flash(); ?>
<?php echo $this->fetch('content'); ?>
</div>
<div id="footer">
<?php echo $this->Html->link(
$this->Html->image('cake.power.gif', array('alt' => $cakeDescription, 'border' => '0')),
'http://www.cakephp.org/',
array('target' => '_blank', 'escape' => false)
);
?>
</div>
</div>
<?php echo $this->element('sql_dump'); ?>
</body>
</html>
Find this:
echo $this->Html->css('cake.generic');
Below it add this:
echo $this->Html->css('cake.generic');
echo $this->Html->css('bootstrap');
echo $this->Html->css('bootstrap.min');
echo $this->Html->css('bootstrap-responsive');
echo $this->Html->css('bootstrap-responsive.min');
Find this:
echo $this->fetch('script');
Below it add this:
echo $this->Html->script('bootstrap');
echo $this->Html->script('bootstrap.min');
***Remember earlier when I said I was going to explain why the files MUST be in the webroot directory(For anyone new to MVC)? The above code is how Cake includes its scripts and css.
The Method it uses for this looks in app/webroot/js for javascript files; and respectively in app/webroot/css for css files. This makes iNcluding js and css files a synch. If you want the js/css files included GLOBALLY include them default.ctp.
*If you only need a script for use with one view/page then use this same code on the view file you need it on.
It might sound a little complicated but it should only take 3 min to include the twitter bootstrap globally in this way.
Hope this helps!
Bootstrap doesn't use any server-side code.
Except for LESS CSS, which you can either compile down to regular CSS on the server, or as the LESS CSS site shows you can have the browser compile it using less.js like this:
<link rel="stylesheet/less" type="text/css" href="LESS_FILE_HERE.less">
<script src="less.js" type="text/javascript"></script>
Just link all the .less files using stylesheet/less and the less.js file and it should work.
Other than that Bootstrap is just HTML and Javascript. just put all the javascript in the webroot/js folder and make a layout for the main HTML and get going.
I have done this. What you will need to do is the following:
create the layout App/Views/Layouts/default.ctp
copy the bootstrap html into that
update the layout with the cake specific code
It works like a charm
Have a look at the CakePHP plugin AssetCompress which handles LESS compiling for you if you have NodeJS and LESS installed on your server.
Then you just need to include the CSS files in your layout and style the forms using the Bootstrap classes.
Maybe you like this plugin: https://github.com/BradCrumb/lesscompiler.
It's a CakePHP Component that automatically compiles less files to css files. I just tested it with Bootstrap and it works find
I agree with #Costa, Slywalker's plugin is the best solution.
Here's the new version of his plugin, working with both Twitter Bootstrap 2.x and 3.x branches.
This plugin is far better as it extends nicely Html Helper, Form Helper and alerts.
Fork BoostCake Plugin for CakePHP 2.x at Github
I had the same problem using slywalker / cakephp-plugin-boost_cake. I opened a ticket and he had it fixed in a few hours. He updated to 1,03 and told me to use it like this:
<?php echo $this->Form->input('email', array( 'label' => array( 'text' => __('Email:'), ), 'beforeInput' => '<div class="input-append">', 'afterInput' => '<span class="add-on"><i class="icon-envelope"></i></span></div>' )); ?>
I hope it helps some one else, too.
Related
i have looked at the documentatioin of cakephp 2.5.4 about custom flash messages and some other tutorials on how to make this but its not working
i have error.ctp and success.ctp under elements folder
error.ctp
<div id="error-flash">
<?php echo h($message); ?>
</div>
success.ctp
<div id="success-flash">
<?php echo h($message); ?>
</div>
and in controller i call them like this
$this->Session->setFlash(__(' file successfully uploaded.','success',array('class'=>"flash_msg_ok")));
$this->Session->setFlash(__('Upload Failed','error',
array("class" => "flash_msg_error")));
my chrome developer tools still shows the default flash generated.
its not rendering the element or applying the specified classes
i've also tried this
$this->Session->setFlash('success','default',array('class'=> 'success'))
still nothing.
of note is that am using custom layout and css for the page.
what am i missing here?
There are a couple of issues..
First, you've accidentally put the other function variables inside the translation string. You can fix the call as follows (note closing bracket moved to end of message string):
$this->Session->setFlash(__(' file successfully uploaded.'),'success',array('class'=>"flash_msg_ok"));
$this->Session->setFlash(__('Upload Failed'),'error',
array("class" => "flash_msg_error"));
Second, you'll need to add the class to your custom error element file (the cakephp docs neglect to mention this!). For example:
<div id="error-flash" class="<?php echo $class; ?>">
<?php echo h($message); ?>
</div>
Hope that helps!
I had this piece of code in my services.ctp file which was working fine before in CakePHP 2.3.10.
href="<?php echo $this->webroot . 'intro/services/1'; ?>
I just copied this file into CakePHP 3.0.0 and it's no longer working and throwing the following error message
Error: C:\apache2\htdocs\myprojxxxx\webroot\Helper could not be found.
what's different with this $this->webroot in CakePHP 3.0 ?
Please help!
You need to use this:
href="<?php echo $this->request->webroot . 'intro/services/1'; ?>
This will work with cakephp 3.0
In cakephp 4.x you need to use this:
href="<?php echo $this->Url->webroot.'/intro/services/1'; ?>
This is not how you should have done it in the first place, as such "hard-coded" URLs are very inflexible in comparison to URL arrays, where it's the connected routes that define the generated URLs at a single point in your application, allowing you to easily make changes wihout having to apply modifications throughout the whole application.
That being said, the magic $webroot property is gone (check the migration guide), its value can be retrieved directly via the View::$request object.
You should however use Router::url(), the UrlHelper, or one of the HtmlHelper methods instead:
\Cake\Routing\Router::url(['controller' => 'Intro', 'action' => 'services', 1])
$this->Url->build(['controller' => 'Intro', 'action' => 'services', 1])
$this->Html->link('Title', ['controller' => 'Intro', 'action' => 'services', 1])
See also
Cookbook > Routing > Generating URLs
Cookbook > Views > Helpers > Url
Cookbook > Views > Helpers > Html > Creating Links
Form me in cake 3.9 that work:
<img src="<?php echo $this->Url->build('/img/logo_app.png'); ?>" style="width:250px" />
I've recently upgraded my 1.3 cake app to 2.0, and I'm trying to redo my app_error code.
With Cake 1.3, it was simply a case of creating an app_error.php file, putting it in my app root, and overriding the built-in error404() and missingController() actions.
Here is my old 1.3 /app/app_error.php file: http://pastebin.com/beWZD9PJ
It had some code that kicked in when someone arrived at the site with a predefined 'alias' URL, and then it redirected them accordingly.
I just need this to work in Cake2.0, and I see the manual is telling me its all changed, but I can't find a specific case like this. Can anyone help me out, so the error404 code kicks in?
Many thanks
4xx and 5xx errors in CakePHP 2.0 ar now exceptions, thus you need to customize your Exception renderer or handler. Read from this section to the bottom http://book.cakephp.org/2.0/en/development/exceptions.html#exception-renderer
You can throw a 404 exception with the following code in your controller in Cake 2:
throw new NotFoundException(__('Your error text here'));
Then, you just need to have APP/View/Errors/error400.ctp present with something relevant to display. Cake includes this by default:
<h2><?php echo $name; ?></h2>
<p class="error">
<strong><?php echo __d('cake', 'Error'); ?>: </strong>
<?php printf(
__d('cake', 'The requested address %s was not found on this server.'),
"<strong>'{$url}'</strong>"
); ?>
</p>
<?php
if (Configure::read('debug') > 0 ):
echo $this->element('exception_stack_trace');
endif;
?>
It's simple.
With cakephp 2, you have to add this function in your AppController:
public function appError($error) {
$this->redirect('/');
}
Here, for example we redirect all errors to index page.
My scenario is such:
In my /views/layout/default.ctp
<head>
<!-- other stuff -->
<?php echo $scripts_for_layout; ?>
</head>
<body>
<!-- more stuff -->
<?php echo $content_for_layout; ?>
In my /views/pages/home.ctp
<?php $this->Html->meta('keywords', 'my, keywords', array(), false); ?>
However, my problem is that even with $scripts_for_layout in my default.ctp, and with boolean inline = false, I still can't see the meta tag in my head, instead I just see them inline.
I am considering the scenario that it $scripts_for_layout is echoed before I make that HTML helper call, but surely there must be an elegant way to do this?
Also note that the HTML helper call is the first line to my views/pages/home.ctp
Edit - Aha I found my mistake. Here's to anybody else who's having the same problem. With CakePHP 1.3, the syntax for the HTML helper changes slightly (and there is no backwards-compatibility for the syntax).
Apparently there's a syntactical flaw in what I wrote in my view.
This is the correct way to say boolean inline = false in version 1.3:
$this->Html->meta("keywords", "keywords, are, sweet", array("inline" => false));
Aha I found my mistake. Apparently there's a syntactical flaw in what I wrote in my view.
This is the correct way to say boolean inline = false in version 1.3:
$this->Html->meta("keywords", "keywords, are, sweet", array("inline" => false));
For CakePHP version 3.x use this in your view:
<?php $this->Html->meta('keywords', 'keywords, are, sweet', ['block' => true]); ?>
Then in your layout's header use:
<?= $this->fetch('meta') ?>
The output will be:
<meta name="keywords" content="keywords, are, sweet"/>
Background: I'm new to CakePHP. I have a small test site (mostly composted of static views and a contact form at the moment) to play with while I learn. Everything worked fine on localhost (Apache on Ubuntu) so I deployed it to a shared hosting account (provided by Lunarpages). I moved the /cake folder out of the normal directory structure (so I could use it for multiple apps) and I reconfigured my webroot's index.php paths accordingly.
Problems:
setFlash messages do not get displayed. Even making a simple view that does nothing other than $this->Session->setFlash('message');. I don't get any error message, the flash just doesn't get displayed
Redirects don't work. For instance, after the contact form is completed I want to $this->redirect( array( 'action' => 'success' ), null, true); but the server throws an error:
Warning (2): Cannot modify header information - headers already sent by (output started at /routetoapp/config/routes.php:40) [CORE/cake/libs/controller/controller.php, line 742]
Everything else seems to work just as it did on localhost - URL rewriting, component loading, model validation. I don't know if my problems are related or separate issues
Troubleshooting so far:
I've tried both 'cake' and 'php' for Configure::write('Session.save', 'val'); but neither made a difference.
My app/tmp folder is writeable.
My layout template has the correct code for displaying flash messages. (The exact same M, V, C, and Layout objects display the expected flash on localhost)
I assume I'm missing something simple, but I'm new to this framework so I'm not sure where else to look.
See Matt Huggins answer for your flash problem. That's correct
As for your redirect issue,
you might have an extra space or something in your routes.php file. Make sure there are no spaces before the starting <?php tag and remove the closing ?>
$this->Session->setFlash(...) is used to SET the flash message from within the controller. When you're in the view, you should be rendering the flash message like this:
<?php $session->flash(); ?>
You can also make your flash message more elaborate if you need with something like this:
<?php if ($session->check('Message.flash')): ?>
<div class="message">
<?php $session->flash(); ?>
</div>
<?php endif; ?>
That was right but there also have echo add before $session->flash();
so, it should be like:
<?php if ($session->check('Message.flash')): ?>
<div class="message">
<?php echo $session->flash(); ?>
</div> <?php endif; ?>
this worked for me!