'Design modules' and making the design proces a more pleasant one with a lower learning curve where needed. My journey in getting to understand design in Drupal.

Events happening in the community are now at Drupal community events on www.drupal.org.
Anonymous's picture

Currently I am experimenting with something I dubbed 'Design modules', and I would like to contribute this idea back to the community and bounce off some ideas. Please feel free to give constructive feedback on this, and whether I am heading in the right direction. This is not to be considered a definitive write up by any means, but just one designer's journey in getting to learn how to design in Drupal, and where needed improve this process.

Short background and case study

I wanted to create a custom content type using CCK for fields. However I could not get the CCK template to do what I want. And this is a problem I run into with Drupal quite a few times. I just don't get it sometimes. Don't get me wrong, I love CCK and Drupal. It is just everytime I mix code with design I feel the sudden need to grow Einstein hair. So in the immortal words 'scratch your own itch and contribute'. Here are some of my feeble attempts for making design easier to understand in Drupal and hopefully lowering the learning curve, thus lowering the threshold for theming where needed, and making design more fun all around.

The (possible) solution

Create 'design modules'. In the admin backend use Drupal and/ or the module as usual. At the design level create a module with custom output you can place in the theme. This bypasses a few problems (and might create a few, I don't know) One is that I know can write custom queries that interact with the database and get the data I want, how I want it. Two is that I can write the code in such a way that I get exactly the HTML and CSS output I want. Third I can place the desired result straight into the theme and incorporate it in the rest of the design.

So what I did was create a module, and in this module put the following code (Please mind you this is alfa code, and still has to be improved (security wise) as far as I know and read, but I am also sometimes getting stuck in the documentation on this, more on that later.)

<?php
// $Id: customsite.module

/
* @file
* Custom functions for this site.
*/

/

* Valid permissions for this module
* @return array An array of valid permissions for the customsite module
*/
function customsite_perm() {

return array('access customsite', 'create customsite', 'administer customsite');

} // function customsite_perm

/
* Implementation of hook_block
* @param string $op one of "list", "view", "save" and "configure"
* @param integer $delta code to identify the block
* @param array $edit only for "save" operation
/


function customsite_single_publications() {

  // Be sure to include the previous piece of this function!
$page_content = '';

if ( arg(0) == 'node' && is_numeric(arg(1)) && ! arg(2) ) {
  $node = node_load(arg(1));
  $node = ($node->nid);
}
    $query = "SELECT node.nid, node.title, content_type_publications.nid, content_type_publications.field_title_publication_value, content_type_publications.field_type_publication_value, content_type_publications.field_date_publication_value, content_type_publications.field_source_value, content_type_publications.field_source_url_value, content_type_publications.field_authors_value , content_type_publications.field_isbn_value, content_type_publications.field_link_to_publication_url_value, content_type_publications.field_synopsis_value FROM {node} INNER JOIN content_type_publications ON node.nid = content_type_publications.nid WHERE node.nid = '$node'";

    $query_result =  db_query($query);

    while ($links = db_fetch_object($query_result)) {
      $page_content .=
'<h4>Title publication</h4><p>' . $links->title . '</p>'
. '<h4>Type of publication</h4><p>' . $links->field_type_publication_value . '</p>'
. '<h4>Date publication</h4><p>' . $links->field_type_publication_value . '</p>'
. '<h4>Source publication</h4><p>' . '<a title="'. $links->field_source_value .'"' . 'href="' . $links->field_bron_url_value . '">&#8578; </a>' . $links->field_source_value . '</p>'
. '<h4>Author(s)</h4><p>' . $links->field_authors_value . '</p>'
. '<h4>ISBN</h4><p>' . $links->field_isbn_value . '</p>'
. '<h4>Link to publication</h4><p>' . '<a title="Link to publication: ' . $links->title  . '"' . 'href="' . $links->field_link_to_publication_url_value . '">&#8578; </a>Link to publication</p>'
. '<h4>Synopsis</h4><p>' . $links->field_synopsis_value . '</p>'
;
    }

  // check to see if there was any content before
  // returning the page
  if ($page_content == '') {
    // no content, let the user know
    $page_content = "Enter pretty text here for no content.";

  }
  return $page_content;
}

The reason I wrote this bit of code was because I wanted the publication source and link to the publication to turn into links 'automatically'. So if you enter the name and the url of the source in the CCK fields in the admin backend then it will in this module automatically turn into a link with the title tag, the href and the name of the source. The same goes for the link to the publication. For the life of me I could not figure this out in CCK. Not to bash on CCK, I love that little module.

Working with and understanding the documentation

As usually occurs with me with some of the documentation. It sometimes just blanks out on me. I just end up sitting there looking at the forum posts, doc pages, internet searches and just not get it. In contrast I learned how to design in Joomla and WordPress in about four months each. With Drupal I am about one year on, and I still don't get too much of it. I just get lost sometimes. The terminology and the existing code is just to advanced/ complex for me to find a point which I can hook into. I can hand code a website in PHP, MySQL, HTML and CSS in no time. So why then do I get stuck in Drupal? Mind you I contribute where I can.

Well one of the reasons might be is that I am used to hand coding, so I have to learn the insides of Drupal and in applicable cases different modules. And I sometime lose a lot of time on this. Trying to find one little bit of code in the puzzle for a custom piece. That's when I came up with the idea for 'Design modules'. Just custom code the data output (query) and the design how you want for a site, and voila. Another reason is that I am sometimes finding it hard to find a proper write-up, and when I do, it can be sometimes so complex for me that I don't understand it, or I am not sure if it is safe code to use. So a good addition might be: Who reviews the code that gets put on Drupal.org? Should we review the code, and create a book section that has reviewed code?

Using existing output or hand coding

The templating system that comes with an existing module might work for you. Certainly. Some great work is available on Drupal. However with Views (another module I love) I had a similar problem, wanting to create a custom view, which I couldn't get done. It ended up not being possible, for now. So hand coding will be the option to solve it, for now, till I figure it out and can contribute it back.

Role definition: one man band or orchestra

So why should a developer/ programmer spend their time layouting their module, when instead they can work on the programming side of things. And then have a designer/ developer create 'design modules' to display the data as wished for in a website theme. Some modules already have subthemes available which you can choose. So maybe a subfolder in a existing module. That sort of thing.

Use a module or learn the code?

When posting a question to the forums often one gets, in my experience, the answer to use a module. But that doesn't help me learn code. So I have started to say more up front that I am looking for the code and/ or documentation. This way I can actually learn how it works, instead of being dependent on a third party, and more importantly not understanding the code. Not understanding the code leads, in my opinion, sometimes to not to being able to design to the maximum. So my advice to designers, is definitely learn to code (a bit) if you can. It can save you a lot of time, and will allow you to interact with programmers more easily because you can converse on the same level. It can also help a programmer help you more when he/ she has a clear idea of what you are talking about.

Oh conditional tags, conditional tags. Wherefore art thou conditional tags?

In WordPress I can use 'conditional tags' in the theme such as is_category, is_single or is_home. This decides whether or not something gets shown at a certain time. It is quite an easy system I find, and I love it. See the WordPress Codex for more info: http://codex.wordpress.org/Conditional_Tags. But in Drupal templates I am still getting confounded on this part. The whole page.tpl and node.tpl still eludes me sometimes. Or for example loading a function in a node.tpl depending on which content type is there. And I am finding it hard to find information on this.

Wrapup

Anyway, to make a long story short, all this is helping me write custom code when needed and being able to use all of Drupal's fantastic ability to build wonderful websites.

I am find that writing modules is making my life easier when designing in Drupal. I am hesitant to call them normal modules because they are geared specifically for custom design output from core/ module data. Just like you have block modules and node modules. Except 'design modules' can go anywhere. You could call them 'block design modules' for blocks, but I would be hesitant to call something a 'design node module' because the output could be used on a taxonomy page, forum page, etc. and that might lead to a unnecessary terminology. This is something which would need to be worked out.

Feedback

So what do you think are 'design modules' the way to go? And how would one best implement this in the code infrastructure?

Please see this as positive constructive feedback. That is the way it is intended. :-)

