Add support for inline insertion of content into content body rather than at the front or back.

Original summary

This module doesn't do what the name suggests, and what I understood from the description; that is inject adsense INTO the content, e.g. after paragraph x. So I rewrote it.

Attached patch file provides two placeholders for use in adsense_injector settings 'Node body ad insertion template': %content1 and %content2. Run the patch file then set this in the settings: %content1[adsense:300x250:1:6]%content2 -- or similar.

The patch puts all the content up to the end of the third paragraph in %content1, and the remainder in %content2. I also cleaned up some duplicate code in the module and tidied up a bit in general.

It uses and requires DOM so needs php5 (domXML might work in php 4 but isn't tested yet).

This patch could be further developed to allow for multiple adsense injections, e.g. %content1[adsense]%content2[adsense]%content3. Or for a different Html element to be counted instead of p.

This patch needs testing. I don't use it on teasers or teaser lists at all, so I haven't tested that yet.

A new settings is now required to define how many paragraphs should go in %content1.

A known issue is that if the content has entities (e.g. ©) then loading the body into DOM fails. Several php warning messages will be left in watchdog and/or on screen (depending on your error handling settings in drupal). Additionally this patch will leave it's own warning message in watchdog with the offending string/content. This issue is related to how entities must be defined in XML. This is the most useful pointer I could find; http://nz.php.net/manual/en/ref.dom.php#57274. Probably a bit more time and patience would do it.

Another probable issue is when the input markup is invalid. I have not tested this as our markup comes through tinyMCE, so is usually pretty good. I tried running the content through tidy, but it was unnecessary for our case. I have left the code in, but commented it out in adsense_injector_xmlstrtodom() for further experimentation. Perhaps this could be configured in settings also.

CommentFileSizeAuthor
adsense injector.patch6.88 KBBevan
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

mcurry’s picture

Thanks for the submission.

I had considered using the DOM manipulation routines found in PHP5 but didn't want to create a dependency on PHP5. So, I need to find a solution that works well or degrades gracefully when PHP5 and the required libraries are not present.

Good point about valid HTML & entities.

Bevan’s picture

Re php5 dependency, I don't think becoming php 5 dependent is too much of an issue when php5 has been out for almost three years. My advice for anyone who would have a problem with this is upgrade your server, and if you can't do it your self and your hosting company or sysadmin can't or won't upgrade, then get a new host.

If it's something that absolutely must be maintained a simple approach is to use phpversion() to determine whether to enable "inline injection" as this feature could be nicknamed, and leave a drupal_message() notice on adsense_injection settings page to let the user know that they're running php4 and therefore missing out on this feature.

Or if someone has the time this feature could be reimplemented for php4 using DOM XML which (at a glance) seems very similar to php5's DOM extension in regards to features, classes, methods and properties, although implemented in a slightly different way. Often this difference seems to be as simple as procedural functions instead of OO methods. This would bring the feature to both versions of php, but at a cost of maintainability. I'm happy to maintain the php5 code.

As alternatives to phpversion(), domxml_version() and function_exists() could be used to determain which php extension is used however advantages would probably be minimal as one would need to manually configure and compile php to get DOM XML in php5 or DOM in php4.

Bevan’s picture

It turns out (says the boss) that some nodes require 2 long paragraphs in %content1, and other nodes require 3. I'm considering implementing either;

* a node-edit field over-ride for the 'paragraphs in %content1 setting' to set this to something else on some nodes
* some logic that determines when enough paragraphs have been placed in %content1 and it should go on to %content2. This would basically turn the test for whether this $child_node goes into %content1 or %content2, from $i>0 into something like;

$word_limit = variable_get('word_limit', 50);
if (word_count($content['parts']['1]) >> $word_limit) {
  // put this $child_node in %content1
}
else {
  // put this $child_node in %content2
}

Any thoughts? The former is quicker, but the latter is a more general solution.

Bevan’s picture

Woops. I meant:

$word_limit = variable_get('word_limit', 50);
if (word_count($content['parts'][1]) >> $word_limit) {
  // put this $child_node in %content1
}
else {
  // put this $child_node in %content2
}
Bevan’s picture

This has become a lower priority for us, but is something that I'll probably continue developing (and fixing) in a number of weeks, when we need it again.

Interestingly, there has been a lot of debate recently about whether drupal should continue to support php4. http://www.nicklewis.org/node/911 http://willy.boerland.com/myblog/and_yet_anoter_drupal_php_4_5_rant http://cmsreport.com/node/898 http://buytaert.net/php-is-dead-long-live-php

I definitely agree with Nick Lewis http://www.nicklewis.org/node/911 and Dries last post: http://buytaert.net/php-is-dead-long-live-php on this matter.

Bevan’s picture

Now that drupal has adopted a policy on php5 support, we can add this feature to drupal 6 with a php5 dependency! :)

fhelmschrott’s picture

Is there any update on the real adsense injection into the content?

Bevan’s picture

Status: Needs review » Needs work

No. But this should be rerolled for adsense.module's drupal 6 release as a php5-only feature. I currently have no motivation for this, so please take it on someone else! :)

Version needs to be set to 6.x-1.x-dev once it's created

lost305’s picture

Does this work with the newest version of Adsense Injector currently (adsense_injector-6.x-2.7) ??

This is much needed for people like me because every node starts off with a picture and having a picture and an ad squashes the text and it looks amateurish.

If this could work it would be the best thing yet!

Thanks for your time.

Bevan’s picture

Given it's over 2 years old now, almost certainly not.

lost305’s picture

Oh well. Google closed my gmail account with no warning or explanation and now I can't access my Adsense account.

netdreamer’s picture

Maybe it's not the best way of doing that... but... why not use JQuery?

This example moves the div I called #adsense-body1 right after second paragraph of the content...

I created this in the "Node body ad insertion"

<div id="adsense-body1" style="display:block;float:right;margin: 5px 10px 5px 10px;">[adsense:250x250:1234567890]</div>
%body

Then, i added this to the scripts of my template:

$(document).ready(
    function() {	
	$('#adsense-body1').siblings('p:eq(2)').after($('#adsense-body1'));
    }
);
WeRockYourWeb.com’s picture

Here's another approach (methods for Drupal 5.x and 6.x) - inserting an ad region automatically into the middle of your body content after a specified number of paragraphs: http://linkth.at/sq

mcurry’s picture

@netdream:

Maybe it's not the best way of doing that... but... why not use JQuery?

One reason not to do this is that some ad systems (Google's AdManager, for example) scripts will hose your page if you try to manipulate the DOM after it's been created. Or at least it seems to be the case. In my case, Very Bad Things happen in FireFox -- the page goes WHITE and does an infinite reload :(

Do have an example of using this with Google AdManager scripts, showing AdSense ads?

Bevan’s picture

I think you'll find that is because calling document.write() (which is what adsense scripts do) after document.close() has been called (i.e. document.ready() has been invoked) causes document.write() to clear the whole document and start writing it from scratch. You can do this if you embed the ad in a new document and put that in a blank (no src="") iframe's document object. Another way is to retrieve adsense via doubleclick and use their "adi" format (instead of adj, img, or jump), then just ad the

with the adi url as the src="" attribute and all with jquery.
mcurry’s picture

All good points. Thanks for the info.

I was under the impression that AdSense TOS prohibits IFRAMEs. I'll investigate the suggestions, though.

I'd love to see a working example on a live site.

anonymous07’s picture

Subscribe

hedac’s picture

instead of after a number of paragraphs... how could it be to inject it right after the teaser break code? if available.
if not.. then using a number of paragraphs is ok.

mcurry’s picture

Version: 5.x-2.5-1 » 6.x-2.x-dev

Moving to 6.x dev, since 5.x is no longer supported.

Magyar’s picture

Stupid question: how do I install this patch? And does this support revenue sharing?

Bevan’s picture

The patch is more than 4 years old and was for Drupal 5. It probably does not apply to any currently supported version.

pwaterz’s picture

I dont understand why this hasn't been adopted. Why not just have three text boxes(Google only lets you put 3 ads on a page.) Each with a set of settings. 1. Char Count, Check box to not break up sentences, and maybe a check box to place in between X number of paragraph tags. I think I will write a patch for this and update when I am done.

Personally I'd rather create a new module that is Textarea Inject, I think thats what I'll do, what does everyone else think?

pwaterz’s picture

If you would like to follow my progress come here http://drupal.org/sandbox/pwaterz/1268988. I am going to develop it for d6 first. I haven't had time to get into d7 much yet. My current job is holding me back.

mcurry’s picture

I appreciate your efforts.

Please keep in mind that the 'three ads per page' limit only applies to adsense standard ad units; there are other rules for link units.

I'm moving this module away from being adsense-specific; it's going to be just as useful for non-adsense and generic content insertion, so I'm unlikely to integrate your suggestions into future versions of this module -- unless I can come up with a way to support contrib plug-ins, in which case your mods would fit quite well into that scheme.

pwaterz’s picture

Ill keep you up to date on my progress maybe we can work together on something.

K-stor’s picture

Are there other modules or combination of modules that offer this functionality in Drupal 7 (insert after paragraph X) ?

mcurry’s picture

Version: 7.x-1.x-dev » 6.x-2.x-dev
Assigned: mcurry » Unassigned
Category: task » feature
Status: Patch (to be ported) » Needs work

Just for the record, the technique in #12 works brilliantly passably in my tests - except that in some cases, nothing is displayed in the relocated div.

I'm using I was using that technique on my blog on all content pages . I'm not using it now because the 6.x-3.x branch supports inline insertion using DOM manipulation, and works very well.

Maybe it's not the best way of doing that... but... why not use JQuery?

This example moves the div I called #adsense-body1 right after second paragraph of the content...

I created this in the "Node body ad insertion"

<div id="adsense-body1" style="display:block;float:right;margin: 5px 10px 5px 10px;">[adsense:250x250:1234567890]</div>
%body

Then, i added this to the scripts of my template:

$(document).ready(
    function() {
$('#adsense-body1').siblings('p:eq(2)').after($('#adsense-body1'));
    }
);
mcurry’s picture

Assigned: Unassigned » mcurry
Status: Needs work » Needs review

I gave up trying to use client-side jquery/DOM manipulation; Google's AdSense scripts do strange stuff when you try to move them around. It's unreliable and probably upsets the Big G.

If anyone is still interested in this feature, I've got a branch of this module for Drupal 6.x that uses the PHP XML DOM library (DomDocument) to allow insertion point selection using xpath expressions.

Check it out on this example page on my site, exodusdev.com. All block ads at top and inline, and the link units at the bottom of the page content are inserted by this experimental Adsense Injector module.

This version is fully functional but lacks ability to update settings from previous versions, so you'd have to reset all your current settings (save copies of your templates first!) and re-configure the module.

This version provides three body insertion points: front/top, inline, and back/bottom. The inline insertion template uses the DomDocument's xpath feature to select an insertion point. This is powerful, allowing for any valid xpath expression to select the insertion point -- but this also requires that you know what you're doing with xpath.

In any case, I'm going to continue evolving this branch, I may commit it as a 6.x.3.x-dev branch so we can try it out.

Anyone who is interested in testing this out at a very early stage, please let me know, and I'll provide a downloadable tarball so you can try it out.

mcurry’s picture

Version: 6.x-2.x-dev » 6.x-3.x-dev

The 6.x-3.x branch now integrates in-line content insertion among other things. The adventurous can download the 6.x-3.x-dev branch and give it a whirl. Be sure to read the CHANGELOG.txt file before you upgrade from 6.x-2.x to the 3.x branch.

ambition13’s picture

Hello,

I am trying to use the new 6.x-3.x-dev branch but I cannot get the settings to reset from upgrading from the 6.x-2.x-dev branch. I have followed your post and disabled everything in the settings before I upgraded. Any other way to force it to reset the settings? Thanks a lot.

edialogue’s picture

Version: 6.x-3.x-dev » 7.x-1.x-dev

Thanks. I hope you can get this to work correctly. Thanks for all your efforts. I am following this.

mcurry’s picture

Category: feature » task
Status: Needs review » Patch (to be ported)

The feature seems to be working fine in the 6.x-3.x branch.

I've created a task to track the port to the 7.x branch (see #1341094: Port inline content insertion to 7.x branch.). Let's continue the discussion there.

Please create problem-specific issues if anyone finds a problem in the 6.x branch.

Greg Boggs’s picture

Version: 6.x-2.x-dev » 7.x-1.x-dev
Assigned: Unassigned » mcurry
Category: feature » task
Status: Needs work » Closed (fixed)
Greg Boggs’s picture

Issue summary: View changes

Log message