NodeBB and ads - A never ending story (Part 2)



  • A long time ago I cried about NodeBB's JavaScript unfriendlieness. Today after updating to the latest stable release I went nuts.
    NodeBB now stopped supporting any DFP code at all. Yes, you have read right. If you are a webmaster who is monetizing its content, you no longer have any possibility to do so. As seen with previous issues (when NodeBB stopped supporting sync rendering or an AdBlocker for example) it now stopped doing anything at all. I know what the developers said the last time, but come on. Are you serious?

    I do not want to call NodeBB shit, but to be honest I am very close before doing so and the worst of all is that I have no chance to go back to the software I initially came from.

    And this time please try to fix the issue! I have put my site like it always was and therefore invite the devs to take a look at it.

    I know that I may sound cocky, especially if you consider this to be an open source project for which I never paid anything. But you should either do a thing right or leave it entirely.


  • Anime Lovers

    @AOKP Actually, I think Nodebb are doing a great job. With new version releases, old plugins may failed, this is inevitability process.

    Btw, which version are you using now? You can always downgrade to previous version that you are using.



  • It seems like you might have missunderstood my post. I am not using a plugin, nor am I writing that the devs do a bad job. Actually I am quite happy how fast bugs get fixed and downgrading is not an option. It would mean that I am just "pushing" the mistake in front of me.


  • GNU/Linux

    @AOKP said in NodeBB and ads - A never ending story:

    NodeBB now stopped supporting any DFP code at all

    If you're reaching out for help with this, please share some code for sample integration and a version of NodeBB where it worked and one (probably master as of your telling) where it doesn't. Some facts are needed instead of vague "It worked, now it doesn't".

    In my opinion the DFP website is shitty as hell, I got trapped within an endless loop between two pages trying to sign up a test account (with checking pricing first). So I'm not doing any further investigation of their service; If you can provide me with some sample code and an API reference I could run further tests as to why the service does not work anymore or how to integrate correctly.
    I suspect, the lack of sample code is the main reason, so few people of the community try to help with this. Please tell if it's not possible to provide sample code.

    I can't believe this is the fault or a bug on side of NodeBB since NodeBB does provide a reasonable amount of integration hooks within the frontend. It must be either a problem with DFP not being able to integrate well OOTB for single-page applications in general or a problem with your integration code as of my point of view.
    The tutorial seems to be out of date and overall dirty hacking the core. I'm sure, with sample code and API reference provided one can set-up a good tutorial or plugin for this.



  • @frissdiegurke as I wrote I am using the latest stable release, so basically v1.x.x, commit 3c5d7f36b2284270a3de23b61f7f6f2abe49a3e2.

    I started to use NodeBB from v0.7.x on, however the first time I used DFP was with the 0.8.x branch, where it worked flawlessly. Back then it wasn't even necessary to make calls to refresh the ads. The last working version used v.1.x.x after baris pushed the XSS fixes (sorry, I couldn't find the commit). However, already there I noticed severe issues with DFP.

    The moment when DFP actually broke was from 1.x.x and higher. Since then I noticed that synchronous rendering would cause the entire page to break. Most likely because the document.write function which is used to load the ads was triggered after the page was loaded and not at the same time. When I did some experiments with the Ajax script I noticed that older versions were working - however, I am not quite sure whether or not Ajax is the real issue here.

    Another reason why I think that it is NodeBB's fold came up when I was trying to use an Anti AdBlock script, which worked just fine in older releases. However, now it does simply nothing and I can confirm that it is not the fold of the script.
    Other issues apperead when using Ezoic or Sulvo ad tags as well - even their staff tells me that the issue on my end.

    However, once more here is how my solution looks like:

    • DFP header code is in the Custom HTML
    • Ads are integrated through the widget system; some through the template
    • Modified /public/src/ajaxify.js (function renderTemplate):
    	function renderTemplate(url, tpl_url, data, callback) {
    		$(window).trigger('action:ajaxify.loadingTemplates', {});
    
    		templates.parse(tpl_url, data, function(template) {
    			translator.translate(template, function(translatedTemplate) {
    				translatedTemplate = translator.unescape(translatedTemplate);
    				$('body').removeClass(previousBodyClass).addClass(data.bodyClass);
    				$('#content').html(translatedTemplate);
    
    				ajaxify.end(url, tpl_url);
    
    				if (typeof callback === 'function') {
    					callback();
    				}
    
    				$('#content, #footer').removeClass('ajaxifying');
    
    				app.refreshTitle(data.title);
    				googletag.pubads().refresh(); <--- Tells DFP to refresh the ads after page was loaded
    			});
    		});
    	}
    

    If you would have read my old tutorial you will see that I discouraged using it as there is a way cleaner, simpler and Google ToS conform way to get the ads working (yes, above code was reviewed and permitted by Google).

    Side note: Use of AdSense + the code above gets AdSense ads working properly. However, thats not part of the discussion here as we want to get DFP running for wider ad support.

    About DFP - it is indeed a bit "special", however considering that NodeBB could be used for a larger website it is more than required. Another reason why I am stressing to get DFP working is that other users could make use of other ad networks as well (DFP is an ad server and therefore you can add ad units from many different providers to it - my use case includes AdSense, AdExchange, Media and Rubicon). For API access you need to register unfortunately, but no worries it is free to use.


  • Community Rep

    @frissdiegurke said in NodeBB and ads - A never ending story:

    In my opinion the DFP website is shitty as hell, I got trapped within an endless loop between two pages trying to sign up a test account (with checking pricing first).

    Hello, in order for the DFP page to work properly, you need to be already signed into a google account with an active adsense account. I have no idea why this happens, but it worked perfectly fine for me after that.


  • Admin

    When I got DFP working it was with the below code

    Is that no longer working?



  • @baris nope.
    Ads do not load at all with the above code. And besides that, even if you manage to load the code try to render them by using DFP's synchronous rendering function.



  • Giving this a bump again (I know it was weekend, but still, just want to make sure it doesn't gets forgotten like my old thread.

    Besides a general note, the issue is not just with DFP. Same happens when I use ad code from Sulvo or any other advertiser who uses document.write. In worst case the site breaks or the script as seen with blockadblock.org. Their script stops working entirely.


  • Admin

    If document.write() is called after nodebb page load it will just clear out the document, not sure if there is anyway to fix that.



  • @baris before it worked though.
    I know you are not Jesus (or maybe you are, at least you are a cat), but do you remember any changes which could be responsible for this?

    How about Ajax being the issue? Wouldn't this be the most "obvious" one or is there anything else responsible for rendering?


  • Admin

    Maybe they weren't using document.write before? NodeBBs rendering engine hasn't changed for a very long time. After the initial page load, when you navigate from page to page we only grab json data from the server via ajax and update the #content element on the page client side.


  • Global Moderator

    @baris Maybe something to do with widgets?

    @AOKP what is the DFP code that was working for you before? Where were you putting the DFP ad code, in HTML widgets?

    As for that adsense code hack, you shouldn't need to change core files, the following should achieve the same result:

    var _refreshTitle = app.refreshTitle;
    app.refreshTitle = function (title) {
      _refreshTitle(title);
      googletag.pubads().refresh();
    };
    

    Also, please don't bump this topic every day.



  • @PitaJ again. I inserted DFP over the Custom HTML & CSS in the Admin CP.
    The code I used is the official Google one.

    Second, I do not use any code hack.

    Third, sure the ads will reload, but I am not sure whether or not this is a violation against AdSense ToS. Without DFP this doesn't seems to be allowed actually.

    Fourth, last time I didn't bumped my topic it got forgotten. And actually it is the third time that I complain about issues with NodeBB and DFP/ad providers in general.

    Fifth, the only way to get it working again is to use a code hack. I did a few experiments yesterday and loaded my former Anti-AdBlock plugin over the base array of js.js (src/meta). And tada, it was working again. Unfortunately whenever I tried this for DFP ad units remained empty. However, I think DFP for jQuery might be able to work out overall.
    I will report back, whether or not I will have to do any hack or if it works straight out of the Admin CP.

    @baris they used document.write before. This has been confirmed by a DFP official to me. Same about the Anti-AdBlock plugin. The creator gave me an older version which worked just fine before I did an upgrade. As expected it did not work.

    Thanks for the interest so far, but please stop looking for the issue on DFP's or the other script providers end. All of them told me after their own investigations that the issue was on my end and after several tests and code hacks with their code it really seems to be the case.

    P.S.: Yes, I use Google PageSpeed, but disabling it didn't changed a thing.


  • Global Moderator

    @AOKP I said to please not bump every day. You can bump whenever you want but please give people some time to respond.

    Where are your DFP ad units located? Are they in your theme? Embedded with widgets?

    Please provide the exact code you were using before DFP stopped working for you. You can of course censor anything compromising if you wish.


  • Swedes

    So this is the only thing that need to be included in the head (With custom header) to get reload to work when using the adsence-plugin?

    var _refreshTitle = app.refreshTitle;
    app.refreshTitle = function (title) {
      _refreshTitle(title);
      googletag.pubads().refresh();
    };
    

    Third, sure the ads will reload, but I am not sure whether or not this is a violation against AdSense ToS. Without DFP this doesn't seems to be allowed actually.

    Is there anyway to verify this?

    Edit: http://stackoverflow.com/questions/30294227/reload-adsense-ads-or-have-to-use-dfp

    This means that we need to solve this issue with DFP. I guess "googletag.pubads().refresh();" code is for Google DFP only. When this is solved we should make a new clean thread with all necessary information to get this working :)



  • @PitaJ alright, alright.

    Again about the DFP code. It is the official Google one.

    Edit:
    I remember you had struggle with the DFP page. Will include the code here in a couple of minutes.

    @Jenkler, AdSense ToS doesn't permits your ad units to refresh automatically.


  • Swedes

    • If we get the DFP to work, is it possible to add adds in the first post of every thread? Header and footer is solvable with widgets.
    • It must be a way to skip the modify of /public/src/ajaxify.js (function renderTemplate): Is it possible to merge the change to core in a good way? What are the downsides of modifying ajaxify.js?

    @AOKP Can I see your webpage, url? Nice to see how you have solved the ad placements ;)



  • @Jenkler yes, even without DFP this is possible. I personally discourage from doing so and recommend to use an after first post ad placement.

    None. No functionallity will be broken or affected by the modification. However, as @PitaJ suggested it can be done as well by a simple header code.

    My NodeBB forum:
    https://forum.meizufans.eu

    @PitaJ & @baris, this is how the recent DFP code looks like:
    Header code:

    <script async='async' src='https://www.googletagservices.com/tag/js/gpt.js'></script>
    <script>
      var googletag = googletag || {};
      googletag.cmd = googletag.cmd || [];
    </script>
    
    <script>
      googletag.cmd.push(function() {
        googletag.defineSlot('/275425923/AdX_Footer', [[970, 250], [336, 280], [728, 90], [970, 90]], 'div-gpt-ad-1476529722718-0').addService(googletag.pubads());
        googletag.defineSlot('/275425923/AdX_Footer_Mobile', [[320, 100], [300, 250], [320, 50]], 'div-gpt-ad-1476529722718-1').addService(googletag.pubads());
        googletag.defineSlot('/275425923/AdX_Mid', [[336, 280], [728, 90], [970, 90]], 'div-gpt-ad-1476529722718-2').addService(googletag.pubads());
        googletag.defineSlot('/275425923/AdX_Mid_Mobile', [[320, 100], [300, 250], [320, 50]], 'div-gpt-ad-1476529722718-3').addService(googletag.pubads());
        googletag.defineSlot('/275425923/AdX_Post', [[336, 280], [728, 90], [970, 90]], 'div-gpt-ad-1476529722718-4').addService(googletag.pubads());
        googletag.defineSlot('/275425923/AdX_Post_Mobile', [[320, 100], [300, 250], [320, 50]], 'div-gpt-ad-1476529722718-5').addService(googletag.pubads());
        googletag.defineSlot('/275425923/AdX_Side', [[160, 600], [300, 250], [300, 600]], 'div-gpt-ad-1476529722718-6').addService(googletag.pubads());
        googletag.defineSlot('/275425923/AdX_Top', [[336, 280], [728, 90], [970, 90]], 'div-gpt-ad-1476529722718-7').addService(googletag.pubads());
        googletag.defineSlot('/275425923/AdX_Top_Mobile', [[320, 100], [320, 50]], 'div-gpt-ad-1476529722718-8').addService(googletag.pubads());
        googletag.pubads().enableSingleRequest();
        googletag.pubads().collapseEmptyDivs();
        googletag.enableServices();
      });
    </script>
    

    Body code (ad units):

    <!-- /275425923/AdX_Footer -->
    <div id='div-gpt-ad-1476529722718-0'>
    <script>
    googletag.cmd.push(function() { googletag.display('div-gpt-ad-1476529722718-0'); });
    </script>
    </div>
    
    <!-- /275425923/AdX_Footer_Mobile -->
    <div id='div-gpt-ad-1476529722718-1'>
    <script>
    googletag.cmd.push(function() { googletag.display('div-gpt-ad-1476529722718-1'); });
    </script>
    </div>
    
    <!-- /275425923/AdX_Mid -->
    <div id='div-gpt-ad-1476529722718-2'>
    <script>
    googletag.cmd.push(function() { googletag.display('div-gpt-ad-1476529722718-2'); });
    </script>
    </div>
    
    <!-- /275425923/AdX_Mid_Mobile -->
    <div id='div-gpt-ad-1476529722718-3'>
    <script>
    googletag.cmd.push(function() { googletag.display('div-gpt-ad-1476529722718-3'); });
    </script>
    </div>
    
    <!-- /275425923/AdX_Post -->
    <div id='div-gpt-ad-1476529722718-4'>
    <script>
    googletag.cmd.push(function() { googletag.display('div-gpt-ad-1476529722718-4'); });
    </script>
    </div>
    
    <!-- /275425923/AdX_Post_Mobile -->
    <div id='div-gpt-ad-1476529722718-5'>
    <script>
    googletag.cmd.push(function() { googletag.display('div-gpt-ad-1476529722718-5'); });
    </script>
    </div>
    
    <!-- /275425923/AdX_Side -->
    <div id='div-gpt-ad-1476529722718-6'>
    <script>
    googletag.cmd.push(function() { googletag.display('div-gpt-ad-1476529722718-6'); });
    </script>
    </div>
    
    <!-- /275425923/AdX_Top -->
    <div id='div-gpt-ad-1476529722718-7'>
    <script>
    googletag.cmd.push(function() { googletag.display('div-gpt-ad-1476529722718-7'); });
    </script>
    </div>
    
    <!-- /275425923/AdX_Top_Mobile -->
    <div id='div-gpt-ad-1476529722718-8'>
    <script>
    googletag.cmd.push(function() { googletag.display('div-gpt-ad-1476529722718-8'); });
    </script>
    </div>
    

    Here how the header code looks like with synchronous rendering:

    <script>
      (function() {
        var useSSL = 'https:' == document.location.protocol;
        var src = (useSSL ? 'https:' : 'http:') +
            '//www.googletagservices.com/tag/js/gpt.js';
        document.write('<scr' + 'ipt src="' + src + '"></scr' + 'ipt>');
      })();
    </script>
    
    <script>
      googletag.cmd.push(function() {
        googletag.defineSlot('/275425923/AdX_Footer', [[336, 280], [970, 90], [728, 90], [970, 250]], 'div-gpt-ad-1476529786566-0').addService(googletag.pubads());
        googletag.defineSlot('/275425923/AdX_Footer_Mobile', [[320, 50], [320, 100], [300, 250]], 'div-gpt-ad-1476529786566-1').addService(googletag.pubads());
        googletag.defineSlot('/275425923/AdX_Mid', [[336, 280], [970, 90], [728, 90]], 'div-gpt-ad-1476529786566-2').addService(googletag.pubads());
        googletag.defineSlot('/275425923/AdX_Mid_Mobile', [[320, 50], [320, 100], [300, 250]], 'div-gpt-ad-1476529786566-3').addService(googletag.pubads());
        googletag.defineSlot('/275425923/AdX_Post', [[336, 280], [970, 90], [728, 90]], 'div-gpt-ad-1476529786566-4').addService(googletag.pubads());
        googletag.defineSlot('/275425923/AdX_Post_Mobile', [[320, 50], [320, 100], [300, 250]], 'div-gpt-ad-1476529786566-5').addService(googletag.pubads());
        googletag.defineSlot('/275425923/AdX_Side', [[300, 600], [160, 600], [300, 250]], 'div-gpt-ad-1476529786566-6').addService(googletag.pubads());
        googletag.defineSlot('/275425923/AdX_Top', [[336, 280], [970, 90], [728, 90]], 'div-gpt-ad-1476529786566-7').addService(googletag.pubads());
        googletag.defineSlot('/275425923/AdX_Top_Mobile', [[320, 50], [320, 100]], 'div-gpt-ad-1476529786566-8').addService(googletag.pubads());
        googletag.pubads().enableSingleRequest();
        googletag.pubads().collapseEmptyDivs();
        googletag.pubads().enableSyncRendering();
        googletag.enableServices();
      });
    </script>
    

    Body code remains same, no matter if async or sync.


  • Swedes

    However, as @PitaJ suggested it can be done as well by a simple header code.

    What code do you refer to? Do you mean this?

    var _refreshTitle = app.refreshTitle;
    app.refreshTitle = function (title) {
      _refreshTitle(title);
      googletag.pubads().refresh();
    };
    
    • Can I do a "after first post ad placement." with widgets?
    • Do your header + body code need additional mods to work? Extra headercode or modify of ajax file?

    I will keep following this thred and when everything is solved maybe you can help me out with a working simple example :) I guess I need this working too :P Thanks!

    EDIT: It seams that you site reload the whole site for every click i do. It it a temp fix?


Log in to reply
 


Looks like your connection to NodeBB was lost, please wait while we try to reconnect.