What this module does

The TARDIS module creates chronological lists of recently added nodes, similar to monthly archives found in blog engines. It's not named "monthly archive" for 2 reasons:

  • I have plans to expand its functionality to include weekly and bi-weekly records.
  • the word "archive" is ambiguous - it could mean both chronological archives and the ability to create compressed files.

This module has some features I already worked on, as well as some others I'm planning to add, such as integration with Date, Token, Entity etc.

This module is based on Monthly archive by node type except that Monthly archive is for Drupal 6 (the code I wrote uses the database abstraction layer in D7) and my module's name is not restrictive to months.

The name TARDIS derives from the time machine in Dr. Who, which I found to be short, catchy, appropriate and (why not?) geeky.

Project page

TARDIS

Git repository

git clone http://git.drupal.org/sandbox/luco/1939164.git tardis

Version

Drupal 7 only.

Review bonus

Haven't gotten around to it yet Here's some reviews:

CommentFileSizeAuthor
#17 tardis-js_behaviors-1942536-17.patch1.71 KB20th
#15 tardis.zip13.29 KBluco

Comments

ycshen’s picture

Status: Needs review » Needs work

please remove the master branch.

luco’s picture

@ycshen will do.

but will that erase older versions of my code? I read that it's important for reviewers to investigate my coding style.

luco’s picture

Status: Needs work » Needs review

master branch removed.

luco’s picture

Issue summary: View changes

something went wrong with the body of my original post.

luco’s picture

Issue tags: +PAreview: review bonus

(I had put the issue description in this comment by mistake. sorry.)

Samuel Joos’s picture

Hi Luciano,

First of all nice work! Your code is looking good and well documented. TARDIS would be much more interesting if it implemented views though. I installed the module and everything seems to work as aspected. One thing that I did noticed is that it doesn't show the current month in the list. You do get the results when you view 2013 but that's the full list of 2013 of course. Maybe add a checkbox in your admin settings for it? (Could be overkill though)

Gr,
Samuel

luco’s picture

@Samuel Joos: thanks for the input, I appreciate it!

sure enough, I ran code sniffer because I didn't want to upset reviewers ;)

although TARDIS doesn't implement Views (yet!) I created a "custom link" field in which you can specify the path to your view and it'll link there. so instead of linking to the TARDIS page, it points to example.com/your/view (make sure you create a view that accepts arguments in the form of YYYY/MM though).

there's a Roadmap in the project page (Views integration is there), and I'm already bumping up the first request - Entity integration. I'll try to be as democratic as possible once people start chipping in their ideas, but the truth is I'm writing code as I learn...

as for the current month, it's by design. I had the idea to show past nodes, so it begins with the past month, but your mindset is more accurate. I'll make this change once I got to review other folks' modules - there's that too ;)

cheers,
Luciano

luco’s picture

Issue summary: View changes

Added my participation in the Review Bonus program.

sd46’s picture

Status: Needs review » Needs work

Hi Luciano,

Code looks good, and the comments have been nice and clear. I have picked up a couple of things while testing your module:

In the _tardis_query_page() function you forget to check if the $tardis_query_month variable has gone over 12, so for the month December you get no node ids returned by the query as the max date becomes "2012-13-01" which when passed through strtotime() returns an empty string. Strangely enough the database query is still valid although its searching between a timestamp and an empty string, but it doesn't return the expected node ids.

As a suggestion you could use PHPs DateTime and DateInterval classes, this would stop you having to worry about checking if the month has gone over 12 or under 1 (Note: DateInterval is only supported in the version of PHP recommended for Drupal 7 not the minimum required version in the system requirements).
Alternatively you could use:

strtotime('+1 month', $timestamp);



Another minor note, you could replace lines 367 and 368:

$q = $_GET['q'];
$q = explode('/', $q);

with

$q = arg();

This should do exactly the same, but with fewer lines and some caching.



One final thing if you go to the recent/nodes page directly without specifying a year or month in the url you get the following error message:

Notice: Undefined offset: 0 in _tardis_query_page() (line 128 of /home/simon/eclipse/sandbox7/sites/all/modules/custom/tardis/includes/tardis.page.inc).

I realise you can't get to this page via the links in the block, but it's probably worth fixing the error anyway.



Hope some of this is helpful to you.

luco’s picture

Status: Needs work » Needs review

@Samuel Joos,

I worked on your solution and found a bug in my module that I had neglected. guess this means I owe you one! ;) I'll upload a newer version later on, so you can test this new feature tomorrow. thanks for the input.

please note: before you update, uninstall the module using the current version, then download the new version and install it. that's because I've changed a few variables around.

