Drupal Views 2: Output using custom markup - drupal

I have a simple view that grabs 4 fields, basically it grabs the fields of a specific content type. The fields are as follows:
CSS class (plain text)
Image (image)
Title
Body
Pretty simple stuff. I've got the view created, but I need to output things in a specialized way and I can't determine how this stuff breaks down in conjunction with my custom markup from my build. I need to wrap each row in a container and each row breaks down into it's own containers, take a look at the following code.
<div id="homepage-folio-portlets">
<div class="homepage-folio-portlet [CSS class]">
<div class="homepage-folio-portlet-image"><img src="[Image]" width="450" height="330" alt="" class="[CSS class]-image" /></div>
<div class="homepage-folio-portlet-text">
<strong>[Title]</strong>
<p>[Body]</p>
</div>
</div> <!-- /homepage-folio-portlet -->
</div> <!-- /homepage-folio-portlets -->
So I've got a container, homepage-folio-portlets, and inside of that I want to iterate over views creating a new container using the class homepage-folio-portlet for each row returned including the CSS class from the row.
My biggest hurdle is figuring out how to build either my .tpl files or my theme functions in template.php. I understand the naming conventions, but once inside I don't really know what to do. I have a feeling I'll need to do a little magic in template.php either way to make sure that my row output is aware of the CSS class from the content, but who knows. Any help and direction is appreciated.