Feel free to couple back improvements to what I wrote.

I hope it helps.

Comments

I do see how this is a

imp7's picture

I do see how this is a helpful approach for a theme designer. I would also love to hear the thoughts of an experienced drupal programmer on modules of this nature as you really see none of it on drupal.org ( in relation to performance / security / best practices )

Template Suggestions?

mandclu's picture

Have you looked into template suggestions?
http://drupal.org/node/190815

From what I've gathered in your post, you should be able to achieve a great deal of what you're looking for simply by ensuring that your theme/subtheme folder has a copy of node.tpl.php and duplicating it to something like node-publication.tpl.php. Then you can go in and completely customize the display logic, and if you look in the file in the comments at the top it even lists the variables available for display logic, including $is_front, $teaser and so on.

If at that stage you don't have all the data you need you could also look at writing a preprocessing function to put more or different data in beforehand. More on preprocessor functions here:
http://drupal.org/node/223430

If you're happy with how CCK is storing and retrieving your data but you just want it presented different, my personal take would be that it's ideal to find a solution within the theme layer rather than writing a module to do the work.

Also, I should point out that hard-coding the database query as you done instead of using the database abstraction layer has some disadvantages. FIrst it's less portable in case you should ever want to move to a different kind of database, such as Postgres. More importantly, however, it precludes a lot of the extra work Drupal can do for you, for example to ensure that the current user has access to see all the nodes that are retrieved.

