Drupal 7: How do I add custom field info to my page? - php

I have a Drupal 7 question. What's the best way to display my values for custom fields onto a page?
I know there's the Manage Display, which is great for sorting information, but I'd like to add lots of styling to these values, place them all over the page in different places, and also use some of them multiple times. Sometimes I'd even like to use values inside other values (like adding field1 and field2 and displaying the sum, or making a field clickable to go to a URL designated in another field).
I've looked at things like Display Suite, but that's more for the whole page. I only need to adjust what shows up in the main content area. It also doesn't seem to do what I need to do.
My themes I've used seem to add variables inside the page code (the .tpl files) and display information that way.
What I've been doing is using some of the included variables (like print $date; and print $time;) and have been calling them directly using PHP and the complex array system revealed by devel.
For example, if I want to show body content, I do this:
$myContent .= "Body: ".$content['body']['#items'][0]['value'];
It works, but I have a feeling there's a better way. If so, what? I haven't yet found it, since I'm looking for something which gives me the most control over how I display the variables for each node type.
Thanks!

https://www.drupal.org/node/1375160
https://www.drupal.org/node/1795314
https://www.drupal.org/node/1433006
you have several post related on this...

Related

Filter Table format view - Drupal 7

I'm looking for some help about "Custom View". I looked throw the internet but can't find it (maybe cause of my bad key words).
I created a custom view with a Table format. The goal is to display content (based on a content type) in a table.
I already have my content showing, I can reorganize rows by client/sector.. by clicking on the column header but now I'd like to :
Filter result depending on the string in an input textfield
and
Filter result using a dropdown menu
I guess It's client side, but I'm a beginner in drupal so it's a bit hard to find out.
Here is what I'd like :
http://hpics.li/175e64e
For the select filter, you should try using exposed filters in your view. In the filter section, add filter on the fields and expose them. If these fields are taxonomy reference fields it should work right away. Otherwise it depends : with entity reference I think Better Exposed Filters can be usefull.
With plain text fields it will be more difficult to get what you want (personnaly I give up on exposed filters when it becomes to complicated), but still possible with this approach and a bit of client side work.
The general idea is to create JSON view wich gets all differents values for a text field across the nodes, using Views Data Source (or get all nodes with fields values then fetch unique values for each fields in javascript).
On client side, on the page load make an ajax call to this view to get an array of all possible values, then build your select list using this array, and then do a client side filtering (using for example the excellent Isotope).
But in my opinion you need to take side : all with views and exposed filters (server side, can be hard and frustrating...) or all in JS (client side), mixing the two should result in a big mess...
For the plain text search box I would choose to work client side, Views won't be of any help I'm afraid.
You can also find good javascript plugins for table sorting / filtering like Datatables.
Good luck.

ModX revo 2.2x: How to use a TV value to set tpl?

