Picture running a WordPress site—maybe with Bricks Builder or any theme—and wanting to give users a form that delivers a PDF, like a quiz result or public guide, without asking for their email.
It’s a simple idea. They fill out the form. A PDF opens in a new tab.
Their privacy stays intact.
This isn’t a one-size-fits-all feature, but for certain cases, it’s a thoughtful way to respect users.
Typical forms beg for emails, which works for marketing but can feel pushy to users who just want quick access without sharing data.
Forcing personal info might turn people away or make your site seem less trustworthy, especially for casual tools like calculators or open resources.
Offering a form that skips data collection entirely is a rare, user-friendly choice that prioritizes anonymity.
This guide shows you how to build a WordPress form that creates a PDF and opens it in a new tab, using Piotnet Forms Pro (our key tool) and WPCodeBox for neat code handling.
It’s theme-agnostic—works with any setup.
The form is built to not send or collect emails, focusing purely on PDF delivery.
I’ll include server needs, beginner-friendly steps, and why this privacy-first approach shines in specific scenarios.
Let’s explore this unique setup.
What You’ll Achieve
Your form will:
- Take user input and generate a PDF (e.g., quiz score, info sheet).
- Open the PDF in a new tab on submission.
- Require no email or personal data, keeping users anonymous.
- Function smoothly across devices and browsers.
This fits niche cases like anonymous surveys or public downloads where privacy builds trust.
Server Requirements
Make sure your server is up to the task.
- WordPress Version: 5.8 or higher (6.0+ recommended).
- PHP Version: 7.4 or higher (8.0+ for performance).
- Why: Uses glob and WordPress AJAX.
PHP Settings
- allow_url_fopen: Enabled.
- file_get_contents: Allowed.
- Memory Limit: 128MB (
memory_limit = 128M
). - Execution Time: 30 seconds (
max_execution_time = 30
). - Why: Supports PDF creation and AJAX.
File Permissions
wp-content/uploads/
must be writable (755 directories, 644 files).- Why: Stores PDFs.
Server Modules
- mod_rewrite: Enabled (for AJAX).
- glob: Available (for file scanning).
Hosting
- Standard hosts (e.g., SiteGround, WP Engine, Code Capsules) are fine.
- Avoid hosts restricting AJAX or file writes.
How to Check
Use the Health Check & Troubleshooting plugin to see PHP settings.
Ask your host about glob and permissions.
Test uploads by adding this to functions.php
:
add_action( 'admin_init', function() {
if ( is_dir( wp_upload_dir()['basedir'] ) && is_writable( wp_upload_dir()['basedir'] ) ) {
error_log( 'Uploads directory is writable' );
} else {
error_log( 'Uploads directory issue' );
}
} );
- Check
wp-content/debug.log
. - If settings are off, ask your host to adjust or upgrade your plan.
Step-by-Step Instructions
These steps assume you’re starting fresh, with no Piotnet Forms Pro or WPCodeBox installed.
I’ll guide you through setup, form creation, and code.
Step 1: Set Up Your WordPress Environment
Install WordPress
- Run WordPress 5.8+.
- Any theme works—Bricks Builder, Astra, or others.
Install Piotnet Forms Pro
- Why
- Its PDF generation is essential.
- How
- Go to Plugins > Add New.
- Buy a license at piotnetforms.com and download.
- Upload via Plugins > Add New > Upload Plugin.
- Activate through the Piotnet Forms Pro Settings panel.
- Note
- The free version won’t do for PDFs.
Install WPCodeBox
- Why
- Keeps code organized.
- How
- Purchase at wpcodebox.com.
- Upload and activate via Plugins > Add New > Upload Plugin.
- Connect license in WPCodeBox > Settings.
Step 2: Create Your Form with Piotnet Forms Pro
Add a New Form
- Go to Piotnet Forms > New Form.
- Name it (e.g., “Anonymous PDF Form”).
- Add fields (e.g., quiz questions, preferences).
Configure PDF Generation
Add PDF Action
- In Actions After Submit, select Add Action > PDF Generator.
Disable Email Actions
- This form doesn’t send or collect emails.
- Remove any Send Email action in Actions After Submit.
Set Submit Button ID
- Click the Submit button.
- In Advanced > Field ID > Custom in-line ID for Button > set a unique ID (e.g.,
form-submit-button
, orform1-submit
,form2-submit
for multiple). - Save.
Embed the Form
- Create a page (Pages > Add New).
- Add the form’s shortcode.
- Publish.
Step 3: Add the Custom Code
You’ll need PHP to fetch the PDF and JavaScript to open it.
Use WPCodeBox.
Option 1: Using WPCodeBox (Recommended)
PHP Snippet
- In WPCodeBox > Add New
- Title: “Get Latest PDF”
- Code Type: PHP
<?php
add_action( 'wp_ajax_wunderkind_get_latest_pdf_url', 'wunderkind_get_latest_pdf_url' );
add_action( 'wp_ajax_nopriv_wunderkind_get_latest_pdf_url', 'wunderkind_get_latest_pdf_url' );
function wunderkind_get_latest_pdf_url() {
$upload_dir = wp_upload_dir();
$pdf_subdir = defined( 'WUNDERKIND_PDF_SUBDIR' ) ? WUNDERKIND_PDF_SUBDIR : 'piotnetforms/files/';
$pdf_dir = trailingslashit( $upload_dir['basedir'] ) . $pdf_subdir;
$pdf_url_base = trailingslashit( $upload_dir['baseurl'] ) . $pdf_subdir;
if ( ! is_dir( $pdf_dir ) ) {
wp_send_json_error( array( 'message' => 'PDF directory not found' ) );
}
$pdf_files = glob( $pdf_dir . '*.pdf' );
if ( ! is_array( $pdf_files ) || empty( $pdf_files ) ) {
wp_send_json_error( array( 'message' => 'No PDF files found' ) );
}
$latest_file = null;
$latest_time = 0;
foreach ( $pdf_files as $file ) {
$mtime = filemtime( $file ) ?: 0;
if ( $mtime > $latest_time ) {
$latest_time = $mtime;
$latest_file = $file;
}
}
$latest_pdf = basename( $latest_file );
$latest_pdf_url = $pdf_url_base . $latest_pdf;
wp_send_json_success( array( 'pdf_url' => esc_url_raw( $latest_pdf_url ) ) );
}
- Save and enable.
JavaScript Snippet
- In WPCodeBox > Add New
- Title: “PDF Redirect”
- Code Type: JavaScript
document.addEventListener('DOMContentLoaded', function() {
if (typeof ajaxurl === 'undefined') {
window.ajaxurl = '/wp-admin/admin-ajax.php';
}
const buttonIDs = [
'form1-submit',
'form2-submit'
];
function attachPDFRedirect(button) {
const id = button.id;
if (button.dataset.pdfRedirectAttached) {
return;
}
button.dataset.pdfRedirectAttached = 'true';
button.addEventListener('click', function(event) {
event.preventDefault();
let attempts = 0;
const maxAttempts = 15;
const interval = 1000;
const poll = setInterval(function() {
fetch(ajaxurl, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
body: "action=wunderkind_get_latest_pdf_url"
})
.then(res => {
if (!res.ok) throw new Error('AJAX request failed');
return res.json();
})
.then(data => {
if (data.success && data.data.pdf_url) {
clearInterval(poll);
try {
const newWindow = window.open(data.data.pdf_url, '_blank', 'noopener');
if (!newWindow) {
const userConfirmed = confirm(
"Unable to open PDF in a new tab, possibly due to a pop-up blocker. " +
"Click OK to open it in this tab, or Cancel to stay here."
);
if (userConfirmed) {
window.location.href = data.data.pdf_url;
}
}
} catch (err) {
alert("Failed to open PDF. Please try again or disable pop-up blockers.");
}
}
})
.catch(err => {
clearInterval(poll);
alert("Failed to retrieve PDF. Please try again later.");
});
attempts++;
if (attempts >= maxAttempts) {
clearInterval(poll);
alert("PDF not found. Please try again.");
}
}, interval);
});
}
buttonIDs.forEach(id => {
const button = document.getElementById(id);
if (!button) {
return;
}
attachPDFRedirect(button);
});
const observer = new MutationObserver((mutations) => {
mutations.forEach(mutation => {
mutation.addedNodes.forEach(node => {
if (node.nodeType === 1) {
buttonIDs.forEach(id => {
const button = node.id === id ? node : node.querySelector(`#${id}`);
if (button) {
attachPDFRedirect(button);
}
});
}
});
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
});
- Save and enable.
- Update: Replace
form1-submit
,form2-submit
with your button IDs.
Step 4: Test Your Form
- Access the Form
- Visit your form page (e.g.,
yoursite.com/form
). - Complete and submit.
- Visit your form page (e.g.,
- Check Behavior
- PDF opens in a new tab.
- Current tab stays put.
- No emails sent or data collected.
- Debug Issues
- No PDF
- Inspect browser console.
- Verify upload permissions.
Check button IDs.
- No PDF
- Downloads
- Browser-dependent behavior.
- Not a code issue.
- Redirects
- Ensure
event.preventDefault()
is in place. - Use correct button IDs.
- Ensure
Step 5: Finalize and Launch
- Style the Form
- Use Piotnet Forms or your theme tools.
- Test Devices
- Try desktop, tablet, and mobile.
- Test with pop-up blockers enabled.
- Clear Caches
- Clear any caching plugins and browser cache.
Benefits of This Approach
- User Privacy
- No email needed.
- Encourages trust through anonymity.
- Simple Experience
- Instant PDF access.
- Feels effortless for users.
- Theme Flexibility
- Works with any theme.
- Fallback Support
- Handles pop-up blockers gracefully.
- Custom PDFs
- Build dynamic PDFs from user input.
Drawbacks to Consider
- No Lead Capture
- No email collection for marketing.
- Niche Use
- Best for anonymous or public tools.
- Plugin Cost
- Piotnet Forms Pro is paid.
- Code Maintenance
- Check after updates.
- Storage
- PDFs can accumulate and require cleanup.
Key Considerations
- Directory Sync
- Match Piotnet’s PDF path with PHP (
piotnetforms/files/
).
- Match Piotnet’s PDF path with PHP (
- Button IDs
- Make sure Piotnet and JavaScript IDs match.
- Dynamic Buttons
- Script supports AJAX-loaded forms.
- Test thoroughly.
- Pop-up Blockers
- Fallback prompt is helpful.
- Still, advise users to allow pop-ups.
- Polling
- Increase
maxAttempts
if PDF generation is slow.
- Increase
- Security
- Public AJAX is fine here.
- Use nonces for private data.
- Cleanup
- Delete old PDFs with this optional, untested code snippet:
add_action( 'wp_scheduled_delete', function() {
$dir = wp_upload_dir()['basedir'] . '/piotnetforms/files/';
foreach ( glob( $dir . '*.pdf' ) as $file ) {
if ( filemtime( $file ) < strtotime( '-7 days' ) ) {
unlink( $file );
}
}
} );
Final Thoughts
This form setup skips email collection. It’s not for lead-hungry sites.
For anonymous quizzes, public guides, or privacy-first tools, it’s a neat way to deliver value while respecting users.
Try it for those special cases where trust matters most.