you'll notice that node types and show nodes from the current month both have been moved to a "general settings" area, because those settings affect both the block and the page.

so give it a try and let me know if you run into any errors, ok?

cheers

luco’s picture

Status: Needs review » Needs work

@FlakMonkey46,

sorry! I was replying at the same time as you and accidentally caused it to go back to "needs review". what are the odds, huh? ;)

anyway, I'll work on your input. thank you!

luco’s picture

Status: Needs work » Needs review

@FlakMonkey46,

I ended up solving the bug you mentioned while addressing the suggestion from Samuel Joos. also included a call to arg() following your suggestion. I'm unable to add DateTime and DateInterval classes yet, but I'll study those in the future.

and the Notice: Undefined offset bit has been corrected already; I think you grabbed an earlier version of my code.

thanks for the remarks! :)

changing back to needs review...

20th’s picture

luco,

First of all, you did a really nice job! I can see that you try to follow Drupal guidelines as close as possible and use its API correctly. It is nice to see that did not disregard the security too - the code calls filter_xss() when it should, and SQL-queries have node_access tag added to them. Files and directories are organized in a logical way as well. So, overall this module has a good structure and its code is easy to understand (except for the _tardis_query_block() function, it has some real dark magic inside).

However, did you take a look at the Archive and Views modules before writing your own? The thing is, Views provide a default view that is called Archive. It provides basically the same functionality as the TARDIS. It is enough to override one or two templates to style that view just like the block provided by TARDIS. Plus, you get all the power of Views. Personally, if I ever need to create an archive or calendar, I will always go for Views.

Do not get me wrong, I am not saying that you module is not useful - it is; it does one thing and does it well. I am just worried that its niche is too small and it will be impossible to compete with Views.

Also, few things caught my eye:

theme/tardis-month.tpl.php and theme/tardis-year.tpl.php
I think it is an overkill to create a template that does nothing but call l(). You can easily replace these templates with theme_* functions, and this will make page generation just slightly faster.
js/tardis.js
Do not use the $(function () { ... }) call to initialize your script. You should always use Drupal behaviors.
_tardis_query_block() function
As I have already said, this function looks scary. Even though it is extensively commented, I cannot figure out what exactly is going on there. Perhaps, you could find a way to split it into several smaller functions.
tardis.module, lines 53-55
The title of this page can be changed by user through the admin interface. Titles of menu items are run through the t() function by default. So what we have here is that user-generated strings are being translated and saved into database. One of Drupal best practices prohibit translation of user-generated strings in this fashion.

Once again, great job! Keep exploring Drupal, write such code and take a look at Drupal Issue Queue. I am sure that you can become a great contributor to Drupal.

sd46’s picture

Hi luco,

Are you definitely pushing all of your code, I just cloned the latest copy of the module and the change adding $q = arg() is there but there doesn't appear to be a fix for the bug and now the TARDIS block isn't showing any links...

On a side note in the _tardis_query_block() function a couple of your if statements are formatted like:

  if ($condition) {
    // Do something.
  } else {
    // Do something else.
  }

they should be formatted the same way as in the rest of your module with the else on a new line.

  if ($condition) {
    // Do something.
  }
  else {
    // Do something else.
  }
luco’s picture

hi @20th,

thanks for the detailed review! yes, TARDIS is similar, but it's different in ways that matter. I thought the Archive module was long since abandoned, so I didn't even consider using it(*). also, it differs from the TARDIS in that it (Archive) shows a calendar that links directly to nodes.

the TARDIS aims at creating blog-archive-like functionality, and in the future it will encompass week (and fortnight) listings of nodes.

I have heard of Views and Date, hehehe. but what motivated me to start writing the TARDIS is that you can't list a view with arguments like YYYY/MM for date fields. also, you can't build a list of links to years and months without PHP code (**). I mean, come on! Wordpress does it, so how hard could it be? ;)

this functionality has never been very well implemented for Drupal; that is why Date and Views integration are in the TARDIS Roadmap. because I will do it. I saw the future, you know. (no flying cars yet, sorry.)

TBPH, at first I thought I'd write a simple Views style plugin and be done with it. I had (some) working knowledge of how to write a module, but it turned out that writing said code was harder than I thought. so I looked everywhere for a tutorial on how to create a Views style plugin and found Drupalize.me's videos.

They have a series on the basics of writing a module and, out of sheer curiosity, I watched it. it blew my mind: I knew nothing. so I decided I'd take the longer road, one in which I'd learn a great deal more, and here I am.

phew.

