From managed file ID to end-user link - neat and clean way? I have a structure in database, and I want it printed. So in hook menu I have entry with

'page callback' =&gt; 'mymodule_mystructure_display',


And in inc file I have 

function mymodule_mystructure_display($id_structure) {
  $mystructure= something(); // Data preparation
  return $mystructure;
}


And I have all helpers set up so in mystructure.tpl.php I can simply use:

kpr($mystructure);


and it all works, so let me omit details for now, they are covered in Examples for Developers anyway.

The real struggle is with files.

In $mystructure['files'] I have a nested array like this:


array(2) {
  [0]=>
  array(2) {
    ["name"]=>
    string(26) "Display name of first file"
    ["fid"]=>
    int(34)
  }
  [1]=>
  array(2) {
    ["name"]=>
    string(27) "Display name of second file"
    ["fid"]=>
    int(62)
  }
}


where ["fid"] corresponds to {file_managed}.fid field in Drupal's database.

What's the cleanest way to output links to files, with ["name"] used as link text?

What I'm doing now is pretty dirty:


In function mymodule_mystructure_display I foreach or array_walk over files.
For each element, I take file id, and use this helper function on it:

_uri_by_id($id) {
  $file = file_load($id);
  return $file-&gt;uri;
}

Result is fed to file_create_url function, and it's result is saved under ["url"] index, to give me this array in $mystructure['files']:


array(2) {
  [0]=>
  array(2) {
    ["name"]=>
    string(26) "Display name of first file"
    ["fid"]=>
    int(34)
    ["url"]=>
    string(50) "http://example.com/sites/default/files/example.pdf"
  }
  [1]=>
  array(2) {
    ["name"]=>
    string(27) "Display name of second file"
    ["fid"]=>
    int(62)
    ["url"]=>
    string(50) "http://example.com/sites/default/files/example.txt"
  }
}

In mystructure.tpl.php I use l() to print actual link:

echo l($item["name"], $item["url"]);



This all works. But it feels bad. I was always a backend guy, my frontend knowledge is somehow lacking. But I'm sure there should be a shorter way from managed file ID to a link. So what would it be?

Note: value under ["name"] is derived from $mystructure, it is not something taken directly from file object. This pretty much stopped me from using theme_file_link(). But even if it wouldn't be the problem, I still need to load file object manually to use theme_file_link().
I'd personally prefer something like this:

// Extract file IDs so we only run one file_load().
$fids = array_map($mystructure['files'], function($x) { return $x['fid']; });
$files = file_load_multiple($fids);

$build = array();
foreach ($mystructure['files'] as $file) {
  // Update the description
  $files[$file['fid']]-&gt;description = $file['name'];

  // Add to the build
  $build[] = array(
    '#theme' =&gt; 'file_link',
    '#file' =&gt; $files[$file['fid']],
  );
}

return $build;


A bit cleaner/more performant, and using as much core API as possible.