- 1095 views
In Drupal, just create a field on your content type of type "file". And allow only PDF's to be uploaded.
In Manage Display settings, set it to have "Generic URL address" as a formatter. This way it will print only URL address and we can use it later.
Navigate to /sites/all/themes/[YOUR THEME]/templates folder and copy file field.tpl.php which you can find in /modules/field directory directly in ROOT folder of your website.
Now rename the file accordingly, check machine name of your field and rename it like following:
field--[type|name[--content-type]|content-type].tpl.php
base template: field.tpl.php
Theme hook suggestions are made based on these factors, listed from the most specific template to the least. Drupal will use the most specific template it finds:
- field--field-name--content-type.tpl.php
- field--content-type.tpl.php
- field--field-name.tpl.php
- field--field-type.tpl.php
Note that underscores in a Field's machine name are replaced by hyphens. Also remember to include "field-" in custom field names, e.g: field--field-phone.tpl.php.
See field.tpl.php in the Drupal API documentation for more information.
<?php
/**
* @file field.tpl.php
* Default template implementation to display the value of a field.
*
* This file is not used by Drupal core, which uses theme functions instead for
* performance reasons. The markup is the same, though, so if you want to use
* template files rather than functions to extend field theming, copy this to
* your custom theme. See theme_field() for a discussion of performance.
*
* Available variables:
* - $items: An array of field values. Use render() to output them.
* - $label: The item label.
* - $label_hidden: Whether the label display is set to 'hidden'.
* - $classes: String of classes that can be used to style contextually through
* CSS. It can be manipulated through the variable $classes_array from
* preprocess functions. The default values can be one or more of the
* following:
* - field: The current template type, i.e., "theming hook".
* - field-name-[field_name]: The current field name. For example, if the
* field name is "field_description" it would result in
* "field-name-field-description".
* - field-type-[field_type]: The current field type. For example, if the
* field type is "text" it would result in "field-type-text".
* - field-label-[label_display]: The current label position. For example, if
* the label position is "above" it would result in "field-label-above".
*
* Other variables:
* - $element['#object']: The entity to which the field is attached.
* - $element['#view_mode']: View mode, e.g. 'full', 'teaser'...
* - $element['#field_name']: The field name.
* - $element['#field_type']: The field type.
* - $element['#field_language']: The field language.
* - $element['#field_translatable']: Whether the field is translatable or not.
* - $element['#label_display']: Position of label display, inline, above, or
* hidden.
* - $field_name_css: The css-compatible field name.
* - $field_type_css: The css-compatible field type.
* - $classes_array: Array of html class attribute values. It is flattened
* into a string within the variable $classes.
*
* @see template_preprocess_field()
* @see theme_field()
*
* @ingroup themeable
*/
?>
<!--
This file is not used by Drupal core, which uses theme functions instead.
See http://api.drupal.org/api/function/theme_field/7 for details.
After copying this file to your theme's folder and customizing it, remove this
HTML comment.
-->
<div class="<?php print $classes; ?>"<?php print $attributes; ?>>
<?php if (!$label_hidden): ?>
<div class="field-label"<?php print $title_attributes; ?>><?php print $label ?>: </div>
<?php endif; ?>
<div class="field-items"<?php print $content_attributes; ?>>
<?php foreach ($items as $delta => $item): ?>
<?php
/* WE REMOVED THAT PART
<div class="field-item <?php print $delta % 2 ? 'odd' : 'even'; ?>"<?php print $item_attributes[$delta]; ?>><?php print render($item); ?></div>
*/
?>
<div id="test-id-1" style="text-align: center; width: 100%; height: 1150px" class="embed-pdf" data-url="<?php print render($item); ?>"><span class="loader">Please wait, PDF is loading...</span></div>
<?php endforeach; ?>
</div>
</div>
So now we only need to add the following snipplet in your javascript file in your theme folder.
Note, that it uses jquery so install jquery update module beforehand.
/* PDF FIX */
$(document).ready(function() {
let embed_pdfs = {};
$('.embed-pdf').each(function() {
var $pdfViewer = $('<iframe src="https://docs.google.com/viewer?url=' + $(this).data('url') + '&embedded=true" style="width: 100%; height: 100%" frameborder="0" scrolling="no"></iframe>');
$pdfViewer.appendTo($(this));
console.log($(this).attr('id') + " created");
embed_pdfs[$(this).attr('id')] = 'created';
});
$(document).find('.embed-pdf iframe').load(function(){
embed_pdfs[$(this).parents('.embed-pdf').attr('id')] = 'loaded';
$(this).siblings('.loader').remove();
console.log($(this).parents('.embed-pdf').attr('id') + " loaded");
});
let embed_pdf_check = setInterval(function() {
let remaining_embeds = 0;
$.each(embed_pdfs, function(key, value) {
try {
if ($($('#' + key)).find('iframe').contents().find("body").contents().length == 0) {
remaining_embeds++;
console.log(key + " resetting");
$($('#' + key)).find('iframe').attr('src', src='https://docs.google.com/viewer?url=' + $('#' + key).data('url') + '&embedded=true');
}
}
catch(err) {
console.log(key + " reloading");
}
});
if (!remaining_embeds) {
clearInterval(embed_pdf_check);
}
}, 1000);
});
Do not forger to clear the cache, so everything takes an effect.
Now it should be working just fine. In times where browser struggle to load the PDF, it will try each second again. I found it to be working perfectly.
Note that the solution is not mine, I just applied it on my use case, check this stackoverflow thread for original solution.