Hi, I want Query Loop the “Product Download Files” in Single Product Template with Bricks. How can I do that?
The old fashioned way, I use PHP WordPress Shortcode for this. My code:
public function init(): void {
add_shortcode( 'get_product_downloads', [ $this, 'get_product_downloads' ] );
}
public function get_product_downloads(): void {
global $product;
$downloads = [];
if ( $product->is_downloadable() ) {
foreach ( $product->get_downloads() as $file_id => $file ) {
$downloads[] = [ 'id' => $file_id, 'name' => $file['name'], 'file' => $file['file'] ];
}
}
echo '<table>';
foreach ( $downloads as $download ) {
$name = $download['name'];
$file = $download['file'];
echo '<tr>';
echo '<td>' . $name . '</td>';
echo '<td>' . "<a href='{$file}' target='_blank'>" . 'Download</a>' . '</td>';
echo '</tr>';
}
echo '</table>';
}
In Bricks I try the new way. My steps:
- I create the Single Product Template
- In Single Product Template I create a Block “Download Files” with Query Loop PHP
- Inside Block “Download Files” I add Button.
=> What PHP I need for query Download Files of Downloadable Product?
=> What Dynamics Tag {what} I add to Button to get the Download File Name and Download File Url?
Hope for your help, thanks 
1 Like
You could create a custom query that returns the array of downloads. Each download item in the loop could be exposed as a superglobal, so your dynamic data tag can access it. It just did something like that in one of my projects.
I created two libraries that come in helpful to register queries in loops:
You would need a custom query that work like this:
Query_Registry::set(
'product_downloads', // Query name
'Product Downloads', // Query label
function(array $args, $query_obj, Query $query) { // Callback for query args
global $product;
$downloads = [];
if ( $product->is_downloadable() ) {
foreach ( $product->get_downloads() as $file_id => $file ) {
$downloads[] = [ 'id' => $file_id, 'name' => $file['name'], 'file' => $file['file'] ];
}
return $downloads;
}
return [];
},
Query_Type::Other
);
DDT_Registry::getInstance()->set( 'product_download', 'Product Download', 'Your Group', function( $post, $context, $filters ) {
global $product_downloads_obj;
if (empty($product_downloads_obj) || !is_array($product_downloads_obj)) {
return "";
}
$filter = $filters[0] ?? '';
switch ($filter) {
case 'id':
return $product_downloads_obj['id'];
case 'file':
return $product_downloads_obj['file'];
default:
return $product_downloads_obj['name'];
}
});
This way you just need to select your query and could use dynamic data tags inside that query like this: {product_download:id} or {product_download:file}
The libraries are completely optional of course and you could implement the same with native bricksbuilder hooks etc.
1 Like