I'm trying to figure out a way to render a resource with a specific tpl based on a template variable(tv) value. here is my use case:
I have setup a modx installation for a basic site with a homepage and a blog (I used the articles add-on). I want to display blog posts on the home page, outside of the articles container. From my experience the easiest way to do this is with getResource. However for this specific project I would like to change the tpl of the getResources results based on whatever the tv value is for each result.
The template variable can be looked at as a "post type". if you choose "text" it would have tplA, if you choose "multimedia" it would have tplB etc...
now based on my research you would use the properties 'tplCondition' and 'conditionalTpls' to achieve this in your getResources call, something like this:
[[getResources?
&tplCondition=`tv.blogPostType`
&conditionalTpls=`{"1":"tplA","2":"tplB","3":"tplC"}`
&tpl=`defaultTpl`
]]
The problem is, this does not seem to work with template variables :( it even says it only uses resource fields in the documentation.....which is a REAL bummer, as i have no idea to pull this off otherwise. Based on my limited knowledge, you can maybe create a snippet or something that does this, But i have no clue.
Does anyone have an elegant solution to this problem?
to sum up what im trying to do, again:
-assign a "post type" to blog posts in my articles container via template variable.
-use the template variable value to set a specific tpl based on that value.
any help is highly appreciated. thanks
EDIT: okay I got a reply on the forums and have come across a"solution" to this.
you can accomplish this with css. in the tpl, you do something like:
<article class="[[+tv.post-type]]">....</article>
this will output the post type selected in the tv as the actual element class used, and you can then use css to give the output different looks based on the tv. its actually so simple im a little embarrased i didnt see it before. In my situation it 100% solves my problem, however if you needed to chasnge html im guessing javascript would need to be involved or another method with php. just leaving this here in case someone needs it!
If you need to do major changes to the html you could still probably solve it with css if you have a nice markup. However if thats not enough i would solve it by using one tpl for the getresources call, and letting that tpl handle the switching. If you could have your TV output the value symbolize the name of the tpl that should be used in each case, your tpl would only need this:
[[$[[+tv.yourtv]]]]
Your tv will be evaluated first, and then it will be processed as a chunk. That way you dont need a nasty switch or if-clause.
This is assumin you want toally different tpls, and not just need to change some small part of the standard tpl, in that case you could still use this tecnique though!
Conditional templates seem to work fine with pdoResources (part of pdoTools). (I have to put "tv." in front of the TV in the tplCondition but not in the other TVs)
James is correct.
[[pdoResources?
&includeTVs=`blogPostType`
&tplCondition=`tv.blogPostType`
&conditionalTpls=`{"1":"tplA","2":"tplB","3":"tplC"}`
&tpl=`defaultTpl`
]]

Pagination with XML and PHP?

before anyone asks; I've googled my 'question', I've also looks at the 'Questions that may already have your answer' and none of them work.
What I'm wanting to do is 'Pagination'. However, I don't want to use Databases as I've never had to and I'd rather not give up and go to them now as XML does everything I want it for.
The code I have is the following:
$files = glob('include/articles/*.xml');
foreach($files as $file){
$xml = new SimpleXMLElement($file, 0, true);
}
I've tried these ones already: XML pagination with PHP, PHP XML pagination and Pagination Filtered XML file and have achieved nothing. I have also tried a lot of Javascript 'pagination' scripts and still nothing.
So to sum it up: I have four articles (More to be added) and I want to show 2articles per a page. The following information will be 'pulled' from the xml file: ID, TITLE, CONTENT, PICTURE, AUTHOR, DATE by doing $xml->id and so on for the rest of them. Does anyone know of any way of doing this? as I've spent the past four hours (Its 4:04AM GMT) and have found nothing that works yet. (If I find anything that does work I'll make sure to update the question with the working code encase there is anyone else out there that needs help with this too.)
For a start define the order in which you want your articles to appear. I.e. which article goes on page 1, which one on page 2, etc. This is important, because that order will be the base for your pagination algorithm. Please note that glob() is not guaranteed to return results in any specific order, which means the order can change from one invocation of your script to another (notably when you add new articles) -- almost certainly not what you want.
Then the second step is to introduce another variable which is part of your URL that denotes the actual page (number) you're on. The URL query string would be a natural choice for putting this information, so your URL's look like: article.php?page=1. On the PHP side you can use the $_GET superglobal to retrieve the query string parameters.
Thirdly, use the new style URL's whenever you link to your article.php script. Additionally, validate the input --especially when you also want to display the current page based on this parameter (or you will end up with an injection vulnerability). This also means you want to have a default value (in case the value is invalid/wrong/ or not supplied at all for some reason).
Finally, filter your articles based on the two key pieces of information: the order of the articles w.r.t. the page number and the page number: i.e compute the actual articles that should appear on the current page.

Converting a site from HTML to Smarty

I have a series of HTML pages which I am converting into Smarty syntax since I've learnt this. This site is a fairly old one in design terms, no include etc. - even though our .htaccess allows us to treat PHP as HTM extension.
I've saved a few as .tpl pages, but what's the best way to go about converting it into full-scale templating?
I've been slowly, but tediously, splitting pages into .tpl files, although not sure if that's the right way to do it... the site is a jointly-created one, dating back to 2006 originally as pure HTML.
I'm using a templating engine because that's what the original site-owner wanted, and we're both competent at using a templating engine.
The manual on Smarty was useful; but I'm wondering how to do a Smarty pagination script where the data is paginated like this for database results (moving some data into a new database that was formerly static data enclosed in < li > tags), rather than 1-10, 11-20 etc.:
http://i44.tinypic.com/5uh7nk.jpg
If there's another solution (for now we don't quite need CodeIgniter etc.) I'd appreciate the help! ;)
The SmartyPaginate plugin may help. This was written by one of the original Smarty developers. I'm not sure if it is compatible with Smarty 3 though, if that is what you're using.
The other possibility would be to create a template that outputs the pagination, and accepts some parameters to set the options.
e.g.
{include file="paginator.tpl" curpage="3" perpage="50" numitems="3428" link="showitems.php" param="p"}
Where...
curpage = the current page being viewed, this would be set by PHP.
perpage = how many items to show per page - this is probably a static value set by php, or from user preferences
numitems = how many total items there are - this is calculated by php/sql and passed to template
link = the page to link each page to
param = the parameter to use for the page number, this is used by PHP to get the page to be viewed. i.e. items.php?p=1
That said, you would use PHP code to check to see if a page number was set in the URL, and then check to see if the page number is valid and within the acceptable range.
Your actual page content would just loop over an array of items which would be the results from the database. Depending on what set of results was fetched, it will be showing items from the given page.
If the SmartyPaginate plugin won't work, you could probably look at it for help with the process of pagination and adapt it to your needs.