but yeah, you can simply set up the block and link it to your view, and it'll work. meanwhile, I'm learning how to integrate with Views, Date, Token, Display Suite etc. etc. etc. all the while giving redshirts like me a working solution that doesn't involve pulling their hair out.

as for the things that caught your eye:

  • theme/tardis-month.tpl.php and theme/tardis-year.tpl.php: those are there to foster the noobs. initially I considered theme_* functions, but I decided it wasn't easy enough for the end user.
  • js/tardis.js: I seriously thought I were following Drupal guidelines. I'll get right on that!
  • _tardis_query_block() function: yeah, I have already gone over my code looking for stuff that could be, err, functionised - but I'll give it another look. granted, this function is complex, but that's working with dates right there.
  • tardis.module, lines 53-55: this is weird... I used to have this run through t(), but now it looks like this: $tardis_page_title = filter_xss(variable_get('tardis_page_title', 'Recent nodes')); is this the code you saw? the idea here is that the page title should be customisable in several languages (I have seen people install i18n just so they could change strings in Drupal).

anyway, thanks for the attention. I appreciate it. I'll get this fixed and come back.
____________________________________

(*) mind you, I've been looking for such a solution a little after I joined Drupal. check out how old is this thread.
(**) here's an example, using views, in one of my own projects: http://shieldsaas.com/blog. it took me quite a while to write. if you look closely, years and months get jumbled in the same views row, which is why I can't format it as a UL. and, structurally, it should have been a UL.

luco’s picture

hi @FlakMonkey46, I tested the code on my webhost and at home before pushing it - but I'll download a fresh copy of the TARDIS and check. thanks!

edit: I should have ran it again through the automated review. I'll remember to do it on the next commit.

luco’s picture

StatusFileSize
new13.29 KB

@FlakMonkey46, I erased all local files and downloaded the latest version of each one from my sandbox. it's working.

please check line 128 of tardis.page.inc: it should read:
if (count($tardis_query_arg) == 1 && $tardis_query_arg[0] != '') {

if not, please use the attached file. also, maybe clearing your cache could help. if that's the code you're seeing and you still get this bug, please provide me with steps to reproduce the issue.

thanks for the support!

luco’s picture

@20th,

the link you posted advised me to replace

$(document).ready(function(){
  // do some fancy stuff
});

with

Drupal.behaviors.myModuleBehavior = function (context) {
  //do some fancy stuff
};

but the TARDIS js is more like:

(function($){
  $(function(){
    // Time travel awesomeness
  })
})(jQuery);

and I couldn't exactly make it work otherwise. could you please link me to a more detailed article? thanks in advance.

cheers

20th’s picture

Status: Needs review » Needs work
StatusFileSize
new1.71 KB

Well, basically you do this...

20th’s picture

I think you misunderstood what I said about translating the tardis_page_title variable. Take a look:

  1. You define menu item like this:
          $tardis_page_title = filter_xss(variable_get('tardis_page_title', 'Recent nodes'));
          $items[$tardis_page_address] = array(
            'title' => $tardis_page_title,
            'description' => 'View past nodes',
            'page callback' => 'tardis_page',
            'access arguments' => array('view TARDIS page'),
            'type' => MENU_CALLBACK,
            'file' => 'includes/tardis.page.inc',
          );
        
  2. When menu is generated, this menu item is processed and default keys are added to it.
  3. So this menu items starts to look like this:
          $tardis_page_title = filter_xss(variable_get('tardis_page_title', 'Recent nodes'));
          $items[$tardis_page_address] = array(
            'title' => $tardis_page_title,
            'title callback' => 't', // <== this is default
            'description' => 'View past nodes',
            'page callback' => 'tardis_page',
            /* ... other stuff ... */
          );
        
  4. Finally, when a user visits the tardis page, an equivalent of the following code is executed:
          $tardis_page_title = filter_xss(variable_get('tardis_page_title', 'Recent nodes'));
          drupal_set_title(t($tardis_page_title));
                        // ^---- notice a call to t() here
        

    And since the value of the tardis_page_title variable is controlled by a user, we can simplify it to:

          drupal_set_title(t($user_defined_text));
        

Now, take a look at this article. While it is almost two years old, as far as I know, Drupal standards of text translation have not yet changed.

Do you see what I am trying to say here? :)

luco’s picture

Status: Needs work » Needs review

cool! I'll make sure to include these contributions (page title variable, jQuery call).

the TARDIS is looking so much more awesome with all the input I'm getting. hope I can help other redshirts like me in the near future. I'm seriously thinking about sticking around even after my wooden sandbox project becomes a real module.

cheers

luco’s picture