After watching the aforementioned video it became a little more clear how to accomplish what I set out to do. The biggest "ah-ha" was that the default code for the "Row style output" template was confusing to me because of the foreach loop. I didn't recognize that I could simply output each field in whatever way I see fit in this file without the loop. The video showed how you could reference your fields individually with the following shorthand $fields['ID-of-field']->content. To get the 'ID-of-field' it's as scrolling past the "Display output", "Style output", and "Row style output" links in the "Theming information" option pane of your specific view.
I used the "Theme information" found in the edit screen of my view to determine the most specific .tpl for "Row style output" to create and created it, in this case view-view-fields--my-view-name--default.tpl.php.
view-view-fields--my-view-name--default.tpl.php - Row output .tpl file
(No longer making use of the default foreach because instead of looping over the fields I know the fields I want and I can simply output them anyway I see fit)
<div id="homepage-folio-portlets">
<div class="homepage-folio-portlet <?php print $fields['CSS_class']->content ?>">
<div class="homepage-folio-portlet-image"><img src="<?php print $fields['Image']->content ?>" width="450" height="330" alt="" class="<?php print $fields['CSS_class']->content ?>-image" /></div>
<div class="homepage-folio-portlet-text">
<strong><?php print $fields['Title']->content ?></strong>
<p><?php print $fields['Body']->content ?></p>
</div>
</div> <!-- /homepage-folio-portlet -->
</div> <!-- /homepage-folio-portlets -->
After that, I did a little recursion into the "Style output" and "Display output" .tpl files to get rid of all that extra markup Drupal adds. Note that all I really cared about was printing out $row (with it's foreach loop) in style .tpl and $rows in the display tpl. It's outputting EXACTLY what I want and I couldn't be happier. Finally, it's making some sense. Hopefully this helps a bunch of other people.
Just for reference...
views-view-unformatted--my-view-name--default.tpl.php - Style .tpl file
(Want to keep the foreach loop in here so each row gets outputted)
<?php foreach ($rows as $id => $row): ?>
<?php print $row; ?>
<?php endforeach; ?>
views-view--my-view-name--default.tpl.php - Display .tpl file
<?php print $rows; ?>
By removing all the extra markup I am losing important stuff specific to views like admin links and such, but for my purposes that's fine.

On the Edit tab for your view, under Basic Settings, look for "Theme:" and click on the "Information" link. Then in the "Default: Theming information" section, the bold filenames are the ones currently being used to theme a particular sub-section of that view. The other names are "suggestions" that can be used to override the defaults and they are ordered from least specific to most specific.
In your case, to start, it sounds like you want to override the "Row style output":
Click on the "Row style output" link, copy the default template code.
Choose one of the suggested filenames to use for the row style, based on whether you want this style to be used for all views, this view, a particular display of this view, etc.
Paste the code copied in Step #1 into the filename chosen in Step #2
Edit the code as necessary, to add the specific classes
Click on the "Rescan template files" to rebuild the template cache
Repeat steps 1-5 for any additional sub-templates you want to customize.

Have you tried using the template files for rows? You should see it in the views module (in the admin). By clicking on "Information" in the lower box on the left side when you are creating the view. You will need to refresh the template cache (you will see a button to do this).

Related

How to customise HTML structure in Drupal view block

I am currently developing a website in Drupal. I have a load of news articles which are of content type 'news'. I want to create a widget to show at the bottom of several pages listing the latest articles. I have managed to achieve thus far by creating the view with the fields I want and then making the view available as a block.
The problem is the format in which the articles are being listed in the view. Ideally I would like to customise the HTML. I understand that I can create a custom template to target views/blocks but I haven't quite got a full understanding of it yet, and find the Drupal documentation to be quite dry and therefore hard to find what I need from.
Any pointers would be helpful.
Go to your view edit page and select "table" as your view mode.
Go to "Theme information" and look for the desired (style output) template name.
Copy this name and create a new file in your theme folder using this name. I.e.: views-view-table--view-name-block.tpl.php.
In this file you can use the following structure (as an example) to get the values of the fields:
<?php foreach($rows as $row):?>
<div>
<h2><?php print $row['title'];?></h2>
<p><?php print $row['field_custom'];?></p>
</div>
<?php endforeach;?>
Don't forget press rescan theme files after you saved the file in the view theme section.
You can get as specific as you want. Create a block view next to the default or page view and you will see specific file names in the "Theme information" section.

How do I create different editable sections within a WordPress page?

I have been building my first theme on WordPress and have run into problem while adding content into different sections.
My HTML is somewhat like this,
<div id="maintext">
<-- Text -->
</div>
<div id="products">
<-- Text and Images -->
</div>
<div id="about_company">
<-- Text boxes -->
</div>
How do I make sure the content added via the WordPress editor falls under the respective divs ? For the "maintext" div I'll load the content from the page itself but how do I add content to the other 2 divs dynamically ?
I searched on a couple of forums and many suggested to add content using widgets, is there any way it can be done without using widgets ?
Any help will be gladly appreciated.
Unfortunately adding multiple editable fields in a single page is not particularly easy using WordPress by itself.
Many WP devs I know (myself included) rely on the Advanced Custom Fields Plugin for additional content fields.
The steps to make this happen:
1) Install the ACF the plug.
2) In the settings area for ACF create some new fields.
3) Assign the new fields to appear for a specific page or set of pages.
4) Update your page-template for the given page(s) so that the new fields are displayed.
For instance you might create a set of standard wysiwyg fields and then assign them to the 'overview' page. Let's call these fields: main_text, products_info and about_company. Once the fields have been created and assigned to a page, when you edit that page the additional fields will be available to edit.
For these new fields to be seen by visitors, they must be added to the page-template you use for your overview page. The code could be something like this:
<div id="maintext">
<!-- Text -->
<?php if(get_field('main_text')){ //if the field is not empty
echo '<p>' . get_field('main_text') . '</p>'; //display it
} ?>
</div>
<div id="products">
<!-- Text and Images -->
<?php if(get_field('products_info')){ //if the field is not empty
echo '<p>' . get_field('products_info') . '</p>'; //display it
} ?>
</div>
<div id="about_company">
<!-- Text boxes -->
<?php if(get_field('about_company')){ //if the field is not empty
echo '<p>' . get_field('about_company') . '</p>'; //display it
} ?>
</div>
There are lots of good examples here. If you are feeling really ambitious, rather than install the plugin you could even include ACF directly in your theme.
You've got three options I believe:
Create a widget area where you can then display the content in a text widget: http://codex.wordpress.org/Function_Reference/register_sidebar
Create a template where you then get the content of a different page: http://codex.wordpress.org/Page_Templates#File_Folders
Create a new meta box for all your pages: http://codex.wordpress.org/Function_Reference/add_meta_box
I believe that the thing you are looking for is option 2. The others are more full-site oriented, if you want the extra content to show up on every single page.
If you are writing the theme, maybe you would like to consider using a WordPress Framework so you don't have to start from scratch.
If that is not the case, think of the end user. How will they add sections to pages and posts? Will they have to move across places within the WordPress UI, or would they rather user short codes?
My recommendation is to build a plugin that render the section within the document content. Or widget content if that is the case.
I wrote a little piece of code to illustrate how you can accomplish such a thing, and also because I kind of need it right now :D. You can find it on github here https://github.com/lionpage/Front-Office-Document-Sections
Hope this helps
<div id="maintext">
<?php the_content(); ?>
</div>
<div id="products">
<?php // echo wp function to get product data; ?>
</div>
<div id="about_company">
<?php // echo wp function to get about companydata; ?>
</div>
I've run into this issue several times now, and while the question is 3 years old, I think it's still rather current. I've succesfully used the Multiple Content Blocks plugin sometimes now:
https://ltz.wordpress.org/plugins/multiple-content-blocks/
After installing the plugin, you can just include the_block in your template:
<div id="maintext">
<?php the_content(); ?>
</div>
<div id="products">
<?php the_block('products') ?>
</div>
<div id="about_company">
<?php the_block('company') ?>
</div>
hi im currently developing a theme with that set up.
there are two ways to achieve this:
widgetized and fixed admin panel (customizer options)
i am using the two in my themes
if widgets
create a .php file that includes the widgets sections
create a widget for that section
if fixed in admin panel
you have to include the .php section in your functions.php
edit * advantage of widgetized is you can arrange them just like in a regular sidebar
Was struggling with this, and did not want to use a plugin. The only WordPress native option I found was to use Custom Fields. This works, but only for text, and is rather cumbersome.
The other non-plugin option is to simply use HTML in the WordPress editor, but this is of course far from ideal either.
Finally I gave up, and opted for the Advanced Custom Fields plugin as well.