Thank you for your

Designer's picture

Thank you for your responses.

Have you looked into template suggestions?
http://drupal.org/node/190815

From what I've gathered in your post, you should be able to achieve a great deal of what you're looking for simply by ensuring that your theme/subtheme folder has a copy of node.tpl.php and duplicating it to something like node-publication.tpl.php.

This is one option I am looking at. On the other I want to avoid node-to-the-umptieth-power.tpl. And am looking at a OOP setup. This mainly because themes can sometimes be extensive and complicated, and I find it easier to navigate through a clear directory.

Then you can go in and completely customize the display logic, and if you look in the file in the comments at the top it even lists the variables available for display logic, including $is_front, $teaser and so on.

Are these all the display logic variables we can choose from? Maybe write a module, which will automatically fill these values. For example: $is_node, $is_term, $is_vocabulary_term, $is_front, etc. So for example enabling hooking up a if statement with being on a term page, and showing the correct piece of code automagically based on that.

It is lot easier/ quicker for me to write:

Pseudocode

if $is_term = $term
or
if $is_term = 'my_term'
then
include theme code_snippet
elseif
etc.

If at that stage you don't have all the data you need you could also look at writing a preprocessing function to put more or different data in beforehand. More on preprocessor functions here:
http://drupal.org/node/223430

NASA calling Einstein. Way over my head that page.

If you're happy with how CCK is storing and retrieving your data but you just want it presented different, my personal take would be that it's ideal to find a solution within the theme layer rather than writing a module to do the work.

From what I read, I'll have to find back the page which I lost, is that queries should not go into theme files.

The problem I'm having with CCK and Views, is that appears that the data in these theme files run cyclical. So I have to work around some kind of loop in order to show the data how I want, which leads to ugly coding, so then I opt for example for a module, to just get some pure code. But I could be wrong on this part.

Also, I should point out that hard-coding the database query as you done instead of using the database abstraction layer has some disadvantages. FIrst it's less portable in case you should ever want to move to a different kind of database, such as Postgres. More importantly, however, it precludes a lot of the extra work Drupal can do for you, for example to ensure that the current user has access to see all the nodes that are retrieved.

I will keep that in mind. If I figure out how to do that.. the less queries the better in my opinion, and if I can run one main query, and reuse that data all the better, is that what you mean? I'm getting lost in the API documentation.

Thanks surge_martin, what you

imp7's picture

Thanks surge_martin, what you are saying makes sense and I can see that writing a module like kind of shurgs off the wonderful work that has already been done for us in the theme layer. Its just that in the case I would see myself writing a module like this, would be for a very specific type of display where views over complicates things. I think that this may be easier and without knowing all the extra work drupal can do for you, in a themers perspective things like portability wont matter and ensuring the current user has access to the nodes will be very obvious through testing you should do anyway.

NASA calling Einstein. Way over my head that page.

Yeah I hear you dolphin I myself felt like a stupid monkey when looking at http://drupal.org/node/223430 as a non programmer, but not after watching dojo lesson 42 http://drupal.org/node/290431 when its explained like it is in the screencast its not that complicated at all :) Really the sql is much more confusing. Now I am dribbling at how powerful and helpful preprocess functions are.

Yes, that code has some

Garrett Albright's picture

Yes, that code has some security issues. Your db_query() call should be using a placeholder for the $node value. (And, stylistically, you should abbreviate table names; this query you have now looks like it was copy-and-pasted from something Views built.) Also, the content_type_publications table name needs curly braces too. And do you really need two nid fields? So like this instead:

