Media Library PDF Attachments Listing in Bricks

Updated on 9 Sep 2024

This Pro tutorial provides the steps for displaying PDF files from a HappyFiles folder as a list/grid using a Bricks query loop with PDF title, caption, description, file size and a view/open button that loads the file in a lightbox. We shall use Adobe PDF Embed API for rendering the PDFs so they work in all devices.

When done, the element structure is going to be like this:

Step 1

Get your free PDF Embed API key.

Register/log into your Adobe account and create a new project or new credentials.

Keep the browser tab open showing your API key or paste/save it in a note.

Note that the keys are domain specific and that a key also works on sub domains.

Step 2

Install and activate HappyFiles (we used the Pro version in our test site).

Go to Media → Library. Create a folder and upload/drag existing PDF files into it.

Click on each file and enter meta data.

Step 2

Let’s add helper functions for getting file size, URL, caption and description of the media item in the Bricks query loop.

Add the following in child theme‘s functions.php or a code snippets plugin:

/* Function to get attachment file size */
function bl_get_attachment_file_size() {
	$attachment_file = get_attached_file( BricksQuery::get_loop_object_id() );
	$attachment_file_size = filesize( $attachment_file );
	$attachment_file_size = size_format( $attachment_file_size );

	return $attachment_file_size;
}

/* Function to get attachment file URL */
function bl_get_attachment_file_url() {
	return wp_get_attachment_url( BricksQuery::get_loop_object_id() );
}

/* Function to get attachment caption */
function bl_get_attachment_caption() {
	return wp_get_attachment_caption( BricksQuery::get_loop_object_id() );
}

/* Function to get attachment description */
function bl_get_attachment_description() {
	return get_post( BricksQuery::get_loop_object_id() )->post_content;
}

Whitelist the above functions.

Ex.:

add_filter( 'bricks/code/echo_function_names', function() {
  return [
    'bl_get_attachment_file_size',
    'bl_get_attachment_file_url',
    'bl_get_attachment_caption',
    'bl_get_attachment_description'
  ];
} );

Step 3

Create a Page in which you would like to show the PDFs and edit it your Bricks.

Copy this JSON and paste it in the Bricks editor.

Query loop settings:

Click on Settings (gear icon) → PAGE SETTINGS → CUSTOM CODE.

Under “Body (footer) scripts” add:

<script src="https://acrobatservices.adobe.com/view-sdk/viewer.js"></script>

<script type="text/javascript">
/* Pass the embed mode option here */
const viewerConfig = {
    embedMode: "LIGHT_BOX"
};

document.addEventListener("adobe_dc_view_sdk.ready", () => {
    const buttons = document.querySelectorAll('.pdf-grid__btn');

    buttons.forEach((button) => {
        button.addEventListener('click', (event) => {
            event.preventDefault();

            const adobeDCView = new AdobeDC.View({
                clientId: "8838b2dab5144f4bbf577bc929916c99"
            });

            const fileURL = event.target.dataset.fileUrl;
            const fileName = event.target.dataset.fileName;

            adobeDCView.previewFile({
                content: {
                    location: {
                        url: fileURL
                    }
                },
                metaData: {
                    fileName: fileName,
                    hasReadOnlyAccess: true
                }
            }, viewerConfig);
        });
    });
});
</script>

Replace 8838b2dab5144f4bbf577bc929916c99 with your API key from Step 1.

We are setting file URL and name as data attributes for the button and pulling these in the JS code to load the corresponding PDF in the lightbox when the buttons are clicked.

Update 1:

I forgot to delete the Post Content element in the shared JSON. The reason why it wasn’t being output in my test site is because I set it as draft (via https://brickslabs.com/draft-status-control-for-sections-in-bricks/).

Regarding the caption, post_excerpt dynamic tag (enclose it in curly braces) is sufficient – a custom function is not needed.

Update 2:

To show file type, use this sample function:

/* Function to get attachment file type */
function bl_get_attachment_file_type() {
    $mime_type = get_post_mime_type( BricksQuery::get_loop_object_id() );
	
	switch ( $mime_type ) {
		case 'application/pdf':
			return 'pdf';
			break;
		case 'application/zip':
			return 'zip';
			break;
		case 'application/msword':
			return 'doc';
			break;
		case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
			return 'docx';
			break;
	}
}

MIME types reference

Usage:

{echo:bl_get_attachment_file_type}

Update 3:

Using the Post Content Bricks element outputs the PDF preview (of the first page) with a link to the PDF.

If you’d like to remove the links, add this code:

/**
 * Remove link from PDF attachment preview
 *
 * @param string $html The current attachment HTML.
 * @return string The modified attachment HTML.
 */
add_filter( 'prepend_attachment', function( string $html ): string {
    // Check if the attachment is a PDF
    if ( 'application/pdf' !== get_post_mime_type( $attachment_id ) ) {
        return $html;
    }

    // Remove the link but keep the image (preview)
    $html = preg_replace( '/<a[^>]+>(.*?)</a>/is', '$1', $html );

    return $html;
} );

Reference

https://developer.adobe.com/document-services/docs/overview/pdf-embed-api/howtos/#lightbox-embed-mode