Status: Needs review » Needs work
luco’s picture

hi @20th,

I think I understand what you mean. here's the code I'll be committing later on:

  $tardis_page_title = variable_get('tardis_page_title', 'Recent nodes');
  $items[$tardis_page_address] = array(
    'title' => $tardis_page_title,
    'title callback' => 'filter_xss', // <-- replacing default call to t() function
    ...
  );

is that ok?

please note: I've checked earlier versions of my code and there was never a call to t() inside drupal_set_title().

cheers,
Luciano

edit: your patch worked just fine. I'll commit that change as well. thanks!

luco’s picture

Issue summary: View changes

Added more reviews for the same modules.

luco’s picture

Status: Needs work » Needs review

ok, updated code according to latest input. changing to needs review. standing by.

luco’s picture

Issue summary: View changes

Added a new review.

luco’s picture

Issue summary: View changes

Added a review.

klausi’s picture

Assigned: Unassigned » cweagans
Status: Needs review » Reviewed & tested by the community
Issue tags: -PAreview: review bonus

manual review:

  1. "variable_get('tardis_block_title', 'Recent nodes'(": all user facing text must run through t() for translation.
  2. "form_set_error('tardis_block_stop_year', 'Please input a valid year with four digits.');": same here - please check all your static strings that they run through t().
  3. tardis_page_settings_validate(): why do you remind people to clear the cache, you could clear the cache yourself in a submit callback?

But otherwise looks RTBC to me. Removing review bonus tag, you can add it again if you have done another 3 reviews of other projects.

Assigning to cweagans as he might have time to take a final look at this.

luco’s picture

thank you, klausi! I'll look into this and get back to you.

I thought about clearing the cache automatically, but I didn't want to bypass site admins' authority. nevertheless, I'll leave a warning telling them which settings force a cache cleanup.

cheers

luco’s picture

ok, I did a re-check of all possible strings that should be passed through t().

some strings just have month names and years in them - but month names already go through t(), in _tardis_month_names().

as for the cache, I looked everywhere for instructions on how to clear the menu cache on form submit, but the best I could come up with is:

<?php

/**
 * Checks whether page title or address have changed, and flushes the cache.
 */
function tardis_page_settings_submit($form, &$form_state) {
  $tardis_page_address = $form_state['values']['tardis_page_address'];
  $tardis_page_title = $form_state['values']['tardis_page_title'];

  // Did the page address or title change? If so, we need to rebuild the menu.
  if ($tardis_page_address != variable_get('tardis_page_address') || $tardis_page_title != variable_get('tardis_page_title')) {
    if (cache_clear_all('menu', 'cache', TRUE)) {
        drupal_set_message(t('Caches cleared.'));
    }
  }
}

?>

which doesn't work. I'd appreciate help on this matter - otherwise I believe I should keep that message telling users to clear their cache, with a link.

(in fact I remember trying to get this to work right at the beginning, but no joy.)

btw how can I put line breaks on git comments? I've tried \n but it didn't create new lines as expected.

cheers

cweagans’s picture

@luco, if you don't use the -m flag for "git commit", an editor should be opened so that you can type in a multi-line commit message.

I will do a review tomorrow morning and hopefully turn on your unrestricted git access :)

luco’s picture

@cweagans,

oh ok! I'm still tiptoeing around Git, you know. trying not to bust anything on Drupal.org... hehehe.

fingers crossed here.

expect me after my review. I rather enjoyed the process; think I'll stick around.

cheers

luco’s picture

Issue summary: View changes

wrong Git link. oops.
added another review.

luco’s picture

Issue tags: +PAreview: review bonus

added reviews.

cweagans’s picture

Status: Reviewed & tested by the community » Fixed

Thanks for your contribution, luco! Sorry for the delay in getting back to this - had a pretty crazy Monday :)

I updated your account to let you promote this to a full project and also create new projects as either a sandbox or a "full" project.

Here are some recommended readings to help with excellent maintainership:

You can find lots more contributors chatting on IRC in #drupal-contribute. So, come hang out and get involved!

Thanks, also, for your patience with the review process. Anyone is welcome to participate in the review process. Please consider reviewing other projects that are pending review. I encourage you to learn more about that process and join the group of reviewers.

Thanks to the dedicated reviewer(s) as well.

luco’s picture

woohoo! we did it!

[insert Freddie Mercury pose here]

thank you, everyone! :D

and thank you, cweagans. we all got our crazy Mondays... ;)

Automatically closed -- issue fixed for 2 weeks with no activity.

Anonymous’s picture

Issue summary: View changes

Added review links.