There are a couple of ways that uploaded files can be linked to in concrete5. Often, it's simply a case of creating links to files in a content block - it's quick and easy and you're free to format the links however you wish.

Note: this blog post applies to concrete5 version 5.5.x. In version 5.6 and above, there is a slightly different way required to override block controller files.

The other main way is to add a File block to a page. By default, the File block simply outputs a single link to the file you pick and the title you enter. It's simple... but it's a bit boring and not really that useful when this can be done easily in the content block anyway.

But unlike the content block, the File block is perfectly set up for customising in terms of output and fetching additional details about a file. Using a block also makes it easier to drag and drop files around a page and to change how files are presented sitewide. The file manager in concrete5 is also well designed to manage meta data about files such as description and tags.

So here are a few overrides to the File block to make it more useful in terms of output - to make it also display the file type and size, an icon, the description for the file and other details if you wish. I will go through the code here as a bit of a tutorial, but if all you care about is the end result, just place the folder from the zip at the end of this post into the /blocks folder of your concrete5 website.

Defaulting to the name/title of the file

The default behaviour of the File block forces you to enter a link title. I personally think this simply adds more work as more often than not the filename/title is perfectly suitable as the link.

The File block is actually already set up to use the file's title (which defaults to the filename when a file is uploaded, but you can change it in the file manager) if no link text is supplied, the block just has validation in place that forces you to enter something. So we just have to turn this unnecessary validation off.

To achieve this, we can copy controller.php from /concrete/blocks/file to /blocks/file and comment/remove the lines:

public function validate($args) {
	$e = Loader::helper('validation/error');
	if ($args['fID'] < 1) {
		$e->add(t('You must select a file.'));
	}
 
//	if (trim($args['fileLinkText']) == '') {
//		$e->add(t('You must give your file a link.'));
//	}
 
	return $e;
}

Since we've now made the file link text optional, it makes sense to edit the add/edit controls for the block slightly to indicate this. We can do that by overriding add.php and edit.php (also in the zip at the end of this post). In these I've just changed the label for the field to 'File name override'. Its up to you whether you want to do this or not. 

Creating searchable content

By default the File block doesn't return much searchable content (in earlier versions none, recent versions just the link text). We can easily enhance the function to return searchable content to the block's controller.php file:

public function getSearchableContent(){
	$text  = $this->fileLinkText;
 
	$f = $this->getFileObject();
	$text .= ' ' .  $f->getTitle();
 
	$text .= ' ' .  $f->getDescription();
	$text .= ' ' .  $f->getTags();
 
	return $text;
}

With this function added, you'll be able to search for files on your site via their title, description or tags. 

Changing the appearance

Concrete5 has built in a set of filetype icons and functions to output them, so in my view.php file I've set it to output an icon as well as the the name/title of the file, the filesize and the file type. If you've set a description for the file in the file manager, it will output that too:

<?php   defined('C5_EXECUTE') or die("Access Denied.");
	$f = $controller->getFileObject();
	$fp = new Permissions($f);
	if ($fp->canRead()) { 
		$c = Page::getCurrentPage();
		if($c instanceof Page) {
			$cID = $c->getCollectionID();
		}
 
		$fv = $f->getVersion();
		$type = strtolower($fv->getExtension());
		$fileurl = $fv->getDownloadURL();
?>
 
<div class="filelisting">
<a href="<?php echo $fileurl; ?>"><img class="icon" alt="" src="<?php echo @$fv->getThumbnail(3, false) ;?>" /></a>
 
<h4><a href="<?php echo $fileurl;  ?>"><?php echo  stripslashes($controller->getLinkText()) ?> <em>(<?php echo $fv->getSize(); ?>, <?php echo $type; ?>)</em></a></h4>
 
<?php  
// uncomment next line for the date added
// echo $fv->getDateAdded('d m y'); ?>
 
<?php 
$desc = $fv->getDescription(); 
 
if ($desc) { ?>
<p><?php echo $desc; ?></p>
<?php } ?>
 
</div> 
<?php 
}
?>

I've left in a commented line for retreiving the date added for a file. The point of leaving this in is to show that you can at this point fetch other information via the fileversion object.

Finally, since we've added an extra div and an image to the output, we'll need some simple styling. Here's a good starting point, but obviously this can be changed to suit your styling:

.filelisting {
	clear:  both;
}
 
.filelisting .icon {
	margin-right:  8px;
	width:  30px;
	float:  left;
}

Example and Download the code

Here's both what it looks like as well as a zip of the above files. Drop the folder within it into your top level /blocks folder and that's it, it should kick in anytime you use a File block.

Notes

  • The 3 in $fv->getThumbnail(3, false) will cause it output an icon for images (jpg, gif, png). If this is changed to 2, you'll get mini thumbnails of the images.
  • This block override should work fine with versions 5.4.x and 5.5.x.
  • Note that in 5.5.2 and above, the file download was changed to display downloads in the browser instead of forcing a download of the file. If you are using anything less that 5.5.2 and don't want it to force download, change getDownloadURL() to getURL() in view.php (be aware that this bypasses permissions and statistics).
  • In the line echo @$fv->getThumbnail(3, false), the @ has been put there to suppress a harmless warning message on some versions of concrete5.