CakePHP, layout with common header and footer - cakephp

I have a fresh CakePHP 1.3 install and it currently has one layout. I am about to add a few more but I don't want to have to keep coping and pasting the Header and footer in to each layout.
At first I thought that I could do this with an Elements, but it does not seem to render the Configure::read('var_name'); chunks while in an element.
My other thought was to create a common layout and use lots of variables to add and remove sections from the screen depending on what type of user they are... but this would be troublesome to say the lest.
My question is:
Is a way to include a header/footer section in to a layout while getting the Configure::read() function to output text?

I still think that elements are the right way to go for this (shared view snippets, FTW). I have to admit that I'm a little surprised that elements can't read from the Configure class, but I'll concede that I haven't tried it. If that really won't work, then try passing the values directly to the element:
<?php echo $this->element( 'partial_name', array( 'var_name', Configure::read( 'var_name' ); ?>
In the element, you should then be able to access the variable simply as $var_name. For more on passing variables to elements, take a look at the [Passing Variables into an Element](Passing Variables into an Element) section of the element documentation.
Hope that helps.

Create element with new header suppose new_header.ctp. Then put element('new_header')?> in your preferred position layout

Related

Render individual page fields once only in Drupal 7 page.tpl.php

So I gather I can render a specific element of the $page['content'] array like so...
<?php print render(field_view_field('node', $node, 'field_image')); ?>
Where out of the box this will render the element as expected with standard defaults. Ok, so how can I make sure that hand plucked element no longer renders in the <?php print render($page['content']) ?> call later?
Why do I want something dumb like this? Because every page WILL have a header image with a few css tricks for overlays, design and such. But not every page will have attachments, links, and so on... you know, things that are additional fields in the page. So I can't manually print out each field since I don't know how many or what else there is. All I know for sure is the field_image I'm printing above is wrapped in a ton of markup for styling and must be done this way. Same for a few other fields.
Basically I'm looking for a way to unset the field immediately after use.
Does anyone know how to achieve this? I'd rather not make a view or a custom block that displays for specific pages. I eventually have to hand this over to a client who will not be able to wrap their heads around a single page being administered over many places in the CMS.
You can in fact control the display of individual fields for content types in Drupal without having to resort to the function you've used.
Since you know in advance which field(s) you want to suppress, you can turn off its display in the content type settings.
In Drupal 7, see:
Admin >> Structure >> Content types >> your content type >> Manage display
Under "Format" select < Hidden > for the field that you want to omit.
This will prevent the field contents from being displayed within the usual node contents, but field_view_field will naturally still work.
You can also fine-tune your field formats based on different view modes, e.g. choose to display the field within teasers but not in full content.
Looks like this will work:
<?php
print render(field_view_field('node', $node, 'field_image'));
MYTHEME_remove_item($page['content'], 'field_image');
?>
and in template.php file I made this function:
function MYTHEME_remove_item(&$content, $field)
{
foreach($content['system_main']['nodes'] AS $key => $val){
unset($content['system_main']['nodes'][$key][$field]);
}
}
This is ridiculous, in my opinion. I would think a system as robust as drupal would have a solution for something like this. If anyone knows the proper way to do this I will gladly mark them as correct. In the meantime, for others facing similar situations, this worked for me.

How to add a custom field into template.php using Zen sub theme

First time poster here, I'm a designer not skilled at all with php and I have a small issue I don't seem to be able to solve. I'm making a site in drupal 7 using a sub theme on zen.
Btw this is a great CMS, even though people say it's really more a developers CMS. I have no trouble to do what I need using views, rules, display suite etc. So a big thank you for all the developers out there making this such a good CMS. But for this apparently simple problem... no module will help me (I think) and I'm kinda stuck.
So here it is: I'd like to add a subtitle next to the title in all my pages.
So what I did was to add a custom field into the content type basic page (machine name: field_sub_title) which is a simple text field.
I uncommented the following line in my template.php
function mytheme_preprocess_page(&$variables, $hook) {
$variables['sub_title'] = t('field_sub_title');
}
Now my question is how do I load the content of my custom field into that variable?
I know i need to change the second part, but I don't have a clue as into what I need to change this.
Displaying the variable into the the page.tpl.php is something I know about so I only need help with the first part.
{EDIT}
Ok I found how to do this :)
I was looking for a solution in the wrong place. I don't need to change any thing in the template.php file.
Just needed to add this bit of code into my page.tpl.php:
<?php
print $node->field_sub_title['und'][0]['value'];
?>
So I'm posting this here for other Drupal newbies struggling with this....
Your solution may work for now, but there may be a more Drupal-y way to handle a problem like this. If you haven't noticed any problems yet, you may find one or more of the following issues down the road:
Someone who doesn't know php or Drupal theming may need to change the way this works.
If you're like me, you may forget where exactly in code this was implemented.
You may see superfluous markup and/or errors on nodes (content) that do not have this sub-title field (ie. event content not having a sub-title field while basic pages and news articles do).
When you add a field to a content type, it will automatically appear anytime content in that content type is displayed. You should be able to add the sub-title field for your page, event or whatever else you need and have it automatically appear in the markup.
You can 'manage display' of a content type to drag and drop the order for fields to appear. You could take it a step further by using a module like Display Suite to add formatting or layout per-content type.
If you feel like this isn't good enough and the markup for the subtitle must be at the same level as the page title (which is rare), at least add an if statement to make your code check to see if the variable is present before trying to print it. I'd also add a new variable and comments for code readability.
<?php
$subtitle = $node->field_sub_title['und'][0]['value'];
if($subtitle){
print $subtitle;
}
?>
Consider using field_get_items or field_view_value, or at least use the LANGUAGE_NONE constant instead of 'und'
See https://api.drupal.org/api/drupal/modules%21field%21field.module/function/field_get_items/7 and https://api.drupal.org/api/drupal/modules!field!field.module/function/field_view_value/7
This has the added benefit of reducing the number of potential security holes you create.

Drupal: D7 rewriting values returned by views

I have a requirement to perform an indexed search across content which must include a couple of tags in the result. The tags must be a random selection. The platform is Drupal 7.12
I have created a view that manages the results of a SOLR search through the search_api. The view returns the required content and seems to work as intended. I have included a couple of Global: custom text fields as placeholders for the tag entries.
I am now looking for a solution to manage the requirement to randomise the tag values. The randomisation is not the issue, the issue is how to include the random values into the view result.
My current approach is to write a views_pre_render hook to intercept the placeholders which appear as fields ([nothing] and [nothing_1]). The test code looks like the following
function MODULE_views_pre_render( &$view )
{
$view_display = $view->display['default'];
$display_option = $view_display->display_options;
$fields = $display_option['fields'];
foreach( $view->result as $result )
{
$fields['nothing']['alter']['text'] = sprintf("test %d", rand(1,9));
}
}
I am currently not seeing any change in the placeholder when the view is rendered.
Any pointers to approach, alternate solutions etc would be gratefully received as this is consuming a lot of scarce time at the moment. Calling print_r( $view ) from within the hook dumps over 46M into a log file for a result set of 2 items.
There are two possible solutions for your task.
First approach is do everything on the template level. Define a template for the view field you want to randomize. In advanced settings of your display go to Theme: Information. Make sure that the proper theme is selected and find the template suggestions for your field. They are listed starting from most general to the most specific and you can choose whatever suits you better.
I guess the most specific template suggestion for your field would be something like this: views-view-field--[YOR VIEW NAME]--[YOUR DISPLAY NAME]--nothing.tpl.php. Create the file with that name in the theme templates directory and in this template you can render what ever you want.
By default this template has only one line:
print $output;
you can change this to:
print sprintf("test %d", rand(1,9));
or to anything else, whatsoever :)
Second approach is to go with Views PHP module. WIth this module you can add a custom PHP field in which you can do whatever you want. Even though the module hasn't been released it seems to work quite well for the most of the tasks and most certainly for such a simple task as randomizing numbers it will work out for sure.
I stumbled upon this while searching for another issue and thought I would contribute.
Instead of adding another module or modifying a template, just add a views "sort criteria" of "Global: Random".

