欢迎各位兄弟 发布技术文章
这里的技术是共享的
In the popular open-source content management system (CMS) Drupal, titles display on every page as part of the Content Management System's functionality. But what if you don't want to have the titles display on some pages? For example, if you want to use a banner instead of the plain title. There's an easy way to make Drupal's node titles optional using the Content Construction Kit (CCK) module.6.x
Presumably you already have Drupal installed if you're reading this. If not, check out Drupal. It's a powerful CMS that is has a great community of developers. Many sites from well-known companies are powered by Drupal. Even the White House's website is powered by Drupal!
What you'll need to get started:
If you don't already have CCK installed, download and install it to your Drupal site now.
Step 1 — Finding content types settings
Once you've installed CCK, go to the "content types" section of Drupal admin (found at /admin/content/types).
Step 2 — Managing a content type's fields
Select "manage fields" for the content type you wish to edit.
Step 3 — Adding a new field
Add a new field to the content type. To do this drag the "new field" row to the position you want and fill in the field information. You'll probably want to drag your new field to right below the title field. You can use whatever label and field name you want, but we use "Title hide" and "titlehide" and we'll refer back to this later. The type should be set to "text" and the form element should be set to "Single on/off checkbox." This field will be used to specify if you want the node's title to be displayed or hidden. Once you're done, click "save."
Step 4 — Defining field's allowed values
After you press save, you'll be brought to a new page where you can specify more detailed settings for the field. Here you need only change one setting: the "allowed values list." Enter "display|Display Title" on the first line and "hide|Hide Title" on the second line. These values will be referred to later. Once you've entered this, scroll down to the bottom of the page and save the field settings.
Once you save, you'll see your new field along with the others.
Step 5 — Hiding the new field
Because this field will be used internally to hide or show the title of a page, you don't want this field to display in the node view. To hide the display of this field in the node view, click on the "display fields" tab. Once the display fields settings have loaded, change the label, teaser, and full node display to "" and then save.
Step 5 — Grab a cup of coffee (tea?)... you're almost done
Awesome — you're "title hide" field is all set up (but you're not done yet)! If you go to add a new node of that content type, you'll see you can now tick the box to hide the title.
Step 6 — Bring the field to life
In order to make your new title hide field useful, you need to build it into your theme. To do this, I added some PHP code that will insert the value of the field as a CSS class of the title.
Step 7 — Identify the theme file that displays the node's title on the page
Identify the theme file that displays the node's title on the page. For most themes the theme file that is responsible for displaying the title is called page.tpl.php.
Step 8 — Find the PHP code that displays the page's title
Locate the PHP code that displays the title:
<?php print $title; ?>
It may be surrounded by additional related HTML and PHP that define layout, styles, or in which cases the title should load:
<?php if ($title): ?> <div id="title"><h1><?php print $title; ?></h1></div> <?php endif; ?>
Step 9 — Insert your title hide field as a class of the title's H1 tag
Insert your title hide field as a class of the H1 tag. This will look something like this:
<?php if ($title): ?> <div id="title"><h1 class="title <?php if(!empty($node->field_titlehide[0]['value'])) {$titlehide = $node->field_titlehide[0]['value']; print $titlehide;} ?>"><?php print $title; ?></h1></div> <?php endif; ?>
Step 10 — Add the CSS class that hides the title
Hiding the h1 tag is based on CSS style rules. Add a CSS rule like the following anywhere in your theme's stylesheets:
h1.hide{ display: none; }
Step 11 — Finito
Congratulations! You now have optional Drupal node titles.
Nothing seems to be happening...
Hiding the h1 tag is based on CSS style rules. Did you remember to add a CSS style rule like the following in order to hide your title?
h1.hide{ display: none; }
This style can be added anywhere to any of your site's CSS stylesheets.
The CSS class isn't being added to the title
Here are a few suggestions...
Thanks, that's awesome!
I've been scratching my head on this small problem for a while!
You're tute works just perfect.
One question however: my Title Hide field offers a third (and default) radio box saying "N/A". How do i get rid of it?
Thanks again!
Simon
Thanks for all the great information. I am glad I ran across your blog. I look forward to reading your next post.
How would I hide a field title? I am just getting into Drupal.....
Cliff
Nice tutorial, thanks.
If I promote the node to display on front page, it will still show the title.
Any idea where that code would be?
thanks
I have the Drupal acquia installation (which includes cck), with the zen theme, and cannot get it to work. Any thoughts?
For my use case I need the actual div "<div id="title">" to not be printed at all when hidden. How could this be accomplished?
So I figured out how to do this with basically the same setup (except my CCK field is titled "field_title_hide")
Instead of changing anything in your page.tpl.php file, add the following to your template.php file. Change "THEMETITLE" to the title of your theme and "field_title_hide" to the name of your cck field.
function THEMETITLE_preprocess_page(&$vars) { if($vars['node']->field_title_hide[0]['value'] == 'hide') { unset($vars['title']); }else{ $vars['title']; } }
Thanks for the clearly written tutorial.
If you have time, it would be really useful to know how to use a similar process to add a CSS tag to a Views field.
I have a Product content type with a single on/off checkbox. First value is empty, second value displays a "New Product" checkbox in node/edit.
allowed values look like this:
|
New | New Product
Products are searchable via exposed filters in views, and I'd like to display "NEW" next to the title (in the filtered results) for any product that's checked New Product.
If I could get the view to add a "new" class to "field-content", I could add a NEW image using specific CSS. I copied views-view-fields.tpl.php and tried adding your code above:
<<?php print $field->element_type; ?> class="field-content <?php if(!empty($node->field_new_product[0]['value'])):?>new<?php endif; ?>"><?php print $field->content; ?></<?php print $field->element_type; ?>>
but it may be obvious that I really have no idea how to get it to read the node's value for field_new_product. A conditional statement that reads the value? And is this whole thing more doable in template.php? Thanks in advance!
Very cool! Thanks for sharing. Now I'm following you..
thanks for your time.! I've used the rewrite before, but didn't think to apply here.
regarding the template, I had gotten as far as theming views-view-field--field-new-product-value.tpl.php with an if/then, but couldn't get it to work right (only "then" was applied). Your solution is MUCH easier.
just read your About page. I can't believe you just graduated from high school last year!! Amazing!
Superb! Generally I never read whole articles but the way you wrote this information is simply amazing and this kept my interest in reading and I enjoyed it. You have got good writing skills.
Greatly written article but for some reason it doesn't seem to be working for me. I copied the code into the area I thought it belonged in the page.tpl.php file.
I'm using a zen based sub theme as well: Here's the code snippet:
<?php if ($breadcrumb || $title || $tabs || $help || $messages): ?> <div id="content-header"> <?php print $breadcrumb; ?> <?php if ($title): ?> <div id="title"><h1 class="title <?php if(!empty($node->field_titlehide[0]['value'])) {$titlehide = $node->field_titlehide[0]['value']; print $titlehide;} ?>"><?php print $title; ?></h1></div> <?php endif; ?> <?php print $messages; ?> <?php if ($tabs): ?> <div class="tabs"><?php print $tabs; ?></div> <?php endif; ?> <?php print $help; ?> </div> <!-- /#content-header --> <?php endif; ?>
Not much of a coder so I'm not sure if I put it in the right place. But that was the only instance of <?php print $title; ?> I found. Thanks for your help.
Hey, your code appears to be fine. Did you add the css style rule that would hide the title element if the setting is turned on? If not, you'll need to go ahead and add this rule. If so, and the css class isn't showing up at all, there's a problem with Drupal calling a variable.
You can use the Devel module (this is a contributed model, not a core module) in order to see what variables are being loaded through the template and are available to use.
Since you're using a zen-based template, the variable should be available to the page.tpl.php theme file.
I've tried doing this, but the title is still there. I am using the Zen starter theme. I replaced the code in the page.tpl.php form, but nothing seems to change.
On the source I see this
1 | <div id= "content-header" > |
2 | <div id= "title" ><h1 class = "title hide" >Home</h1></div> |
3 | </div> <!-- /#content-header --> |
Pardon my ignorance, I'm still learning, but where would would I add the CSS class too?
Outstanding! That looks like that took care of that. I will definitely check out your site for other tips and tricks as I learn my way through drupal. Thanks!
Okay awesome got it to work for individually generated Page, Blog and Forum titles. Thanks, turns out I had forgotten to add the CSS class.
How do I go about hiding the title for the main Blog and Forums pages?
site.com/blog
site.com/forums
Both still have their titles (Blog, Forums) visible. And I'm not sure where to turn those off. Thanks again for your help.
Unfortunately my method only works for nodes. There is however, an alternate method that can be applied to any page:
Add the following code to your template.php file (anywhere will do as long as you don't break up another piece of code), making sure to change any instance of 'magic' to the actually name of your own theme. Note that this name is the name of your theme's .info file, omitting the .info extension.
001 | /** |
002 | * Override or insert variables into the page templates. |
003 | * |
004 | * @param $vars |
005 | * An array of variables to pass to the theme template. |
006 | * @param $hook |
007 | * The name of the template being rendered ("page" in this case.) |
008 | */ |
009 | function magic_preprocess_page(& $vars , $hook ) { |
010 | // Add conditional stylesheets. |
011 | if (!module_exists( 'conditional_styles' )) { |
012 | $vars [ 'styles' ] .= $vars [ 'conditional_styles' ] = variable_get( 'conditional_styles_' . $GLOBALS [ 'theme' ], '' ); |
013 | } |
014 |
015 | // Classes for body element. Allows advanced theming based on context |
016 | // (home page, node of certain type, etc.) |
017 | $classes = split( ' ' , $vars [ 'body_classes' ]); |
018 | // Remove the mostly useless page-ARG0 class. |
019 | if ( $index = array_search (preg_replace( '![^abcdefghijklmnopqrstuvwxyz0-9-_]+!s' , '' , 'page-' . drupal_strtolower(arg(0))), $classes )) { |
020 | unset( $classes [ $index ]); |
021 | } |
022 | if (! $vars [ 'is_front' ]) { |
023 | // Add unique class for each page. |
024 | $path = drupal_get_path_alias( $_GET [ 'q' ]); |
025 | $classes [] = magic_id_safe( 'page-' . $path ); |
026 | // Add unique class for each website section. |
027 | list( $section , ) = explode ( '/' , $path , 2); |
028 | if (arg(0) == 'node' ) { |
029 | if (arg(1) == 'add' ) { |
030 | $section = 'node-add' ; |
031 | } |
032 | elseif ( is_numeric (arg(1)) && (arg(2) == 'edit' || arg(2) == 'delete' )) { |
033 | $section = 'node-' . arg(2); |
034 | } |
035 | } |
036 | $classes [] = magic_id_safe( 'section-' . $section ); |
037 | } |
038 | if (theme_get_setting( 'magic_wireframes' )) { |
039 | $classes [] = 'with-wireframes' ; // Optionally add the wireframes style. |
040 | } |
041 | $vars [ 'body_classes_array' ] = $classes ; |
042 | $vars [ 'body_classes' ] = implode( ' ' , $classes ); // Concatenate with spaces. |
043 | } |
044 |
045 | /** |
046 | * Override or insert variables into the node templates. |
047 | * |
048 | * @param $vars |
049 | * An array of variables to pass to the theme template. |
050 | * @param $hook |
051 | * The name of the template being rendered ("node" in this case.) |
052 | */ |
053 | function magic_preprocess_node(& $vars , $hook ) { |
054 | // Special classes for nodes |
055 | $classes = array ( 'node' ); |
056 | if ( $vars [ 'sticky' ]) { |
057 | $classes [] = 'sticky' ; |
058 | } |
059 | if (! $vars [ 'status' ]) { |
060 | $classes [] = 'node-unpublished' ; |
061 | $vars [ 'unpublished' ] = TRUE; |
062 | } |
063 | else { |
064 | $vars [ 'unpublished' ] = FALSE; |
065 | } |
066 | if ( $vars [ 'uid' ] && $vars [ 'uid' ] == $GLOBALS [ 'user' ]->uid) { |
067 | $classes [] = 'node-mine' ; // Node is authored by current user. |
068 | } |
069 | if ( $vars [ 'teaser' ]) { |
070 | $classes [] = 'node-teaser' ; // Node is displayed as teaser. |
071 | } |
072 | // Class for node type: "node-type-page", "node-type-story", "node-type-my-custom-type", etc. |
073 | $classes [] = magic_id_safe( 'node-type-' . $vars [ 'type' ]); |
074 | $vars [ 'classes' ] = implode( ' ' , $classes ); // Concatenate with spaces |
075 | } |
076 |
077 | /** |
078 | * Override or insert variables into the comment templates. |
079 | * |
080 | * @param $vars |
081 | * An array of variables to pass to the theme template. |
082 | * @param $hook |
083 | * The name of the template being rendered ("comment" in this case.) |
084 | */ |
085 | function magic_preprocess_comment(& $vars , $hook ) { |
086 | include_once './' . drupal_get_path( 'theme' , 'magic' ) . '/template.comment.inc' ; |
087 | _magic_preprocess_comment( $vars , $hook ); |
088 | } |
089 |
090 | /** |
091 | * Override or insert variables into the block templates. |
092 | * |
093 | * @param $vars |
094 | * An array of variables to pass to the theme template. |
095 | * @param $hook |
096 | * The name of the template being rendered ("block" in this case.) |
097 | */ |
098 | function magic_preprocess_block(& $vars , $hook ) { |
099 | $block = $vars [ 'block' ]; |
100 |
101 | // Special classes for blocks. |
102 | $classes = array ( 'block' ); |
103 | $classes [] = 'block-' . $block ->module; |
104 | $classes [] = 'region-' . $vars [ 'block_zebra' ]; |
105 | $classes [] = $vars [ 'zebra' ]; |
106 | $classes [] = 'region-count-' . $vars [ 'block_id' ]; |
107 | $classes [] = 'count-' . $vars [ 'id' ]; |
108 |
109 | $vars [ 'edit_links_array' ] = array (); |
110 | $vars [ 'edit_links' ] = '' ; |
111 | if (theme_get_setting( 'magic_block_editing' ) && user_access( 'administer blocks' )) { |
112 | include_once './' . drupal_get_path( 'theme' , 'magic' ) . '/template.block-editing.inc' ; |
113 | magic_preprocess_block_editing( $vars , $hook ); |
114 | $classes [] = 'with-block-editing' ; |
115 | } |
116 |
117 | // Render block classes. |
118 | $vars [ 'classes' ] = implode( ' ' , $classes ); |
119 | } |
120 |
121 | /** |
122 | * Converts a string to a suitable html ID attribute. |
123 | * |
124 | * <a href="http://www.w3.org/TR/html4/struct/global.html#h-7.5.2" title="http://www.w3.org/TR/html4/struct/global.html#h-7.5.2">http://www.w3.org/TR/html4/struct/global.html#h-7.5.2</a> specifies what makes a |
125 | * valid ID attribute in HTML. This function: |
126 | * |
127 | * - Ensure an ID starts with an alpha character by optionally adding an 'id'. |
128 | * - Replaces any character except alphanumeric characters with dashes. |
129 | * - Converts entire string to lowercase. |
130 | * |
131 | * @param $string |
132 | * The string |
133 | * @return |
134 | * The converted string |
135 | */ |
136 | function magic_id_safe( $string ) { |
137 | // Replace with dashes anything that isn't A-Z, numbers, dashes, or underscores. |
138 | $string = strtolower (preg_replace( '/[^a-zA-Z0-9-]+/' , '-' , $string )); |
139 | // If the first character is not a-z, add 'id' in front. |
140 | if (!ctype_lower( $string {0})) { // Don't use ctype_alpha since its locale aware. |
141 | $string = 'id' . $string ; |
142 | } |
143 | return $string ; |
144 | } |
145 |
146 | // Allows theming of individual nodes |
147 | // function phptemplate_preprocess_node(&$vars) { |
148 | // $vars['template_files'][] = 'node-' . $vars['nid']; |
149 | // return $vars; |
150 | // } |
And then make sure you're page.tpl.php file's body tag looks like this:
1 | <body class = "<?php print $body_classes; ?>" > |
This will add relevant classes to the body tag about the content you're on. You can use these classes to create CSS style rules to hide h1 tags on specific pages.
Okay so I added that code to the template.php folder.
I see how it creates:
body class="not-front logged-in no-sidebars page-blog section-blog lightbox-processed"
But from there I'm lost. I added a .page-blog class to the style.css and I can make the whole page disappear with display: none; but I haven't been able to come up with the code to make just the page title disappear.
Thanks for your help. *sigh* Chose Drupal because I thought I wouldn't have to code anything. :P
Here's what that code specifies:
Set the display mode to hide for h1 elements with the class "title" that are child to (nested within) the body element with the class of "page-blog."
If the title is an h2, you'll have to replace h1 with h2 in the rule.
Awesome. Got it. And I even understand it.
If I end up saying screw it and decide to have someone else do all the work for me I'm calling you guys for a quote :)
No problem and sounds good, haha. Good luck with your project.
Our theme uses this code for the page title.
<?php if ($title): echo ''. $title .''; endif; ?>
Any idea how to code it for this to work? THANKS
Hi,
I'm trying this again, but I switched to the wabi theme. I can't get it to work, and the title function in the page.tpl.php page has a bit more code. Is it possible to get it to function in this theme? Here is what the code looks like
01 | <?php print $breadcrumb ?> |
02 | <?php if (! empty ( $node ) && $page == 0) { ?> |
03 | <div id= "cr8" ></div> |
04 | <?php } else { ?> |
05 | <?php if ( $title ) { ?> |
06 | <table border= "0" cellpadding= "0" cellspacing= "0" class = "pagetitle" > |
07 | <tr> |
08 | <td class = "pagetitle-l" ></td> |
09 | <td class = "pagetitle-c" > |
10 | <h1><?php print $title ?></h1> |
11 | </td> |
12 | <td class = "pagetitle-r" ></td> |
13 | </tr> |
14 | </table> |
15 | <?php } ?> |
I read your post about "How to Make Optionally Hide Node Titles in Drupal (Using CCK)" and I evaluated it very interesting but unfortunately it don't work for me.
I have made all the change in drupal and i think that the problem is in my page.tpl.php.
Can you see my code (if i understand where is the problem i can share your metod with italian drupal community)?