I'm using CakePHP 2.2.4 and have similar layouts. For one page, however, the <head> content is the same, but essentially the whole body is different. What I have is a website with a navbar used from twitter's bootstrap. On this one page, the navbar is completely different. I know the quick fix would be to create a layout for just that page, but what if I come across another page I need to make with a different navbar? What would be the "proper" MVC way of doing this?
If every view will have a navbar of some kind, then you can just use CakePHP Elements to display the bar, you would put the element call in your one layout file and set a variable from the controller which you pass to the element to show a specific element...
echo $this->element('navbar', array(
"which_element" => "thisone"
));
In the above example, your navbar.ctp would have to contain all navbars and use a PHP Switch statement or something to work out which to display based on the $which_element...
Or better still, just call the element directly using the variable from the controller
$this->set('navbar', "thisone"); // this line is in your controller and sets the file name of your nav bar, minus the .ctp extension
echo $this->element($navbar); //this line is in your layout.ctp and renders elements/thisone.ctp, in the above example.
If some pages will have a nav bar but some will not, use View Blocks
$this->start('navbar');
echo $this->element($navbar);
$this->end();
I guess it depends how complex the differences are.
One way to go would be to have a common layout file
// in app/View/Common/layout.ctp
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Your header content -->
</head>
<body>
<div id="wrap">
<div class="navbar">
<?php echo $this->fetch('menu'); ?>
</div>
<div class="container">
<?php echo $this->fetch('content'); ?>
</div>
</div>
<div id="footer">
<?php echo $this->fetch('footer'); ?>
</div>
</body>
</html>
Have your layout file extending it
//app/View/Layouts/default.ctp
<?php
$this->extend('/Common/layout');
$this->assign('menu', $this->element('menu'));
echo $this->fetch('content');
$this->assign('footer', $this->element('footer'));
?>
Related
EDIT:
My objective:
Create a news page template with header and footer and body.
The news page needs a form for a content editor to add content to with two fields: Headline and story.
Each news page requires its own SEO meta data (keywords / description title).
These stories need to be easy to find within the CMS for future editing etc etc.
What is the best way of going about this?
What I currently have is a "Page" content-type which has all the form fields I require.
To create a new news item, I currently do:
Go to Site Browser
Right-Click [myFolder]
Click "New" --> Page
Choose my page from the select box (that was the page content-type I created earlier)
I now see my form, fill it in and save/publish and I see it, but with the issues I expressed before.
I am pretty sure I am going about this in the wrong way, but what is the right way?
-------------
I am struggling to create a very basic page in dotCMS.
Here is what I want to do:
Create a form for a content editor to be able to add content to the page (Content-Type: Page called "myForm") DONE
The form contains all the default fields (seo stuff etc that comes with the Page content-type) + two extra text fields I have created (fieldA and fieldB) DONE
Create a container and add in the velocity variable names. DONE
Surround the velocity variable names in some HTML. <div>$fieldA</div> and <div>$fieldB</div> DONE
Create a new theme with a template.vtl file DONE
So that is all set up. I now go and create a new page in a folder via Site Browser choosing my new "Page" called "myForm" from the drop down menu. I see my form and enter my data, save and publish.
Result. I dont see any of my data. Just a blank page.
So I check the docs and see what I have missed.
There is a page explaining that I need to add in some velocity into my template.vtl that looks like this:
#if($dotPageContent && $dotPageContent.fieldA)
<div class="row">
#dotedit($!dotPageContent.inode,$!dotPageContent.fieldA)
</div>
#end
#if($dotPageContent && $dotPageContent.fieldB)
<div class="row">
#dotedit($!dotPageContent.inode,$!dotPageContent.fieldB)
</div>
#end
(link to dotCMS help page)
OK, so now when I check my page again, the data is indeed being displayed. But there is a problem. The HTML that is in my container does not get parsed.
E.g. <div>$fieldA</div> and <div>$fieldB</div> does not have the <div></div> tags.
So now I'm worried this is not the way to create pages.
The reason I chose the "Page" content-type was that it comes ready to go with the "Advanced Propertied" for the page like SEO meta data (which by the way all worked fine).
Can someone point out what I may have missed or perhaps a better way of going about this?
Thanks in advance.
If you could post your container and template code somewhere and include the links here I could help you resolve the issue for sure, but I think what might be happening is that you are confusing the Page Content Type with the Container defined Content Types.
Here is a quick explanation that might help conceptual differentiation:
http://screencast.com/t/PlEXKU9glGd
What I explain in the video is that the Page Content Types are for page properties only - not content addition. Like you want a different facebook link on many of your pages, or some other special property tied to each page. To place content in a container, you use a secondary "Content" Content Type, and you add that content type to a container's code field. When a page loads, the execution happens in this order, the Page content loads, page properties and metadata are set, the page calls a template that provides the layout, the template calls containers, the containers have the code that formats the content, and then the content executes in the order that it is placed in the container by the content publisher. The Page content type is not intended to really provide any information that the front end user actually sees other than the Page Title, page url, and properties and metadata that are set "silently" in the background html of the page.
You also might find it helpful to join the dotCMS communty forum: http://dotcms.com/forum/
Hope that helps
In addition to my other post, I did do the test with what you were trying to to, in a test advanced template, and the template.vtl file does display the Page Content, as long as you actually edit your page properties and set, in this case, field A:
<!DOCTYPE html>
<html lang="en">
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
#set($dotTheme = $contents.getEmptyMap())
#set($blah1 = $dotTheme.put("path", "/application/themes/one-pager/"))
#set($dotThemeLayout = $contents.getEmptyMap())
#set($blah2 = $dotThemeLayout.put("title", "Bear Mountain"))
<head>
#if($dotPageContent && $dotPageContent.fieldA)
<div class="row">
#dotedit($!dotPageContent.inode,$!dotPageContent.fieldA)
</div>
#end
##dotParse("${dotTheme.path}html_head.vtl")
</head>
#set($utilClass = $pageTitle.toLowerCase().replace(' ', '-'))
<body data-spy="scroll" data-target=".top-nav" data-offset="100">
<div class="body-wrapper">
#dotParse("${dotTheme.path}header.vtl")
<div class="content-wrapper" id="hotel">
<div class="container">
<div class="row">
<div class="col-sm-12">
<h2>The Lodge</h2>
</div>
</div>
<div class="row">
<div class="col-md-6 col-sm-12">
<div class="wow fadeInLeft" data-wow-delay=".8s">
## Container: Default 2 (Page Content)
## This is autogenerated code that cannot be changed
#parseContainer('5eb11b21-6b13-4fb8-a823-1de20bba56c0')
</div>
</div>
<div class="col-md-6 col-sm-12">
<div class="wow fadeInRight" data-wow-delay="1.2s">
## Container: Default 3 (Page Content)
## This is autogenerated code that cannot be changed
#parseContainer('f1ba7688-453c-4c0d-a214-e5ac802b8034')
</div>
</div>
</div>
</div>
</div>
<div class="image-wrapper bg-image-1 hidden-xs" data-stellar-background-ratio="0.5"></div>
<div class="content-wrapper">
<div class="container">
<div class="row">
<div class="col-sm-12">
## Container: Default 1 (Page Content)
## This is autogenerated code that cannot be changed
#parseContainer('56bd55ea-b04b-480d-9e37-5d6f9217dcc3')
</div>
</div>
</div>
</div>
<div class="image-wrapper bg-image-2 hidden-xs" data-stellar-background-ratio="0.7"></div>
<div class="content-wrapper">
<div class="container">
<div class="row">
<div class="col-sm-12">
## Container: Default 4 (Page Content)
## This is autogenerated code that cannot be changed
#parseContainer('a6e9652b-8183-4c09-b775-26196b09a300')
</div>
</div>
</div>
</div>
</div>
#dotParse("${dotTheme.path}footer.vtl")
Powered by Dotcms - The Leading Open Source Java Content Management System
</body>
</html>
This was tested on demo.dotcms.com: U:admin#dotcms.com / P: admin
Ember automatically puts whatever you have in application.hbs inside a <div class='ember-view'>.
For example, if your application.hbs is:
<div class='wrapper'>
...
</div>
The resulting DOM in the browser will be:
<html>
<body>
<div id='ember345' class='ember-view'>
<div class='wrapper'>
...
</div>
</div>
</body>
</html>
That gives me a problem because the 3rd CSS I'm using depends on certain structure. To make it work, it has to be like this:
<html>
<body>
<div class='wrapper'>
...
</div>
</body>
</html>
So I need to tell ember **not** to wrap the content of application.hbs inside that <div id='ember345' class='ember-view'>. How to do that?
Before 1.13 you can make a view (following the naming convention), explained here: How do I customize the view element for the application.hbs template?
But now I'm using 1.13..., and there's no longer the notion of "View"..., and I don't want to use ember-legacy-view add-on (sounds like a step back to me).
Does anybody have a solution?
Thanks,
Raka
Oh... just figured out, you can still create a corresponding view in ember 1.13 (without having to use legacy-view).
I simply did (in ember-cli)
ember g view application
And edit the generated views/application.js to be like this (specify empty string as tagName):
import Ember from 'ember';
export default Ember.View.extend({
tagName: ''
});
I would like to ask a question about django base templates. How do they exactly work..What do I mean.
I have a base file that lets say has a static conten and a block content that changes in templates that extend the base file.
base.html
<html>
<head>
<script src="main.js"></script>
</head>
<body>
<div class="side-nav">
<!--static content here-->
</div>
<div class="content">
{% block "content"%} {%endblock%}
</div>
</body>
</html>
I have three templates that extend base.html, e.g t1.html, t2.html and t3.html. All of them have some dom elements that are edited by the main.js file importedn in base.html. My question is the following. Does it load all the page its time i render a template and thus main.js is run again or does it only render the "dynamic" content of the base file? Will the code of main.js run everytime I load a template that extends base.html?
You basically have to understand a basic difference:
Rendering in done on the Server Side
JavaScript works on Clent side.
So if JS is sent again to Client side than it will definitely run again
You can read more about Templates in Django here : https://docs.djangoproject.com/en/1.5/topics/templates/
Django put together all templates at first. After that completed page will be send to browser. Your javascript code run in browser with full page.
How would I insert my navigation into my html file as following. (sort of wordpress style)
home.html:
<html>
<body>
(I dont know what to put here for nav)
<div main>
</div>
</body>
<html>
nav.html
<nav>
<img scr="logo.png">
<ul>
<li>home</li>
</ul>
</nav>
And then how do I implement the template on the with plates?
Note:
I'm using flatiron,plates,director
Plates doesn't support a way to inject html into another string.
It's used to bind DATA to your markup.
The easiest solution would be using files which can be concatenated in a sequence to form the page you want.
Example:
header.html
disclaimer.html
page1.html
page2.html
page3.html
footer.html
After choosing which components you need (let's say header.html, page2.html and footer.html) you can use plates to bind your data to the page markup and send everything back to the client.
Plates does support partials, see https://github.com/flatiron/plates#partials.
And here's another method (probably from before Plates had explicit support for partials):
https://stackoverflow.com/a/10076623/263447
I desperately need help. I am trying to customize main menu (only) in Drupal 7 so that it suits my blueprintcss needs. I tried to find the answer in the documentation, but there is no straightforward example for this, which makes it a bit difficult.
Basic requirement is to have other menus (navigation etc) not affected by the main menu styling.
My page.tpl.php includes this code:
<?php if ($main_menu): ?>
<div class="span-9" id="topmenu">
<?php print theme('links__system_main_menu', array(
'links' => $main_menu,
'attributes' => array(
'id' => 'main-menu',
'class' => array('links', 'inline', 'clearfix'),
),
)); ?>
</div>
<?php endif; ?>
The output shows:
<div class="span-9" id="topmenu">
<ul id="main-menu" class="links inline clearfix">
<li class="menu-151 first">Home</li>
<li class="menu-152">Contact Us</li>
<li class="menu-153 last">About Us</li>
</ul>
</div>
Whereas the desired output should be something like this:
<div class="span-9" id="topmenu">
<div class="span-3 menu-151">Home</div>
<div class="span-3 menu-152">Contact Us</div>
<div class="span-3 menu-153 last">About Us</div>
</div>
You can override the theme function to modify the generated markup.
To achieve this :
Locate the theme function you are calling (shall be
theme_links__system_main_menu).
Copy and paste the code of this function into a custom theme function (could
be done in phptemplate or custom module)
Customise your theme function to use divs instead of ul li
See the offical Drupal documentation : Overriding themable output Section "How to change HTML the Drupal way"