CakePHP $this->element correct usage?

I'm trying to make a reusable component (a weekday dropdown box, simple as pie) and am following the advice in http://book.cakephp.org/view/1081/Elements.
According to that page, I should make a blah.ctp file in app/views/elements, and it will be magically accessible in my view code as $this->element('blah').
So I did it. I'm passing the form and field name to my element in the view code:
$this->element(
'weekday_input',
array('form'=>$this->Form, 'fieldname'=>'weekday')
);
Earlier I created a form using $this->Form->create, so I figured I need to pass it to the element explicitly.
And my element code, in weekday_input.ctp:
echo $form->input(
$fieldname,
array(
'options',
array('Sunday'=>'Sunday',...,'Saturday'=>'Saturday')
)
);
(Weekdays in between omitted for brevity.)
Am I using $this->element properly? Is there something more clean available?
You don't have to pass the Form object. Form, Html and other helpers are available in elements (just as in view). Whether or not you want to pass fieldname depends: Do you need to change it?
An element is a bit too simple I expect. Also it is not very testable. Would focus on Helpers, which is a more advanced way of developing this. But there is another solution I would prefer even more:
For this kind of issues it might be more appropriate to extend the formhelper itself. You can see a simple example here:
http://blog.nlware.com/2012/02/07/cakephp-2-0-how-to-extend-the-formhelper/
A full example can be found for example here:
https://github.com/slywalker/cakephp-plugin-boost_cake/blob/master/View/Helper/BoostCakeFormHelper.php
As you asked for a clean solution think about creating a plugin (or check out existing plugins). That will separate the code out of your project more clean. And it will be available for re-use without much issues.
you can find all files needed for a plugin in the same project:
https://github.com/slywalker/cakephp-plugin-boost_cake
And the documentation here:
http://book.cakephp.org/2.0/en/plugins.html

