WordPress ACF插件新出版物PDF链接失效技术求助
Hey Joseph, let's break down what's going wrong here and fix that broken link issue for your new publications.
First off, looking at your template code, the immediate red flag is how you're concatenating link_url and upload_pdf directly in the href attribute. This creates two big problems:
- If one of the fields is empty (like
link_urlfor PDF-type publications), you end up with a partial/invalid URL. - If your ACF
upload_pdffield is set to return a file object instead of a direct URL (a common setting change),the_sub_field('upload_pdf')will outputArrayinstead of a valid link—this is almost certainly why your new posts are breaking (old posts might have been created when the field was set to return URLs).
1. Verify ACF Field Settings
Head over to your ACF field group for the links repeater field:
- Check the Return Format for the
upload_pdf(file upload) field. If it's set to "File Object" or "File ID", that's why new posts are outputtingArrayinstead of a URL. You can either switch it back to "File URL" (note: this might break old posts if they rely on object data) or adjust your code to handle the object (recommended, since it's more flexible). - Double-check that the field keys (
link_url,upload_pdf,type_of_link) match exactly what's in your template—ACF field keys are case-sensitive, so a typo here would cause empty output.
2. Fix the Template Logic (Critical!)
Your current code forces both fields to be concatenated, which doesn't align with your use case (you want to use either the PDF upload or the online link, not both). Replace the link output section with this improved, safe code:
<?php if( have_rows('links') ): ?> <ul> <?php while( have_rows('links') ): the_row(); $link_type = get_sub_field('type_of_link'); $final_link = ''; // Determine which link to use based on the link type if ( $link_type === 'PDF' ) { $pdf_data = get_sub_field('upload_pdf'); // Handle both file object and direct URL cases $final_link = is_array($pdf_data) ? $pdf_data['url'] : $pdf_data; } else { $final_link = get_sub_field('link_url'); } // Only output the link if it's not empty if ( !empty($final_link) ): ?> <li> <a target="_blank" href="<?php echo esc_url($final_link); ?>"> <?php echo esc_html($link_type); ?> </a> </li> <?php endif; endwhile; ?> </ul> <?php endif; ?>
This code:
- Uses
get_sub_field()instead ofthe_sub_field()for better control over the data - Checks the link type and uses the correct field accordingly
- Handles both file objects and direct URLs for the PDF upload
- Adds
esc_url()andesc_html()to sanitize output (a WordPress security best practice) - Only renders the link if it has a valid value (no empty links)
3. Validate New Publication Entries
Go into the new problematic posts (like "SPOTLIGHT EDITION #4 - DECEMBER 2017 Copy") and confirm:
- The
linksrepeater field is properly populated (no empty rows or missing fields) - For PDF-type entries, the
upload_pdffield has a valid file uploaded - For online-type entries, the
link_urlfield has a full, valid URL (includinghttp://orhttps://)
4. Double-Check Custom Post Type Slug
Quick sanity check: Your template uses 'post_type' => 'publication', but you mentioned the CPT is named "publications". Make sure the CPT's slug is indeed publication (this is separate from the label name). Since old posts are showing up, this is probably not the issue, but it's worth confirming just in case.
Old posts worked because either:
- The ACF
upload_pdffield was set to return direct URLs when they were created, or - The concatenation didn't break things (e.g.,
link_urlwas empty butupload_pdfwas a valid URL, so the href ended up being just the PDF link).
New posts are breaking because the field setting changed (to return objects) or the logic of forcing both fields together creates invalid URLs when one is empty. The updated code fixes both scenarios.
内容的提问来源于stack exchange,提问作者Joseph Hart