<?php
$query_result
= db_query('SELECT n.nid, n.title, ctp.field_title_publication_value, ctp.field_type_publication_value, ctp.field_date_publication_value, ctp.field_source_value, ctp.field_source_url_value, ctp.field_authors_value , ctp.field_isbn_value, ctp.field_link_to_publication_url_value, ctp.field_synapsis_value FROM {node} n INNER JOIN {content_type_publications} ctp ON n.nid = ctp.nid WHERE n.nid = %d', $node->nid);
?>

Or if you're just selecting every possible column from the ctp table anyway…

<?php
$query_result
= db_query('SELECT n.nid, n.title, ctp.* FROM {node} n INNER JOIN {content_type_publications} ctp ON n.nid = ctp.nid WHERE n.nid = %d', $node->nid);
?>

(And maybe now I'm just being petty, but the English major in me wants me to tell you that you probably didn't mean to call it a synapsis instead of a synopsis. But maybe you did; I don't know.)

Also, any time you're retrieving something from the database and printing it to the screen, you should be using a filtering function - check_plain(), check_markup(), or possibly t(), depending on your intentions.

You're also entirely bypassing the theme layer, but I guess that's the entire intention of the module…? It would be better and more secure if you learned to work with it instead of around it.

I highly suggest picking up the Drupal Book and reading the relevant passages on security and the theming layer at the very least. There's also an entire separate book dedicated solely to the topic of Drupal security.

Thank you for your

design_dolphin's picture

Thank you for your reply. :-)

This topic isn't about a specific module, but about the concept in general. I appreciate you submitting code, but I am afraid if we all start submitting code in the topic than it could become a mess. From now on it might be easier/ better if we link to a specific page on drupal.org, with a short explanation why the code was added or think the code could be useful.

For example, if you have time read the post on Why doesn't this query work? Confusing documentation. It goes into a detail exploration on how to write a proper query using the database abstraction layer in Drupal. Admittedly the title could be clearer, and I can understand why you overlooked it. Still finding my way in setting up this topic. In all sincerity I do appreciate you giving constructive criticism on the idea. However, please do make sure you have the correct information at all times, or state that you are not sure if you are not when submitting information. As far as I can see your contribution is missing some things. However please feel free to correct me if I am wrong. Mind you I'm still learning myself, which is why I am making it a habit to say that I do not know all of the code, or it is subject to review. I hope it helps.

Or if you're just selecting every possible column from the ctp table anyway…

As far as I know from a security standpoint one is to always specify the fields that one is calling from a table.

Also, any time you're retrieving something from the database and printing it to the screen, you should be using a filtering function - check_plain(), check_markup(), or possibly t(), depending on your intentions.

From what I can see you forgot check_url. It might be easier to link to the relevant page which contains all the information, for example: Handle text in a secure fashion

You're also entirely bypassing the theme layer, but I guess that's the entire intention of the module…? It would be better and more secure if you learned to work with it instead of around it.

Thank you for opinion. However, I respectfully disagree. I do know how to theme in Drupal, for the most part and I still have a lot to learn, however I too often find it a tedious and ambiguous process (as stated above), hence this exploration. It makes my life as a designer easier, as well as learning to program in Drupal.

I highly suggest picking up the Drupal Book and reading the relevant passages on security and the theming layer at the very least. There's also an entire separate book dedicated solely to the topic of Drupal security.

Thank you for the suggestion. I will look into that.

Thank you for the correction on the spelling mistake. I looked over that when translating, and have corrected it. Not sure if to replace the code, once I have the module worked out, but that might be a good idea. Like I said it is not the main intention of this topic. But more a general exploration. Having said that it might be nice to have the proper code, or references to pages on drupal.org which could benefit all who would work with building these kind of design modules, but that might be in a later stage. Not sure yet on that part.

So stumbled upon a module

design_dolphin's picture

So stumbled upon a module called Contemplate which peaked my interest.

Anyway here is what I did in short:

Download and setup a virgin install of Drupal
Install and enable the CCK module
Install and enable the Contemplate module

The documentation on CCK and Contemplate I found easy to understand.

I then created a custom content type. Then created CCK fields for the custom content type. And then used Contemplate to create custom layouts using the data from the CCK fields. Really a piece of cake. Making design fun again.

Great stuff. Thanks for building these modules.