Drupal - logic of the template.php file

I have spent a good proportion of time today looking into expanding a drupal site I inherited, convinced that the issues I face were down to my bespoke SQL query.
I have since realised that the SQL is ok (checked it in PHPMYadmin and got it executing of sorts within the drupal website). So I am happy I am getting all the results from the database I need, looping through them and outputting them on the page in the specific markup.
The problem I have is where the loop is displaying. I cannot seem to figure the theming system or understand what is going on in template.php.
Let me explain:
The code I needed to change was in the template.php file. My understanding is that this file allows you to overide certain functions and theme elements.
Within the template.php file this is the code I needed to change:
//old function from original development
function abc($node,$submitted,$node_url) {
//execute code
}
So I added my code within function abc(), as I wanted it to be output where the old code was output.
This is my psuedo code for the sql and the loop:
function abc($node,$submitted,$node_url) {
$sql = 'my sql query'
$results =db_query($sql);
while ($data = db_fetch_array($results)) {
//output my results here
}
}
What led me to believe that the sql was wrong is that I should have got 23 results, but I was getting a lot more duplicate entries. After wasting alot of time looking in the wrong place, and scrutinising the sql, I realised that it was the function executing the sql and the loop multiple times, not the sql returning duplicate entries. I did this like so:
function abc($node,$submitted,$node_url) {
$sql = 'my sql query'
$results =db_query($sql);
$x = 1;
while ($data = db_fetch_array($results)) {
if ($x == 1) {
echo '<p style="background-color:#ccc;">'. $x . '. '.$data['title'] . '</p>';
}else{
echo '<p>'. $x . '. '.$data['title'] . '</p>';
}
$x = $x + 1;
}
}
As the code executed I was expecting an incremented number to go on for as many duplicate entries and shade the first entry's background to grey, but it did not. At result 23, it reset itself to 1 and shaded that entry's background to grey, indicating to me that it was the function executing the sql and the loop multiple times.
I am not wholly sure what this abc() function is, apart from the fact that when I place my code within it, the output displays where I need it to on a specific page and nowhere else (with no duplicate entries).
When I take my code out of this function (still within template.php), my code is output in the head of all pages which is not desirable.
Does anyone have any ideas as to what might be happening, where I can look to find out what this function is or know of a way for me to determine the display of my code?
I have been reading a bit about themes etc, but working with someone else's code is turning into a bit of a confusion nightmare.
Cheers in advance!
You are down the wrong path here, probably because you are inexperienced in how Drupal works, so let me give you some info and advice.
You could say that Drupal have to layers in which it execute code, the modules/core and the theming. Generally you could say that the first layer, the modules/core is the generation/fetching of data, while the 2nd is the presentation of that data. What you are doing is fetching data in the presentation layer, which really should be avoided. This is also the reason why you had so much trouble tracking down the cause, because of the confusion of what is getting the data and what is presenting it. What you did is also very much a waste of resource, I'll come to that later, but first what happened?
You have taken over a site, which probably have a custom theme, and I can tell that it has been made in an hacky way. Maybe the one who did it, didn't know the proper way but made something that “works”. Now what trying to alter it, you broke it. When Drupal presents a node (a node is a piece of content), it gets a lot of data, modules can hook in and add, alter or delete that data, and in the end the data gets to the template (all template files are denoted tpl.php - that is unless a different template engine is used). The way this works, is that it uses the “page” template to create the basics of the site, the navigation, the different regions ect. Now when displaying a list of nodes, each node will be displayed within the page template by having it's data outputted to the node template. Normally there's a lot of divs ect. combined with some php printing of data. In your example a function was also called. In some cases this can be fine, if you use fx translate functions for multi lingual sites or a simple function that checks something for you. However in your case you used that function to get data. By looking at the SQL you created it seems like you actually was trying to get the list of blog nodes you wanted to show. This could kind of work if only a single node was displayed, but when a list of nodes are displayed, you run the SQL and print the result for every node listed which is what got you in this mess. This is also very ineffective, as you run the query each time the node template is used. As you can see, it's very confusing and hard to control fetching data in the theming layer. But how do you do it then?
There are some different ways to do things kind of things, there are even made modules for this. Now it seems you want to display a list of blog nodes based on 2 CCK date fields.
The easy non coding way:
Simply create a view, using the views module. You can select nodes of type blog and filter based and the current data and the date on the cck fields. You can choose different displays. Showing either the full node or only part of the node, list, table ect. Lastly you select an URL for the view and you're done.
The harder coding way:
Create a custom module. First you need to implement hook_menu() to create a menu item which is how you setup the URL. Doing that you assign a function that you must create for that URL. In it you put much of the above code, fetching the data with SQL, however you will also need to run that data through various theming functions that will generate the markup and lastly you return the data. This is actually quite easy to do, if you know how Drupal works. If not, it will be hard to do this properly as you will need to call a lot of functions you don't know, and implement hooks ect.
This ended up being a bit longer than I planed, but I hope it helps you out with your new Drupal site.
Edit:
It actually looks like the SQL you posted is the SQL generated from a view that looks to be working. The only flaw is that you ask for both date fields to be greater or equal to now. CCK fields can have a default value but I believe you can always edit it to whatever you like when you edit the node, unless the node form has been edited to hide the fields. Also there wouldn't be any reason to use a CCK date field for the publish date. That information is available on every node along with last edited date.
You can find a lot of good stuff at Lullabot. They have made a lot of stuff on how to use CCK and views. Some of it they sell and some of it you can get for free. In your example, the difficult part is getting the nodes you want. To do that you need to add filters. When you want to sort by any date, you need to add a date filter located in the date group. In it you can check the fields you want to use. However in your case you want to add the date filter twice one for each of the date fields, as you have different values for the fields. This is probably where your flaw is and what is giving you problems.
Just to clarify my comment, it should look something like this:
function getData(){
$sql='my sql query';
results =db_query($sql);
$return_string = '' ;
while ($data = db_fetch_array($results)) {
//Loop through data and save to $db_data
$return_string .= $db_data;
}
return $return_string;
}
It sounds like you're on the right track with calling this function from within page.tpl.php; note that you can have it display only on specific pages by conditionally invoking it for specific values of $node->nid:
<?php if ($node->nid == xxx || $node->nid == yyy) print getData() ;?>
If you're using CCK and displaying the results of your function for specific content types only, Contemplate is a good module, esp. for beginning Drupalers, that makes some of this easier.
Well, to start, you shouldn't use echo, since it will print when the code is run (e.g. at the top of the page while it's loading) rather than into the variables that the template displays at the appropriate spots in the page. (This isn't to say that echo won't ever work, but using it isn't best practice.)
What did the previous function use to output the data? (There might be a page named something like abc.tpl.php (if your function is named abc) that will help you find the appropriate variable names.
If you add the SQL strings you were using, I might be able to diagnose that issue as well.
EDIT:
Assuming, based on your earlier comment, that you are trying to format a blog node (I base this on your mentioning the lack of a node-blog.tpl.php):
Drupal's assumptions, when rendering a page, go something like this (simplified):
Load the core. Grab the content from the database. Get the taxonomy and other goodies, and make these available to the modules and themes
Then, look in all the modules to see
if they have hooks that, based on
their function name, will modify the
page. If they do, run the functions.
If they don't, leave the page alone.
Then, look in all the theme to see
if template.php have hooks that,
based on their function name, will
modify the page. If they do, run the
functions. If they don't, leave the
page alone.
Last, look at the tpl.php files and display the page using those. If there's no tpl.php file with the right file name, then load it using node.tpl.php
A good summary of all that is at http://drupal.org/node/173880
If you have no functions in template.php that look like the would modify the page, and you have no tpl.php files that match the node you're looking for, that means that all your pages are being loaded using the default template.
(This is probably why your predecessor set up the strange construction that he did. Using a function like that is a kinda hacky way to do what Drupal can do automatically through the theme functions)
So:
Go ahead and make the tpl.php file. Call it node-blog.tpl.php if your content type is a blog node, or something else. You can probably just copy the existing tpl.php files for now. Then, create a preprocess function in template.php to go along with it.
(You will need to rebuild the theme registry for Drupal to recognize the changes -- you already have the Devel module installed, so it should be easy from there. Visiting /admin/build/modules on your site will work as well.)
Then, visit http://drupal.org/node/223430 and http://drupal.org/node/337022 for some quick explanations and code snippets that will let you pass your data as a variable, that the template can then render on your pages
One Last Edit:
By any chance, does this function build a list of blog posts, and present the information in summary form (e.g. a list of pending posts)?
I ask because if so, the Views module can probably do all of this work for you. Unless the data processing in function abc() is really, really, fancy, this seems like just the sort of thing that Views was built for.
While template.php is used for overriding various theme functions it can also be used to simply store functions that are called on your templates (you can also force template.php to be available in a custom module depending on how hacky the site was done by the original developer(s)). So just because a function is in template.php does not automatically assume it is a theme override (if you can provide he actual name for the function it would help to determine if it is though).
And the reason taking your code out of the function but leaving it in template.php causes the output on every page is because template.php is included in every page. Theoretically you can put more than just functions in template.php. On a large site I worked on one of the developers broke up the functions into a couple smaller files so template.php was just 2 or 3 functions and 3 or 4 include()'s.
Knowing the actual name of the function would really help determine if this is a custom function or a theme override.
To answer a few questions you have raised:
The previous function was doing this:
function abc($node,$submitted,$node_url) {
echo $node->taxonomy['color'];
$a = explode(",",$submitted);
$b = explode("-",$a[1]);
// THIS IS THE DESCRIPTION
if(strlen($node->content['body']['#value'])>180)
{
$c = str_split($node->content['body']['#value'],180);
$d = $c[0]."...";
}
else{
$d = $node->content['body']['#value'];
}
$multiple = $node->field_mul_event[0]['view'];
$eventcode = $node->field_event_code[0]['value'];
$strdata="";
$strdata.="specific markup to output here";
return $strdata;
}
This functionjust pulled out a start and end date and a description
The sql string in my code is:
select DISTINCT node.nid AS nid, node.title AS node_title,
content_type_blog.field_date_from_value AS node_data_field_date_from_field_date_from_value,
DATE_FORMAT(content_type_blog.field_date_from_value, '%%d/%%m/%%Y') AS dateFrom,
content_type_blog.field_date_from_value2 AS node_data_field_date_from_field_date_from_value2,
content_type_blog.nid AS node_data_field_date_from_nid,
field_mul_event_value AS multiEvent,
field_event_code_value AS eventCode,
node.type AS node_type,
content_type_blog.field_event_excerpt_value AS node_data_field_date_from_field_event_excerpt_value,
image_attach.iid AS image_attach_iid,
node_images.filepath AS imagePath,
color AS catColour
FROM node
node LEFT JOIN content_type_blog content_type_blog ON node.vid = content_type_blog.vid
LEFT JOIN image_attach image_attach ON node.nid = image_attach.nid
LEFT JOIN node_images node_images ON node.nid = node_images.nid
LEFT JOIN term_node term_node ON node.nid = term_node.nid
LEFT JOIN term_data term_data ON term_node.tid = term_data.tid
WHERE node.type LIKE 'blog' AND content_type_blog.field_date_from_value >= DATE(NOW()) AND content_type_blog.field_date_from_value2 >= DATE(NOW())
ORDER BY content_type_blog.field_date_from_value ASC
As I am sure you can tell, this sql grabs all the same data (and some extra info) except data older than todays date and then orders it in date order.
I have taken a look in the theme folder and there are two tpl.php files with the same code in them:
<?php print $fields['title']->content; ?>
<?php print $fields['introduction']->content; ?>
I cannot see any custom modules as such in sites/all/modules. This is the list in there (but they all seem like inherent modules to me):
cck
date
devel
extlink
fckeditor
image
imce
menu_breadcrumb
nice_menus
node_images
pathauto
sections
swftools
token
views
wysiwyg
Excuse my ignorance - but I am learning drupal as I go along. More of a wordpress gal usually if you know what I mean. Not used to nodes/taxonomy/the drupal system and the like which is my base excuse for my lack of knowledge.
I need to find that function and determine what it does - gah!!!
Thanks everyone!
Ok had a look about using the theme developer:
Parents: theme_taxonomy_term_page < page.tpl.php
Template called:
node.tpl.php
File used:
modules/node/node.tpl.php
Candidate template files:
node-blog.tpl.php < node.tpl.php
Preprocess functions:
template_preprocess + template_preprocess_node + content_preprocess_node + nodereference_preprocess_node + views_preprocess_node
Duration: 6.84 ms
Look in here modules/node/node.tpl.php and found references to abc function
<?php print abc($node,$submitted,$node_url); ?>
Can't find node-blog.tpl.php and can't find any references to functions template_preprocess + template_preprocess_node + content_preprocess_node + nodereference_preprocess_node + views_preprocess_node
Stumped.
A very good start to see what's going on with the theme hooks and template files is the devel module. Enabling it and going to the site and enabling the "Theme Developer" module will get you a little widgety thing in the bottom left part of your pages, where you can check a box and then click on any element on the page - and it will show you what it is executing, why, and what else it could be executing.
Could be a start.

Categories