Templates reference
Who this is for
This page is for developers and theme authors who need to override download form templates. For a shorter guide, see Template overrides.
Template system overview
The plugin uses a template hierarchy similar to WordPress themes:
- Child Theme -
/wp-content/themes/child-theme/somdn-templates/ - Parent Theme -
/wp-content/themes/parent-theme/somdn-templates/ - Plugin -
/wp-content/plugins/free-downloads-woocommerce-pro/templates/
Templates in your theme override plugin templates.
Available Templates
Basic Edition Templates
Located in /templates/ directory:
single-file.php- Single file download buttonmulti-file-button.php- Multiple files with button onlymulti-file-button-checkboxes.php- Multiple files with checkboxesmulti-file-button-filenames.php- Button with file names listedmulti-file-button-links.php- Button with individual file linksmulti-file-links.php- Individual file links only
Pro Edition Templates
Located in /pro/templates/ directory:
Email Capture:
download-forms/capture-email-form.php- Email capture modal
Account:
account/free-download-limits.php- Download limits displayaccount/free-download-history.php- Download history table
Overriding Templates
Step 1: Create Directory
Create template directory in your theme:
/wp-content/themes/your-theme/somdn-templates/
Step 2: Copy Template
Copy template from plugin to theme:
From:
/wp-content/plugins/free-downloads-woocommerce-pro/templates/single-file.php
To:
/wp-content/themes/your-theme/somdn-templates/single-file.php
Step 3: Customize
Edit the template in your theme. Your changes will be preserved during plugin updates.
Template Variables
All templates receive these variables:
$product
WooCommerce product object.
Usage:
$product_name = $product->get_name();
$product_price = $product->get_price();
$product_id = $product->get_id();
$somdn_args
Array of display arguments.
Available Keys:
button_text- Download button textbutton_classes- CSS classes for buttonlink_classes- CSS classes for linksshow_files- Whether to show file listarchive- Whether on archive pageproduct_id- Product IDvariation_id- Variation ID (if applicable)
Usage:
$button_text = $somdn_args['button_text'];
$button_classes = $somdn_args['button_classes'];
$files
Array of downloadable files.
File Structure:
array(
'name' => 'File Name',
'file' => '/path/to/file.pdf',
'download_id' => 'abc123'
)
Usage:
foreach ($files as $file) {
echo esc_html($file['name']);
}
Single File Template
File: single-file.php
Purpose: Display single download button
Default Structure:
<div class="somdn-download-wrap">
<form id="somdn-download-single-form" method="post">
<?php wp_nonce_field('somdn_download_token', 'somdn_download_token'); ?>
<input type="hidden" name="somdn_download_single" value="1">
<input type="hidden" name="somdn_product_id" value="<?php echo esc_attr($product->get_id()); ?>">
<button type="submit" class="somdn-download-button <?php echo esc_attr($somdn_args['button_classes']); ?>">
<?php echo esc_html($somdn_args['button_text']); ?>
</button>
</form>
</div>
Customization Example:
<div class="custom-download-wrapper">
<h3>Free Download Available</h3>
<p>Get instant access to <?php echo esc_html($product->get_name()); ?></p>
<form id="somdn-download-single-form" method="post">
<?php wp_nonce_field('somdn_download_token', 'somdn_download_token'); ?>
<input type="hidden" name="somdn_download_single" value="1">
<input type="hidden" name="somdn_product_id" value="<?php echo esc_attr($product->get_id()); ?>">
<button type="submit" class="btn btn-primary btn-lg">
<i class="fa fa-download"></i>
<?php echo esc_html($somdn_args['button_text']); ?>
</button>
</form>
<p class="download-info">No account required • Instant access</p>
</div>
Multiple Files with Button
File: multi-file-button.php
Purpose: Download all files as ZIP
Default Structure:
<div class="somdn-download-wrap">
<form id="somdn-download-all-form" method="post">
<?php wp_nonce_field('somdn_download_token', 'somdn_download_token'); ?>
<input type="hidden" name="somdn_download_all" value="1">
<input type="hidden" name="somdn_product_id" value="<?php echo esc_attr($product->get_id()); ?>">
<button type="submit" class="somdn-download-button <?php echo esc_attr($somdn_args['button_classes']); ?>">
<?php echo esc_html($somdn_args['button_text']); ?>
</button>
</form>
</div>
Customization Example:
<div class="multi-file-download">
<div class="file-count">
<?php echo count($files); ?> files included
</div>
<form id="somdn-download-all-form" method="post">
<?php wp_nonce_field('somdn_download_token', 'somdn_download_token'); ?>
<input type="hidden" name="somdn_download_all" value="1">
<input type="hidden" name="somdn_product_id" value="<?php echo esc_attr($product->get_id()); ?>">
<button type="submit" class="download-all-button">
Download All Files (ZIP)
</button>
</form>
</div>
Multiple Files with Checkboxes
File: multi-file-button-checkboxes.php
Purpose: Select specific files to download
Default Structure:
<div class="somdn-download-wrap">
<form id="somdn-download-checked-form" method="post">
<?php wp_nonce_field('somdn_download_token', 'somdn_download_token'); ?>
<input type="hidden" name="somdn_download_checked" value="1">
<input type="hidden" name="somdn_product_id" value="<?php echo esc_attr($product->get_id()); ?>">
<div class="somdn-download-files-wrap">
<?php foreach ($files as $file) : ?>
<div class="somdn-download-file-wrap">
<input type="checkbox"
name="somdn_download_files[]"
value="<?php echo esc_attr($file['download_id']); ?>"
id="file-<?php echo esc_attr($file['download_id']); ?>">
<label for="file-<?php echo esc_attr($file['download_id']); ?>">
<?php echo esc_html($file['name']); ?>
</label>
</div>
<?php endforeach; ?>
</div>
<button type="submit" class="somdn-download-button <?php echo esc_attr($somdn_args['button_classes']); ?>">
<?php echo esc_html($somdn_args['button_text']); ?>
</button>
</form>
</div>
Customization Example:
<div class="file-selector">
<h4>Select Files to Download</h4>
<form id="somdn-download-checked-form" method="post">
<?php wp_nonce_field('somdn_download_token', 'somdn_download_token'); ?>
<input type="hidden" name="somdn_download_checked" value="1">
<input type="hidden" name="somdn_product_id" value="<?php echo esc_attr($product->get_id()); ?>">
<div class="file-list">
<?php foreach ($files as $index => $file) : ?>
<div class="file-item">
<input type="checkbox"
name="somdn_download_files[]"
value="<?php echo esc_attr($file['download_id']); ?>"
id="file-<?php echo esc_attr($file['download_id']); ?>"
class="file-checkbox">
<label for="file-<?php echo esc_attr($file['download_id']); ?>" class="file-label">
<span class="file-number"><?php echo $index + 1; ?>.</span>
<span class="file-name"><?php echo esc_html($file['name']); ?></span>
</label>
</div>
<?php endforeach; ?>
</div>
<div class="download-actions">
<button type="button" class="select-all-btn">Select All</button>
<button type="submit" class="download-selected-btn">
Download Selected Files
</button>
</div>
</form>
</div>
Multiple Files with Links
File: multi-file-links.php
Purpose: Individual download links for each file
Default Structure:
<div class="somdn-download-wrap">
<div class="somdn-download-files-wrap">
<?php foreach ($files as $file) : ?>
<div class="somdn-download-file-wrap">
<form method="post" class="somdn-download-link-form">
<?php wp_nonce_field('somdn_download_token', 'somdn_download_token'); ?>
<input type="hidden" name="somdn_download_link" value="1">
<input type="hidden" name="somdn_product_id" value="<?php echo esc_attr($product->get_id()); ?>">
<input type="hidden" name="somdn_download_id" value="<?php echo esc_attr($file['download_id']); ?>">
<button type="submit" class="somdn-download-link <?php echo esc_attr($somdn_args['link_classes']); ?>">
<?php echo esc_html($file['name']); ?>
</button>
</form>
</div>
<?php endforeach; ?>
</div>
</div>
Customization Example:
<div class="file-downloads">
<h4>Available Files</h4>
<ul class="file-list">
<?php foreach ($files as $file) : ?>
<li class="file-item">
<form method="post" class="inline-form">
<?php wp_nonce_field('somdn_download_token', 'somdn_download_token'); ?>
<input type="hidden" name="somdn_download_link" value="1">
<input type="hidden" name="somdn_product_id" value="<?php echo esc_attr($product->get_id()); ?>">
<input type="hidden" name="somdn_download_id" value="<?php echo esc_attr($file['download_id']); ?>">
<button type="submit" class="file-download-link">
<i class="fa fa-file-pdf"></i>
<?php echo esc_html($file['name']); ?>
<i class="fa fa-download"></i>
</button>
</form>
</li>
<?php endforeach; ?>
</ul>
</div>
Email Capture Template (Pro)
File: pro/templates/download-forms/capture-email-form.php
Purpose: Email capture modal
Key Elements:
- Modal wrapper with
.somdn-capture-email-wrap - Form with ID
somdn-capture-email-form - Required fields with
.somdn-capture-required - Honeypot field for spam prevention
- Close button
Customization Tips:
- Maintain form structure and field names
- Keep
.somdn-capture-requiredclass on required fields - Preserve honeypot field
- Keep nonce field
- Maintain form ID for JavaScript
Example Customization:
<div class="somdn-capture-email-wrap custom-modal">
<div class="modal-content">
<button class="close-modal" onclick="somdn_close_email_capture()">×</button>
<h2>Get Your Free Download</h2>
<p>Enter your email to access this free resource.</p>
<form id="somdn-capture-email-form" method="post">
<?php wp_nonce_field('somdn_download_token', 'somdn_download_token'); ?>
<!-- Email field -->
<div class="form-group">
<label for="somdn_download_user_email">Email Address *</label>
<input type="email"
name="somdn_download_user_email"
id="somdn_download_user_email"
class="form-control somdn-capture-required"
required>
</div>
<!-- Additional fields as needed -->
<!-- Honeypot (keep hidden) -->
<input type="text"
name="somdn_download_user_name_check"
style="display:none!important;"
tabindex="-1"
autocomplete="off">
<button type="submit" class="btn btn-primary btn-block">
Download Now
</button>
</form>
<p class="privacy-note">
We respect your privacy. No spam, ever.
</p>
</div>
</div>
Download History Template (Pro)
File: pro/templates/account/free-download-history.php
Purpose: Display user's download history
Key Variables:
$downloads- Array of download log posts$user_id- Current user ID$limits- User's download limits (if enabled)
Customization Example:
<div class="download-history-section">
<?php if (!empty($limits)) : ?>
<div class="limits-display">
<h3>Your Download Limits</h3>
<p>You have downloaded <?php echo $limits['current']; ?> of <?php echo $limits['total']; ?> files this <?php echo strtolower($limits['period']); ?>.</p>
<p><?php echo $limits['remaining']; ?> downloads remaining.</p>
</div>
<?php endif; ?>
<h3>Download History</h3>
<?php if (!empty($downloads)) : ?>
<table class="download-history-table">
<thead>
<tr>
<th>Product</th>
<th>Date</th>
<th>Files</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php foreach ($downloads as $download) : ?>
<tr>
<td><?php echo esc_html(get_post_meta($download->ID, 'somdn_product_name', true)); ?></td>
<td><?php echo get_the_date('', $download); ?></td>
<td><?php echo count(get_post_meta($download->ID, 'somdn_download_files', true)); ?></td>
<td>
<a href="<?php echo esc_url(add_query_arg('redownload', $download->ID)); ?>" class="redownload-btn">
Re-download
</a>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else : ?>
<p>You haven't downloaded any free products yet.</p>
<?php endif; ?>
</div>
Template Functions
somdn_get_template()
Load a template file.
Usage:
somdn_get_template('single-file.php', array(
'product' => $product,
'somdn_args' => $args,
'files' => $files
));
somdn_locate_template()
Locate a template in theme or plugin.
Usage:
$template_path = somdn_locate_template('single-file.php');
CSS Classes Reference
Wrapper Classes
.somdn-download-wrap- Main wrapper.somdn-download-files-wrap- Files container.somdn-download-file-wrap- Individual file wrapper
Button Classes
.somdn-download-button- Download button.somdn-download-link- Download link.single_add_to_cart_button- WooCommerce button class
Form Classes
#somdn-download-single-form- Single file form#somdn-download-all-form- Download all form#somdn-download-checked-form- Checkbox form.somdn-download-link-form- Individual file form
Email Capture Classes
.somdn-capture-email-wrap- Modal wrapper#somdn-capture-email-form- Capture form.somdn-capture-required- Required field.somdn-download-user-name- Input field class
State Classes
.somdn-loading- Loading state.somdn-error- Error state.somdn-success- Success state
JavaScript Integration
Templates work with plugin JavaScript:
Button Click Handling:
// Automatically handled by plugin
document.querySelector('.somdn-download-button').addEventListener('click', function(e) {
// Loading state added
// Email capture checked
// Form submitted
});
Custom JavaScript:
// Add custom behavior
jQuery(document).on('click', '.somdn-download-button', function() {
// Your custom code
console.log('Download button clicked');
});
Best Practices
Maintain Structure
Keep essential elements:
- Form IDs and names
- Hidden fields
- Nonce fields
- Required classes
Escape Output
Always escape:
echo esc_html($text);
echo esc_attr($attribute);
echo esc_url($url);
Responsive Design
Make templates mobile-friendly:
@media (max-width: 768px) {
.somdn-download-wrap {
width: 100%;
}
}
Accessibility
Include ARIA labels:
<button type="submit" aria-label="Download <?php echo esc_attr($product->get_name()); ?>">
Download
</button>
Version Control
Document template version:
/**
* Template: Single File Download
* Version: 1.0.0
* Last Modified: 2024-01-15
*/
Troubleshooting
Template Not Loading
- ✅ Check directory name:
somdn-templates - ✅ Check file name matches exactly
- ✅ Clear all caches
- ✅ Check file permissions
- ✅ Verify theme is active
Styling Issues
- ✅ Inspect CSS classes
- ✅ Check theme conflicts
- ✅ Add custom CSS
- ✅ Use browser dev tools
- ✅ Check CSS specificity
Functionality Broken
- ✅ Verify form structure
- ✅ Check field names
- ✅ Ensure nonce present
- ✅ Test with default template
- ✅ Check JavaScript errors
What's Next
- Actions reference - Action hooks for custom behavior
- Filters reference - Filter hooks to modify data
- Template overrides - User guide to overrides
- Security - Security best practices for custom templates