n my module I use the hook_node_view to make alterations to the content when it is viewed. To do this I fetch and set $node->content['body'][0]['#markup']. It works fine, but I've lately had some trouble with my teaser views which made me track the problem to the data fetched from $node->content['body'][0]['#markup'].
It seem like what is in it depends at least on the view mode because if I do write
print $node->content['body'][0]['#markup'];
either when the mode is 'full' or when it's 'teaser' I get different results.
For some reason the content of $node->content['body'][0]['#markup'] is very short when I view the content as a teaser. Shorter then the teaser length even.
This made me wonder more about what is in $node->content['body'][0]['#markup'], and when and where it is set?
Instead of using hook_node_view I would suggest using hook_node_load.
http://api.drupal.org/api/drupal/modules%21node%21node.api.php/function/hook_node_load/7
Related
I have two content types (in a Drupal 7.20 environment) which embed views or blocks. When I allow those content types in search results, the results page goes sideways whenever those content types are represented in the result set: the pager shows a different number of total pages from one results page to the next, or disappears entirely after I hit Next (!), fewer than 10 results show per page (yet there's a pager...), etc., etc.
If I disallow those content types (via Custom Search), I don't see any problems with pagination, etc.
What I have noticed is that the actual views/blocks get executed when the search results page is constructed - it's not merely a matter of hits being found in the search_index table.
Anybody know how to address this problem?
(I've searched through stackoverflow, and issues for Search and Custom Search on Drupal.org - no joy.)
Thanks in advance,
Lee
[Edit: fixed a couple of typos...]
[3/17/13 Edit: The problem turns out to be due to the pager for the view or block that is included in the search result set. If the view is in the result set, but doesn't have a pager, there is no problem. My solution, therefore, is to detect that I'm on a search results page in hook_views_query_alter() (by looking at the request URI) and set
$view->items_per_page = 0;
which effectively gets rid of the view's pager.
[I didn't realize I could answer my question - not sure how that's different from editing the question to include the answer, but I'll put my answer here as well, anyway.]
The problem turns out to be due to the pager for the view or block that is included in the search result set. If the view is in the result set, but doesn't have a pager, there is no problem. My solution, therefore, is to detect that I'm on a search results page in hook_views_query_alter() (by looking at the request URI) and set
$view->items_per_page = 0;
which effectively gets rid of the view's pager.
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.
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.
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".
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.