Two steps to embedding an iframe in every page and into a fixed position of a Drupal 8 site using jQuery

Submitted by Nicola Rainiero on 2017-02-20 (last updated on 2017-02-22)

Sometimes you have the necessity to put in a fixed position of every article of your site a block of content, in my case one or more adverts, but Drupal 8 and its new theming system doesn't help you much. So I'll try to show you my first rough solution via jQuery and iframe, hoping to obtain some idea to improve it or another method more efficient, maybe through only Twig.

Drupal 8 have introduced a lot of changes respect the 7 version, even in theming with twig, that replaces PHPTemplate as the default theme engine. This means the theme_* functions and PHP-based *.tpl.php files have been replaced by *.html.twig templates ().1

The main benefit of bringing Twig to Drupal was be security, indeed it separates the presentation from business logic. When you use PHP as template system you are giving too much power to the presentation layer. So, it's easy for things to get messy mixing code and layout, and even worse: having security issues in custom themes.2

From this point of view, if you have to create or modify the node content of your template, in D8 is necessary to work in two different layers or better files inside your drupal theme directory:

  1. YOUR_THEME_NAME.theme (to define new variables for blocks or views);
  2. templates/node.html.twig (to reorganize the default placement of the fields or to insert the variables of the first point that populate your page).

Speaking of theming in Drupal is not an easy task, so I won't enter in datails anymore, however I suggest you the reading of Theming Drupal 8, in order to deepen this topic.

Two steps to embed an iframe in any location of every node in a Drupal 8 site using jQuery

Look the picture above, how much should be easy to add in every node an element where do you want? In that case an iframe that floats right before the first paragrah and another element or more in the middle of an article.

In Drupal 7, I didn't have any problem to do that, simply I found an interesting article that helped me to solve it: Add a block in the middle of a node Body field in Drupal 7, or better I could have installed one of the two following modules:

  1. Advertisement;
  2. Block Inject.

In D8? At the moment I have not found any module that helps me and  I tried to instruct the Twig, but without finding the correct way. For sure in Twig I know how to change the order of fields in the content and how to display a block or a view among the fields, but nothing anymore.

How do that in D8: first attempt

I followed another way to place the adverts in my nodes: an external HTML page with the code that I embed through an iframe and a javascript library defined in my custom theme.

PROS

  • easy to implement, you have only to modify YOUR_THEME_NAME.libraries.yml and create a javascript file and the HTML for the element to embed;
  • the powerful of jQuery allows you to move and place everything you want in the page.

CONS

  • JavaScript slows the page loading;
  • putting the advertisement in an iframe is deprecated and above all unprofitable;
  • difficulty to exclude some nodes to display it.

Walkthrough

I just higlight the procedure for reproducing the image above or in short put an Altervista advertisement (the code is provided and customized by my Host) on the right of the first paragraph in every node of my site.

  1. In the /themes/YOUR_CUSTOM_THEME/js directory:
    • Add a file named advert_right.html for the advert:
      <script type="text/javascript">
      /* <![CDATA[ */
      document.write('<s'+'cript type="text/javascript" src="http://ad.altervista.org/js.ad/size=300X250/?ref='+encodeURIComponent(location.hostname+location.pathname)+'&r='+new Date().getTime()+'"></s'+'cript>');
      /* ]]> */
      </script>
      
    • Add ad_middle.js with:
      (function($) {
      $(document).ready(function(){
      var count = $("#content p").length;
      var advertRight = `<div style="float: right;"><div class="sponsor">
      <iframe src="/themes/rainnic/js/advert_right.html" width="300" height="250" frameborder="0" scrolling="no"> </iframe></div></div>
      `;
      if (count > 4) {
          $(advertRight).insertBefore("p:eq(0)");
      });
      }(jQuery));
      I have defined a variable that contains the iframe and some CSS code. Besides I don't want to show the adv if my article has less than four paragraphs, so I count the p tags of the content and check if they are more than four.
    • If you want insert the iframe in the middle you have to change it in this manner:
      (function($) {
      $(document).ready(function(){
      var count = $("#content p").length;
      var advertRight = `<div style="float: right;"><div class="sponsor">
      <iframe src="/themes/rainnic/js/advert_right.html" width="300" height="250" frameborder="0" scrolling="no"> </iframe></div></div>
      `;
      var inTheMiddle = Math.floor(count/2)-1;
      if (count > 4) {
          $(advertRight).insertBefore("p:eq("+ inTheMiddle +")");
      });
      }(jQuery));
      
  2. In the file /themes/YOUR_CUSTOM_THEME/YOUR_CUSTOM_THEME.libraries.yml add this bold code:
    global-styling:
      version: VERSION
      js:
         js/ad_middle.js: {}
      dependencies:
        - core/jquery
        - core/drupal
      css:
        base:
        [...]
    

Now it is necessary to clean all caches of Drupal and test if it works.

Spoiler: Second attempt

I am now testing a new little different approach: adv blocks that I move in the content using jQuery, but I always hope to find a solution that uses only blocks and Twig. Stay tuned!



Related Content:

Nicola Rainiero

A civil geotechnical engineer with the ambition to facilitate own work with free software for a knowledge and collective sharing. Also, I deal with green energy and in particular shallow geothermal energy. I have always been involved in web design and 3D modelling.

Add new comment

The content of this field is kept private and will not be shown publicly.

Plain text

  • No HTML tags allowed.
  • Web page addresses and email addresses turn into links automatically.
  • Lines and paragraphs break automatically.
CAPTCHA
This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.