Display page view inside page.tpl.php drupal 7

I have a file called page--advertsindex.tpl.php.. Now what i want to do is display that page inside the content region of page.tpl.php..
page--advertsindex.tpl.php contains the HTML which need's to be rendered in the content region of page.tpl but what it does currently when i navigate to my_drupal_site/advertsindex it only show's the html of page--advertsindex, not the page.tpl.php file and the page--advertsindex in the content region..
How can i do this? or is there a different way to achieve my goal?
Any page--<identifier>.tpl.php will be used instead of page.tpl.php for the url /identifier. That is by design and the entire purpose of this system. This can be extended for deeper paths too: page--foo-bar-baz.tpl.php for /foo/bar/baz.
If you want certain content to appear on /identifier, you have two options: Conditionally include the content or copy the content. What to choose depends on your situation.
Conditionally include: inside page.tpl.php:
<div class="footer">
<?php if (arg(0) == "advertsindex"): ?>
<?php print theme("advertsindex_disclaimer"); ?>
<?php endif; ?>
</div>
Overrides: introduce a page--advertsindex.tpl.php:
<div id="content">
<?php print $content ?>
</div>
When to choose what:
Only use conditional includes or conditional rendering when:
The content to be included or excluded is small and shared. Patterns like `[large 20+ line of frontpage HTML][normal HTML] are very bad.
The content to be included needs all sorts of fancy new variables pulled in. Patterns like are really bad. Drupals theme system is push (theme gets variables from modules) and never pull (theme requests parameters at modules).
In all other cases you'd use the overrides. And yes, that will include a lot of duplication, but that is by design and accepted as the default practice in Drupal. To avoid having to modify some HTML in 20+ files, "split" or "copy" them as late as possible.
A rule of thumb is that a conditional should be a few lines only and never require variables that are not available in the parent.
If advertsindex is would be one of your content type then you have to create node--advertsindex.tpl.php file instead of page--advertsindex.tpl.php. Or If you wont to display some content in the page.tpl.php page, then it is better to copy all code of page.tpl.php into YOUR-Custom_page.tpl.php and put your code inside the content section of YOUR-Custom_page.tpl.php.
I think it helps.

Views is stripping tags from the output

I have a Drupal view which should output a video player using flash. I am trying to output a script that will call the flash film. The problem is that Views applies some sort of filter that strips my <script> tags, the opening and the closing one. I am searching a solution (some setting in views that will disable that filter), but cannot seem to find an answer. Other HTML tags work, but it seems the script tag is being stripped, probably for some security reason.
I have selected the option to rewrite the output of the field and I am using the tags correctly
Views also strips style attributes from my tags. For example:
<h3 style="border-bottom: solid 1px #ffcc99;">Some text here</h3>
appears like this:
<h3>Some text here</h3>
Is there a solution for this? Thank you.
Begin edited
I am pasting below the code I am using in my view.
<div class="bloco-filme">
[title]
<div class="field-imagem">
[field_imagem_fid]
<script type='text/javascript' src='sites/default/files/js/swfobject.js'></script>
<div id='mediaspace[nid]'>Se você estiver visualizando esta mensagem, significa o Flash Player não está instalado em sua máquina. Para assistir ao vídeo é preciso instalar o Flash player</div>
<script type='text/javascript'>
var so = new SWFObject('sites/default/files/plugins/jqplayer/player.swf','mpl','205','undefined','9');
so.addParam('allowfullscreen','true');
so.addParam('allowscriptaccess','always');
so.addParam('wmode','transparent');
so.addVariable('file','[field_video_fid]');
so.addVariable('quality','false');
so.write('mediaspace[nid]');
</script>
[field_video_fid]
</div>
<div class="field-resumo">
<p>[body]</p>
</div>
</div>
Edited again
The code above is beinng posted in my view. I have created a view to handle this. This is the FIELDS area of my view:
Fields
Node: Nid
Node: Título (title, it is in pt-br)
Node: Link "editar" (edit)
Node: Link "apagar" (delete)
Conteúdo: Imagem thumbnail image
Conteúdo: Video URL do arquivo (video file URL)
Node: Corpo (Body)
I have disabled the display of all the fields above and have packed all the code in the Body field. There I selected the option that I want to rewrite the output of the field.
kiamlaluno identified the basic problem, but to solve it, you're going to have to use a field template which will avoid using the filtering system Views uses. Group 42 has a great guide to walk you through the basics of Views theming, so I'll just gloss over those details and talk about your specific case.
First, you need to identify which field you want to rewrite: I believe you're doing that using the Field configuration, but it's not clear which field you are rewriting. I'm going to assume it's the body field. Go through Group 42's guide to create a new template file for the body field in your theme.
In the new template file, use the following code:
<div class="bloco-filme">
<?php print $view->field['title']->render($row) ?>
<div class="field-imagem">
<?php print $view->field['field_imagem_fid']->render($row) ?>
<script type='text/javascript' src='sites/default/files/js/swfobject.js'></script>
<div id="mediaspace<?php print $view->field['nid']->render($row) ?>">Se você estiver visualizando esta mensagem, significa o Flash Player não está instalado em sua máquina. Para assistir ao vídeo é preciso instalar o Flash player</div>
<script type='text/javascript'>
var so = new SWFObject('sites/default/files/plugins/jqplayer/player.swf','mpl','205','undefined','9');
so.addParam('allowfullscreen','true');
so.addParam('allowscriptaccess','always');
so.addParam('wmode','transparent');
so.addVariable('file','<?php print $view->field["field_video_fid"]->render($row) ?>');
so.addVariable('quality','false');
so.write('mediaspace<?php print $view->field["nid"]->render($row) ?>');
</script>
<?php print $view->field['field_video_fid']->render($row) ?>
</div>
<div class="field-resumo">
<p><?php print $output ?></p>
</div>
</div>
Save your new template file, and now the body field will be replaced with the correct output. Just make sure all the fields you've referenced in the template are before the body field within the Fields list when you edit the View.
You can see that this is mostly HTML with a few PHP bits. Code like this:
<?php print $view->field['title']->render($row) ?>
outputs the contents of a field other than current one (i.e. you use this code when you want to reference fields other than Body). It references the same row and finds the value of the field.
And code like this:
<?php print $output ?>
Outputs the value of the current field, in this case, Body.
I don't think the view is causing the issue. kiamlaluno is quite correct that the input format will strip a lot out of your code, unless you alter the input format, however I'm not sure you'll actually be able to achieve what you are trying to do using the body field in any sort of graceful way.
Use views to output the content you need from each node type, but I never use views to determine how this will be displayed (apart from ordering fields etc). I tend to do this either using the display fields option (/admin/content/node-type/[your-node-type]/display) or in the theme. In other words I theme the node (content type) or the field itself.
I would consider looking here - http://drupal.org/node/206980 - to see how to theme individual fields. use the field_ (field name prefix) at the start of a copy of the content-field.tpl.php in your theme folder (you'll find it in the theme folder of your cck folder), and use this to theme the field the way you want it to be presented (using your code above). So, when the view picks it up to display it, it will theme it using your code above.
This, of course, has the added advantage that you don't need to add in any code to the body element of the page, which is not a scalable way to do this at all.
Alternatively, you could write a small module which uses hook_field() (link 1, link 2) to rewrite the field display, but unless you want to be able to customize any of this in the admin area of the site, your best option is probably to theme the field itself as above.
I had nearly exactly this issue (thanks for posting it!), but a few things have changed (obviously) in the three years since this post.
In my case, using Views 3 and D7, I was able to paste all of the relevant swfobject code into a Header or Footer of my view, making sure to use the Text Area type with Full HTML as the text input filter.
No editing of the template.php was necessary. I even used token replacement to provide contextual filter arguments to my movie's flashvars.

Can I make fields visible only if image attach has an image

Is it possible to use CCK to add a conditional to the image attach module form where unless I have selected an image to use for a content node, certain fields are not visible?
Currently I do not have any operations available for my image attach field in my content type definition where configure and remove are available for all other fields.
This would be really simple in your theme, e.g. node-foo.tpl.php for the content-type foo, that has a field "video"
<?php if(!empty($field_video[0]['view'])): ?>
<div class="block video">
<?php print $field_video[0]['view'] ?>
</div>
<?php print $field_some_other[0]['view'] ?>
<?php print $field_the_other_one[0]['view'] ?>
<?php endif; ?>
Some notes on style and best practices:
I prefer the if/endif in templates, others prefer the if() {}. Technically little difference, I think elseif; is more readable in HTML.
Technically it is not correct to simply print a value, but one should use drupal_render(). I personally still prefer print, because of its transparancy and simplicity. Drupal_render(), however, registers what it has "rendered" and allows you to drupal_render($node) at the end, to render all unrendered fields; very usefull if you decide to add fields later on, whithout having to change the entire template every time you do so. Drupal_render is not available in the tpl.php, but in the preprocessing: as sayd, a lot less transparent and slightly more complex.
Dont! Ever! print the $field_foo[0]['value'], always the ['view'] part: the first is unescaped and may (will!) contain XSS injections and the likes.
The strange nested array ($field_foo[0]['value']) is a result of the multiple-fields option in Drupal. A better way would be to always iterate over each field and never just render, hardcoded, the first ([0]) item. However, for reasons of readability, simplicity and transparancy, I prefer to hardcode the indexes in my template. Others (rightfully) disagree with me on this.

Resources