How to use default.ctp in cakephp

I just finished the "15 min Blog Post tutorial" included in the documentation for cakephp. I was asked for another tutorial to change the layout for first tutorial.
However, I am fairly new to MVC programming/Cakephp and I have no real clue how to do so. Well, I know I need "default.ctp" placed in app/views/layouts/ and I presume I need to include
to include my data? . . .
I am really at a loss of what to do. I set up my default.ctp as I mentioned above, but when I go to localhost:9999/posts the layout is still the same. I guess I need to include a stylesheet (and if so, where?)
I guess if someone can point me in the right direction to a beginner's guide to layout styling or how to use it I would greatly appreciate any help.
I would advice you to read the following from the cookbook: Layouts and CSS. Then copy the layout from /cake/libs/view/layouts/ to /app/views/layouts/ and modify it to your needs. After that create you stylesheet (or modify existing one) in /app/webroot/css/ and include it in your layout.
Create in app/View/Layout a file named "my_posts_layout.ctp"
In your PostController set $this->layout = 'my_posts_layout';
This way you should view the content defined on my_posts_layout.ctp.
Lack of stylesheets has no impact here.
How MVC works in CakePHP:
The router dispatches an incoming request to an appropriate Contoller.
The appropriate Controller function executes (no output, just fetching data, setting up variables).
The appropriate view is rendered. In fact, the output of the view is just contained in $content_for_layout.
What you really get back in the browser is in the layout. Therefore you can put your view's output into the layout by echo $content_for_layout in default.ctp. (Of course you can also have different layouts.) In addition, the layout can be enhanced with elements.
I really recomend the CakePHP CookBook, easily found from the CakePHP homepage. Modifying default.ctp should edit your applications layout.
A more specific question (eg. code samples of your default.ctp, expected results etc) might help people provide a better answer than mine.

Resources