I have a quick question here. Let say I have a view file myView.ctp in cakePHP and inside my view I have some javascript (which I have there for a reason). I know I can tell cake to put my javascript code into the header section of my page by using the scriptStart() and scriptEnd() blocks like:
<?php $html->scriptStart(array('inline' => false)); ?>
// My script code goes here...
<?php $html->scriptEnd(); ?>
The array('inline' => false) is what actually tells cake to put my script in the header. Now my question is this: How do I achieve the same thing for css codes (WITHOUT putting my css codes into an external file)? This techniques seem to only work for javascript codes.
Thank you
Ran into this article when I was looking to do the same thing. Turns out there is now (as of Cake 2.1) a slightly more modern way of accomplishing this using view blocks. To wit:
$styleTag = $this->Html->tag('style', $yourCSS);
// adds your stuff to the "css" block which is injected via "fetch" in
// the head section from the view's layout
$this->append('css', $styleTag);
P.S. Would be nice if there was a HtmlHelper::tag() equivalent for style blocks instead of merely the content, just for cleanliness. Oh well.
$css = $this->Html->tag('style', '/* my css */');
$view =& ClassRegistry::getObject('view');
$view->addScript($css);
The addScript() function on the view will append your script to the $scripts_for_layout var.
Edit: Comment reiterated something important I missed so I revised the answer.
Related
How would I put this in my cakephp default.ctp file?
Im pretty novice at cakephp as ive just started using it.
<script>
$(function()
{
$('#slider-id').codaSlider();
});
</script>
Thanks, in advance.
Although your question is too vague to answer in its current state, you should have a look at the JsHelper,especially Js->buffer(). This allows you to append script in your views and output them all at once in your layout.
http://book.cakephp.org/2.0/en/core-libraries/helpers/js.html#working-with-buffered-scripts
open the app/View/Layout/default.ctp file in your favorite code editor
add the following between your <head> and </head>:
<script>
$(function()
{
$('#slider-id').codaSlider();
});
</script></li>
In CakePHP 2.x there are now things called blocks, and blocks are just chunks of output stored in memory until they are fetched for output.
There use to be a $scripts_for_layout variable that you could put your script into, but now we use the $this->fetch('scripts'); to get any JavaScript needed for the Html.
There are a few ways to inject JavaScript into the scripts block using the HtmlHelper.
To add it to the block, and this can be done in Views or Layouts. Just run this code before you fetch the block.
$this->Html->scriptBlock("$('#slider-id').codaSlider();",array('inline'=>false));
To output the scripts in your layout is easy.
$this->fetch('scripts');
The advantage of this approach is you can add JavaScript from multiple places in CakePHP, but they will be outputted in the layout at the location you desire.
I need one advice from you. I am working on a website, which uses PHP and HTML. As the biggest part of the header and footer code will be same for many pages, I am thinking of using PHP's include to avoid code duplication. But, each of those pages requires different stylesheets and JS files included. What do you think how could I let the other file know what scripts and stylesheet to import?
Our company does this:
The header reads the filename of the page calling it when it's included.
Then, it changes the extension to '.js' and outputs that if it exists. Same for CSS.
So if I have a page "register.php", it will auto-include "register.js" and "register.css" if they exist.
Here's what I do:
<?php include("includes/headContent.php"); ?>
<title>Page title goes here!</title>
<script src="script_only_used_on_this_page"></script>
<?php
require_once("includes/siteHeader.php");
?>
Site Content Goes Here!!
<?php
require_once("includes/siteFooter.php");
?>
Head Content includes any PHP I want included in every page, as well as the opening html and head tag, and any Javascript libraries and css stylesheets I want on every page. Site header closes the /head tag, and opens the body as well as printing out my site header and some other markup that goes on every page. Finally Site Footer closes out my template. Everything in between is my content area!
There are lots of different ways you can do templating, if you wanted to create a simple include and an echoHeader() and an echoFooter() function... just have the echoHeader function accept a parameter which you would pass your javascript and CSS lines to.
you can use MVC coding pattern
We have a couple of pages that require special care, jquery-ui will be called from external scripts which are going to "somehow" be added to the head section of an article.
I've attempted with jumi, however it isn't the best choice(including a js in stead of php would render it in html body), the only way I could add a javascript file was by including a php file which would echo a , but as one would imagine, this isn't elegant nor efficient in terms of performance.
Another attempt was, in stead of echoing a script, I've tried using:
<?php
$document = &JFactory::getDocument();
$document->addScript( "path/to/jsfile.js" );
?>
but it didn't work as I've expected, it seems that joomla creates the head section before this php script has the chance of being executed.
I've also gave easy header a go, however, it seems that it will include the files in all articles, which I do not wish since it will have a pretty big impact in terms of bandwidth and possible javascript issues down the road.
I'm farily new to joomla so anything that would provide some flexibility is good as an answer.
If something isn't unclear, please ask, I will try to answer the best I can.
Please note that I'm using joomla 1.7 and php5.
Jumi uses the onAfterRender event (looking at the 2.0.6 plugin) - by this time I think the <head> tag has already been written out, in-fact the whole document is already rendered.
You could try getting the document body and then searching for the closing tag </head> and inserting the script link before it. Something like this:
$myJS = "<script type='text/javascript' src='http://mysever.com/my.js'>"
$content = JResponse::getBody(); // gets the html in it's ready to send to browser form
$hdPos = strpos($content, '</head>');
$hdPos += 7; //move position to include the <head> tag
$bodyLen = strlen($content);
$content = substr($content, 0, $hdPos) . $myJS . substr($content, $hdPos, $bodyLen);
JResponse::setBody($content);
NB: This is untested and I don't use Jumi these days but it should be close.
You didn't have to go through all this!
Go to: extensions -> template manager -> templates tab (its on "styles" by default) -> go to your template and click on "edit HTML". You'll be able to add your code directly in the header, and it will be loaded in all the pages.
A bit more elegant way is to define a function that does what you want in the header - and call it from the body of the specific article you want.
Most HTML in a large website is duplicated across pages (the header, footer, navigation menus, etc.). How do you design your code so that all this duplicate HTML is not actually duplicated in your code? For example, if I want to change my navigation links from a <ul> to a <ol>, I'd like to make that change in just one file.
Here's how I've seen one particular codebase handle this problem. The code for every page looks like this:
print_top_html();
/* all the code/HTML for this particular page */
print_bottom_html();
But I feel uncomfortable with this approach (partially because opening tags aren't in the same file as their closing tags).
Is there a better way?
I mostly work with PHP sites, but I'd be interested in hearing solutions for other languages (I'm not sure if this question is language-agnostic).
I'm not a php programmer, but I know we can use a templating system called Smarty that it works with templates(views), something like asp.net mvc does with Razor.
look here http://www.smarty.net/
One solution at least in the case of PHP (and other programming languages) is templates. Instead of having two functions like you have above it would instead be a mix of HTML and PHP like this.
<html>
<head>
<title><?php print $page_title ?></title>
<?php print $styles ?>
<?php print $scripts ?>
</head>
<body>
<div id="nav">
<?php print $nav ?>
</div>
<div id="content">
<?php print $content ?>
</div>
</body>
</html>
Each variable within this template would contain HTML that was produced by another template, HTML produced by a function, or also content from a database. There are a number of PHP template engines which operate in more or less this manner.
You create a template for HTML that you would generally use over and over again. Then to use it would be something like this.
<?php
$vars['nav'] = _generate_nav();
$vars['content'] = "This is the page content."
extract($vars); // Extracts variables from an array, see php.net docs
include 'page_template.php'; // Or whatever you want to name your template
It's a pretty flexible way of doing things and one which a lot of frameworks and content management systems use.
Here's a really, really simplified version of a common method.
layout.php
<html>
<body>
<?php echo $content; ?>
</body>
</html>
Then
whatever_page.php
<?php
$content = "Hello World";
include( 'layout.php' );
Sounds like you need to use include() or require()
<?php
include("header.inc.php");
output html code for page
include("footer.inc.php");
?>
The header and footer files can hold all the common HTML for the site.
You asked for how other languages handle this, and I didn't see anything other than PHP, so I encourage you to check out Rails. Rails convention is elegant, and reflects #codeincarnate 's version in PHP.
In the MVC framework, the current view is rendered inside of a controller-specific layout file that encapsulates the current method's corresponding view. It uses a "yield" method to identify a section where view content should be inserted. A common layout file looks like this:
<html>
<head>
<% #stylesheet and js includes %>
<body>
<div id="header">Header content, menus, etc…</div>
<%= yield %>
<div id="footer">Footer content</div>
</body>
</html>
This enables the application to have a different look and feel or different navigation based on the controller. In practice, I haven't used different layout files for each controller, but instead rely on the default layout, which is named "application".
However, let's say you had a company website, with separate controllers for "information", "blog", and "admin". You could then change the navigation for each in a clean and unobtrusive manner by handling the different layout views in their respective layout files that correspond to their controllers.
You can always set a custom layout in the controller method by stating:
render :layout => 'custom_layout'
There are also great helper methods built into Rails so you don't have to rely on $global variables in PHP to ensure your CSS and Javascript paths are correct depending on your development environment (dev, staging, prod…). The most common are:
#looks in public/stylesheets and assumes it's a css file
stylesheet_link_tag "filename_without_extension"
#looks in public/javascripts and assumes it's a js file
javascript_include_tag "jquery"
Of course, each of these sections could be expounded upon in much greater detail and this is just brushing the surface. Check out the following for more detail:
http://guides.rubyonrails.org/layouts_and_rendering.html
What you suggested works OK. As long as print_top_html and print_bottom_html stay in sync (and you can use automated tests to check this), then you never need to worry about them again, leaving you to focus on the real content of the site -- the stuff in the middle.
Alternatively, you can combine print_top_html and print_bottom_html into a single call, and send it HTML code (or a callback) to place in the middle.
I use the partials system of Zend_View (very similar to Rails). A partial is essentially a small HTML template that has its own variable scope. It can be called from inside views like:
<?php echo $this->partial('my_partial.phtml', array( 'var1' => $myvar ));
The variables that get passed into the construct get bound to local variables inside the partial itself. Very handy for re-use.
You can also render a partial from inside normal code, if you're writing a helper object where you have more complex logic than you'd normally feel comfortable putting in a view.
public function helperFunction()
{
// complex logic here
$html = $this->getView()->partial('my_partial.phtml', array('var1' => $myvar ));
return $html;
}
Then in your view
<?php echo $this->myHelper()->helperFunction(); ?>
So I had a question on general organization of code for the Zend framework with regard to the layout.
My layout is basically this:
(LAYOUT.PHTML)
<div id='header'>
<?= $this->Layout()->header ?>
</div>
<div id='main'>
<?= $this->Layout()->main ?>
</div>
<div id='footer'>
<?= $this->Layout()->footer ?>
</div>
and so on and so forth. Now, in order to keep my code in my header separate from the code of my main and the code of my footer, I've created a folder for my view that holds header.phtml, main.phtml, footer.phtml. I then use this code to assign the content of header.phtml into $this->layout()->header:
(INDEX.PHTML)
$this->Layout()->header = file_get_contents('index/header.phtml');
$this->Layout()->main = file_get_contents('index/main.phtml');
$this->Layout()->footer = file_get_contents('index/footer.phtml');
That was working great, but I've hit a point where I don't want main to be static HTML anymore. I would like to be able to insert some values with PHP. So in my Controller in indexAction, I want to be able to load from my database and put values into index/main.phtml. Is there a way to do this without restructuring my site?
If not is there a way to do it so that I can have:
The ability to put code into different sections of my layout, such as Layout()->header, Layout->footer.
Separate these pieces into different files, so that they're easy to find and organize, like my index/footer.phtml, index/main.phtml etc.
Not have to put that code into quotes unnecessarily to turn it into a string to pass it to Layout()->header etc.
Thank you guys so much for your help.
-Ethan
Here is an idea:
Assign layout()->header the filename instead of the contents.
Put your code in this file
In your layout file, include() or require() the layout->header().
Since your layout headers/footers are now parsed, you can use them just like a view.
The ->header in $this->layout()->header is response segment. You can render parts of response using $this->_helper->viewRenderer->setResponseSegment('header'); in an action.
If you use
$this->layout()->header = $this->render('index/header.phtml');
It will even use the view, therefore keeping all your variables defined when rendering the header.
I would suggest using something like
<?php echo ($header = $this->layout()->header)?
$header : $this->render('headerDefault.phtml'); ?>
in your layout file - it will render a default header from the layout folder if the view script doesn't override it.
Have you tried looking at view helpers. They are a way of structuring view logic into reusable and modular code. In this case you would use a view helper to generate each of your required segments. So your example view script would look like
$this->Layout()->header = $this->header();
$this->Layout()->main = $this->main();
$this->Layout()->footer = $this->footer();
The benefit of using view helpers over include and require statements is that all of the file handling and name resolution is handled by the framework. The manual has more information on how to set up the paths and usage examples etc.
helpers are good. Another option is like the above, putting filenames in header/footer - put the template names and use $this->render($this->layout()->header)), etc etc. This is just like the include/require above, but more consistent.