It seems as though when it comes to providing a decent download manager in Drupal, there just isn't much there. Joomla has DOCman, which is truly excellent. Drupal has... ummm... yeah. There are modules such as dbFM and WebFM, which are very nice, but they are more like an OS's file manager than what I consider a download manager to be. I guess I should explain what I consider a download manager to consist of:

These are some of my requirements. The big thing for me is to have a nice layout which uses user-friendly names and descriptions. The idea is that the general public needs to be able to know what they are getting, and filenames (usually) aren't the best way to express that.
While Drupal does not have an immediate "set-it-and-forget-it" module to do this, the beauty of Drupal is that it is quite customizeable, and can be made to do just about anything we want. In this document, I will attempt to walk through how to mimic much of DOCman's behavior in Drupal, using common modules.
The most important thing to do in order to create the download manager is to create a node and view for the download content type. This section will cover the technical aspects of the setup, and is essential to having this work. In fact, this section alone will create a working download manager, but it won't have the visual appearance of DOCman yet.
As far as getting Drupal initially installed and setup, I am going to leave that to other resources (such as http://www.drupal.org.) It isn't too hard, and there are already quite a few sites that go into this in better detail than I could. I will also assume that by now you know how to install and activate modules. If not, check the documentation at http://www.drupal.org.
Also, if following this tutorial completely screws up your website, computer, job, or life, don't blame me. I recommend doing anything like this first on a local test site. You might want to start with a fresh install, just so you don't have anything else that could possibly cause conflicts, or you may setup a local version of your live site. This has the advantage that when you are satisfied with the mod, you can upload it to the server, and be set to go.
I am writing this tutorial using Drupal 6.6, but the process should be similar for other versions.
Activate the following core modules in Drupal under Administer->Site Building->Modules:
You might also want to enable the following, depending on your needs:
With the core modules set, we need to go get some from http://www.drupal.org. By the way, I usually like to install the Nice Menus module right away, even if I don't want it available to the public. It just makes administering the site much easier to have the pop-up menu. Anyway, download and install the following modules:
Once the necessary modules are installed, it is time to setup the content type for the documents. This is how we will add files to the download manager.
Go to Administer->Content Management->Content Types and choose "Add Content Type." Enter a name for the content type (for this tutorial, I will use "Downloads" for the name, and "downloads" for the type, but you can use anything.) If desired, enter a description for the type to assist you or other users in the future.
Expand the "Submission form settings" section, and change the body field label to something more intuitive, such as "Description of download." You might also fill in the submission guidelines if you are going to allow others to use this.
I typically don't want every download to be published on the front page, but that's just me. There's certainly nothing wrong with it, and in many cases, it is desireable. If you don't want the download to be promoted to the front page, uncheck the "Promoted to front page" checkbox under "Workflow settings."
Adjust the comment settings, if desired. I just leave them as default. When finished, save the content type.
Taxonomy allows us to categorize our content by specifying a number of tags, which can then be used to search for nodes. This is also how we group the files. Go to Administer->Content Management->Taxonomy. Select "Add Vocabulary" and fill in the fields (something like "Downloads" for the vocabulary name, enter a suitable description and help text to inform users what the tags are, and check the "Downloads" document type. For the settings, I would check "Tags," which allows the taxonomy terms to be created when the user submits the file. This could could lead to confusion if different users misspell the tags or use tags that don't fit, but it is an easy way to create the terminology. "Multiple select" allows each file to have multiple tags (this is already true if you selected "Tags" but go ahead and check it anyway.) Check "Required" if you want each file to be associated with at least one taxonomy term. Since this is how we will categorize the content, I recommend it.
If you want an image associated with the taxonomy terms, and have installed the Taxonomy Image module, go to Administer->Site Configuration->Taxonomy Image. Adjust the settings to your needs and tastes, but I'd recommend checking the "Add wrapper <div> tag" under Advanced. You may want to set the resizing constraints to keep images at a reasonable size (use the "not greater than" option.) You don't need to check the content type unless you want to use the image for every file. I leave it unchecked...
Select "Manage Fields" for the download content type we just created. Near the bottom, under the "New Field" section, enter "File Name" in the label box, and filename (field_filename) in the "Field Name" box. Select "File" for the field type, and "File Upload" for the widget type. Save the field.
You can now configure the file name field. In the "Help Text" box, enter a description, such as "Select a file to upload." If you want to restrict what file types may be uploaded, enter the appropriate extensions under "Permitted upload file extensions" or leave it blank to allow all files. Also, if you want to restrict the file sizes for upload, or total size of attachments per now, enter the values in the appropriate fields. You may also specify a location within Drupal's files directory for the download files. This isn't necessary, but I create a path for this type to help keep things organized.
Since a download manager isn't much use without downloads, check the "required" checkbox. You can specify how many files may be attached to the node, but since I am creating a download manager where each file has it's own node, I leave this at 1.
Make sure the default list value is "listed" and is "enforce default." Disable the description field. Save the settings.
If you want to have an image associated with each file (something like the screenshots used with files at http://www.sourceforge.net,) you need to add an image field similar to the file field added above. Enter "Preview Image" in the label, and "previewimage" in the field name. Select "Image" for both the type and form element, and save it. This will open the configuration page for the image field (or we can click the "configure" link.) Enter some help text to describe the field, and it would probably be a good idea to specify a maximum resolution (something like 100x100.) You might want to specify a file path for the images, and maybe change some of the other settings, but the defaults are alright.
Click the "Display Fields" link at the top. For the preview image, and set the teaser to "Image linked to node" and full node to "Image." Save.
You should now be back at the "Manage Fields" page, and the newly created "File Name" field will be listed with the default fields. You can reorder these to suit your tastes. I like to have the following order:
Once these settings are to your liking, click save.
Assuming we want to have the download manager accessible from the menu, we need to setup a view for the content type. Go to Administer->Site Building->Views, and click "Add" at the top of the page. Enter a name (ie. "downloads") and (optionally) a description ("Collection of files available for download") and a tag ("downloads") for this view. Leave the type as "Node" and click "Next."
We now have a fairly complicated looking page. Don't despair, we'll get through this.
On the left, under "Defaults," there is a drop-down box with some view displays. Select "Page" and click "Add Display." Repeat this for the block display type. (Note: The block display is optional, but if you wanted, say, a sidebar that shows the most recent download files, you'll need this.)
Select "Defaults" again. Under "Basic Settings", change the title to "Downloads" or something more descriptive than the default. You change the values by clicking the link, then editing the fields that appear at the bottom of the page.
We now need to add some things to different groups. Do this by clicking the "+" box in the appropriate group.
Under "Sort Criteria," add "Node: Post Date" by clicking the "+", selecting the "Node" group, then checking the "Post Date" checkbox. Click "Add," then set the sort order and granularity (I use descending, with second granularity.) Click "Update" to finish.
Under "Filters," add "Node: Type" and "Node: Published." Set "published" to true, so only those download files that have been published will be displayed, and leave it unexposed. Make the type "Is one of" and "Download" (or whatever you named the content type.)
Now we add the fields we want displayed in the node. This process is similar to the above, and you can add any fields you wish, but I'll just explain what I have.
Save the settings.
Click "Page" in the left column to bring up the page settings.
Under "Page Settings", set the path to "downloads" so that you can access the downloads page by going to http://sitename.com/downloads.
Save the settings.
Set the menu to "Normal menu entry" and "Downloads" as the title and select which menu to add it to. This will add a "Downloads" item to the menu, which will basically list all items, like a blog. This is fine in some cases (for instance, a most recently added list) but not really categorized like we'd want. Read option 2 for a nicer solution.
Save the settings.
Typically, we'd like to have our files organized by the taxonomy terms associated with them. This is quite simple to do by using the "Taxonomy List" module. Basically, all you need to do is create a new menu item (Administer->Site Building->Menus-><name_of_menu>) and click "Add Item." Enter a title, which will appear on the menu, and in the path field, enter "taxonomy/vocabulary/<vid>," where <vid> is the id of the vocabulary ("Downloads") that we want to list. In order to find the vocabulary id, go to Administer->Content Management->Taxonomy, and hover over the "edit vocabulary" link for the vocabulary we a looking for. Notice the address of the link ends with a number (something like ..../taxonomy/edit/vocabulary/1, where 1 is the vocabulary id.) You may set any of the other options for the menu (description, parent, etc.) that you like and save it. Now when you click the menu item, you are taken to a page that has the taxonomy terms for the download files. Click a term, and you have the files in that category.
You may want to configure the taxonomy list a bit. Go to Administer->Site Configuration->Taxonomy List. I set it to display 1 term per row, but that's up to you. I do recommend checking the "Add edit term link" so you can edit the term's description when logged in as an administrator. The reason for this is that we are letting users define new terms when a file is uploaded. These new terms won't have a description (which is nice to have for the category) and by having the edit link here, it is easier to modify through casual browsing.
Save the settings.
Under "Block Settings," change the "admin" to give the block a description name, such as "DownloadBlock."
Save the settings.
At this point, you should have a menu item for your newly created downloads view. However, if you click on it, you will see the "Downloads" title, and nothing else. Let's go ahead and add some sample content.
Go to Create content->Download. Enter a title for the download, and give it a description. Under "File Name," browse for the file you want to add, and upload it.
Save the new entry.
Now, if you go to the "Downloads" link from the menu, you will have the node for the file you just added. At this point, it doesn't look too bad, but we can do more with the appearance to make it look similar to DOCman. If that's something you're interested in, keep on reading.
It would be a nice feature to allow the user to sort the elements in the manager. The default style of showing the most recent addition is nice, but what if the user is looking for something older? Or what if they know the name of it, and would like the nodes sorted in alphabetical order?
Go to Administer->Site Building->Views. Locate the 'taxonomy_term' view, and if it isn't already enabled, click the 'enable' link on the right. This will be the default view for the taxonomy terms. By default, it will sort the terms by posted date, with the most recent first. If you wanted to change the default sort method, or if you wanted to filter it so only certain nodes were displayed, you could edit this view to do so. However, for our purposes, the default settings are fine.
The first thing we will do is to create the view to sort with the newest entries first. Since this is the default behavior, it is a simple task. However, as we need to be able to change the sort order, we should have a way to set it back to the default, so let's go.
Go to the views list (Administer->Site Building->Views) and click the 'clone' link next to 'taxonomy_term'. This will make a new view, which is initially the same as 'taxonomy_term'. You will be prompted to specify some information about the new view. I recommend changing the name to 'taxonomy_term_newest' and changing the view tag to 'newest'. You may want to change the description as well. Click the 'next' button to create the view and begin editing it. At this point, the view will work as we'd like, but we need to add a tab so that users may set the sort order to 'newest'. Click on the 'Page' tab, then under 'Page settings', change the path to taxonomy/term/%/newest. The menu will currently be set to 'No menu', so click that to modify it. Select 'Menu tab' for the type, enter 'Newest' for the title, and give it a description if you like (i.e. Sort the items from newest to oldest). The weight isn't too critical, unless you want to have the sort tabs in a specific order. The lower the weight, the further to the left the tab will be. For example, I will use the order of Newest | Oldest | Alphabetical (ascending) | Alphabetical (descending), and assign weights of 0, 1, 2, and 3, respectively. Feel free to use whatever weights you'd like. Finally, click 'Update' then 'Save' to save the view.
Sorting from the oldest to the newest will require another view, similar to the one we just created, but with a different sort order. We could clone either the base view (taxonomy_terms) or the one we just created (taxonomy_terms_newest). Let's clone the one we just made.
If we are still on the screen to edit the 'taxonomy_terms_newest' view, click the 'List' link at the top. Otherwise, go to Administer->Site Building->Views to get the list of views. Locate 'taxonomy_terms_newest' and click the 'Clone' link. Change the name to 'taxonomy_terms_oldest', and change the tag to oldest. Click 'Next' to begin editing the new view.
On the 'Default' tab, change the sort criteria of 'Node: Post Date' from descending to ascending (remember to 'Update' then 'Save'.) Then click the 'Page' tab. Change the path to 'taxonomy/term/%/oldest' and change the menu so the tab title is 'Oldest' and give it an appropriate description and weight. Remember that we are modifying a clone of 'taxonomy_terms_newest'. If we cloned the base view (taxonomy_terms), the menu would need to be created by setting the type to 'Menu tab', as described above. Update and save the view.
It is also a good idea to be able to sort the items by their title, both ascending and descending. Create a clone of 'taxonomy_terms_oldest', changing the name to 'taxonomy_terms_alpha_ascending' and the tag to 'alphabetical ascending'. Click 'Next' and remove the 'Post date' from the sort criteria (you can do this by clicking it to edit, then click the 'Remove' button.) Click the '+' by the sort criteria, and add 'Node: Title', leaving the order in ascending. Update and save the view.
Click the 'Page' tab, and as described above, change the path to 'taxonomy/term/%/alpha-ascend', and set the menu tab title to 'Alphabetical (ascending)' (updating the description and weight if desired.) Update and save.
Finally, clone 'taxonomy_terms_alpha_ascending' to 'taxonomy_terms_alpha_descending'. Change the sort order of 'Node: Title' to descending, change the path to 'taxonomy/term/%/alpha-descend', and change the menu tab title to 'Alphabetical (descending)'. Change the description and weight of the menu tab, if desired, then update and save the view.
Go to your download manager. The terms are listed alphabetically (this is done by the Taxonomy_List module.) Find a term that has more than one entry, and click on that. This will show all downloads in that category, sorted from newest to oldest. You should now see tabs at the top to change the sort order (Newest, Oldest, Alphabetical (ascending), Alphabetical (descending)). Try clicking on the tabs and see if the sort order changes.
If you've been going in order, the "Downloads" node is up and essentially working. It just doesn't look like you might expect it to just yet. This next section will delve into how to theme the downloads, allowing you to essentially duplicate the DOCman appearance.
Since we want the download nodes to have their own styling, we will need to make some changes to the template files to allow specific templates for a view.
By default, any styling we try to perform on the download nodes will affect all other nodes as well. This probably isn't what we had in mind, so let's correct that.
Note: In this tutorial, I am using the standard Garland theme, but the process should be the same for others.
First we need tell the template engine to look for the right file when it is rendering the nodes. Inside of your template directory, open the "template.php" file. Look for the phptemplate_preprocess_page function (around line 55) and change the entire function body from
function phptemplate_preprocess_page(&$vars) {
$vars['tabs2'] = menu_secondary_local_tasks();
// Hook into color.module
if (module_exists('color')) {
_color_page_alter($vars);
}
}
to
function phptemplate_preprocess_page(&$variables) {
if ($node = menu_get_object()) {
$variables['node'] = $node;
$suggestions = array();
$template_filename = 'page';
$template_filename = $template_filename . '-' . $variables['node']->type;
$suggestions[] = $template_filename;
$variables['template_files'] = $suggestions;
}
}
(actually, I just comment out the old function. You know, in case something goes wrong.)
Save and close "template.php."
I'm not actually sure this is necessary. If the attached file is not displaying in the node, add the following code to the end of node.tpl.php (just before the last </div> tag.)
<?php if ($page == 0) { // dont list them in full node view
if ($node->links['upload_attachments']['title']){ // anyone know a cleaner way of checking wether there are files uploaded AND listable?
print ("<B>".$node->links['upload_attachments']['title'].":</B>"); // Printing how many there are (this is what gets printed out in your "links" <div>)
print("<UL>");
foreach($node->files as $file){
if ($file->list == 1){ // check wether the files are listable in each case so that we don't print "unlistable" files
print ("<LI><A HREF=\"".$file->filepath."\">".$file->description."</A>"); //Printing the description of each file linking to it
}
}
print ("</UL>");
}
}
?>
We need to specify a custom template for download pages. Make a copy of the template file "page.tpl.php" and rename it to "page-<node_type>.tpl.php," where <node-type> is the name we gave to the node type when we created the content type. In our case, we would name the file page-download.tpl.php.
Open the new file in a text editor. Around line 69 (just after the mission) add a new line and add
<div id="downloads-page">
I close the div after the rss icon is displayed (but you might want to enclose more/less within the div) by adding
</div>
around line 80. This will let us theme the entire page that the node appears in, from buttons that appear at the top of the page when a download node is displayed to the footer.
Just as we copied page.tpl.php to page-downloads.tpl.php, we need to do the same for the node.tpl.php file. Actually, the modification is very minor and easy to miss. In the first div, change the name of the class from "node" to "downloads-node". In other words, change the line from
<div id="node-<?php print $node->nid; ?>" class="node<?php if ($sticky) { print ' sticky'; } ?><?php if (!$status) { print ' node-unpublished'; } ?>">
to
<div id="node-<?php print $node->nid; ?>" class="downloads-node downloads-node-<?php print $zebra; ?><?php if ($sticky) { print ' sticky'; } ?><?php if (!$status) { print ' node-unpublished'; } ?>">
This will let us theme the body of the node. Note the
downloads-node-<?php print $zebra; ?>
in the modified line. This will allow you to alternate the background colors of even/odd nodes if you'd like.
We are coming along. So far, we can theme the download nodes as we like, but the layout isn't quite how I'd want it. We need to create a new template file named views-view-fields--<view_tag_name>.tpl.php, or views-view-fields--downloads.tpl.php. Note that I changed the name for the view tag to "downloads" as opposed to the singular "download" that we used for the node type. This isn't necessary, and you may keep them consistent. This file is actually a copy of views-view-fields.tpl.php, which is located in the modules/views/theme directory, but I have completely changed the structure. You may modify it to suit your needs/wants/desires.
Inside of the views-view-fields--downloads.tpl.php file, paste the following:
<?php
// $Id: views-view-fields.tpl.php,v 1.6 2008/09/24 22:48:21 merlinofchaos Exp $
/**
* @file views-view-fields.tpl.php
* Default simple view template to all the fields as a row.
*
* - $view: The view in use.
* - $fields: an array of $field objects. Each one contains:
* - $field->content: The output of the field.
* - $field->raw: The raw data for the field, if it exists. This is NOT output safe.
* - $field->class: The safe class id to use.
* - $field->handler: The Views field handler object controlling this field. Do not use
* var_export to dump this object, as it can't handle the recursion.
* - $field->inline: Whether or not the field should be inline.
* - $field->inline_html: either div or span based on the above flag.
* - $field->separator: an optional separator that may appear before a field.
* - $row: The raw result object from the query, with all data it fetched.
*
* @ingroup views_templates
*/
?>
<div id="download-view">
<div id="download-titlebar">
<span class="download-date">
<?php print $fields['changed']->content; ?>
</span>
<div class="download-title">
<?php print $fields['title']->content; ?>
</div>
</div>
<div id="download-body">
Originally posted on <?php print $fields['created']->content; ?>
<div class="download-description">
<?php print $fields['body']->content; ?>
</div>
<div class="download-filename">
<?php print $fields['field_filename_fid']->content; ?>
</div>
<div class="download-comments">
Comment count: <?php print $fields['comment_count']->content; ?>
</div>
<div class="download-tags">
Tags: <?php print $fields['tid']->content; ?>
</div>
</div>
</div>
We can now apply css styling to control the layout of the fields in the node, but first we have one more file to modify.
Create another file named views-view-unformatted--downloads.tpl.php, or better yet, copy modules/views/theme/views-view-unformatted.tpl.php and rename it. All we need to do is add the line
<?php print $classes['changed']; ?>
after the comment header, but before any actual code.
All that's left to do now is to create CSS styles to control to look of the download nodes. This is where a browser add-on, such as "Web Developer" for Firefox comes in quite handy.
Well, that should help to have something similar to DOCman in Drupal using common modules. It took us a little while to get to this point, and it isn't quite as powerful, but it does the job nicely.
You don't have to implement your download manager in the same way as I described. Feel free to add/remove fields from the nodes, use a different layout, etc. The possibilities are endless!
--Chad