This guide will list some of the most commonly requested uses and placements.

For ease of understanding, the following examples mainly involve using single conditional statements only, although there are some more complex examples towards the end.

In order to combine statements, you can nest them, with each statement on its own line, like so:
Code:
<xen:if is="!{$visitor.user_id}">
	<xen:if is="{$contentTemplate} == 'template'">
		Ad code
	</xen:if>
</xen:if>
Or join them together using AND and OR on a single line:
Code:
<xen:if is="!{$visitor.user_id} AND {$contentTemplate} == 'template'">
	Ad code
</xen:if>
For a more comprehensive list and detailed explanation of conditional statements, see this resource:
https://www.null-scripts.net/resources/conditional-statements.2507



Templates: all ad_* templates

1. Display to guests only.
Code:
<xen:if is="!{$visitor.user_id}">
	Ad code
</xen:if>
2. Display to a single user group - change 1 to the group ID.
Code:
<xen:if is="{xen:helper ismemberof, $visitor, 1}">
	Ad code
</xen:if>
3. Display to multiple user groups - change 1 and 2 to the group IDs, add more comma separated.
Code:
<xen:if is="{xen:helper ismemberof, $visitor, 1, 2}">
	Ad code
</xen:if>
4. Display on a single page - change template to the template name.
Code:
<xen:if is="{$contentTemplate} == 'template'">
	Ad code
</xen:if>
5. Display on multiple pages - change template_* to the template name, add more comma separated.
Code:
<xen:if is="in_array({$contentTemplate}, array('template_1', 'template_2'))">
	Ad code
</xen:if>
6. Prevent ads from being displayed to a single user group - change 1 to the group ID.
Code:
<xen:if is="!{xen:helper ismemberof, $visitor, 1}">
	Ad code
</xen:if>
7. Prevent ads from being displayed to multiple user groups - change 1 and 2 to the group IDs, add more comma separated.
Code:
<xen:if is="!{xen:helper ismemberof, $visitor, 1, 2}">
	Ad code
</xen:if>
8. Prevent ads from being displayed on a single page - change template to the template name.
Code:
<xen:if is="{$contentTemplate} != 'template'">
	Ad code
</xen:if>
9. Prevent ads from being displayed on multiple pages - change template_* to the template name, add more comma separated.
Code:
<xen:if is="!in_array({$contentTemplate}, array('template_1', 'template_2'))">
	Ad code
</xen:if>
Templates: ad_message_body, ad_message_below

10. Display in or after the first post in a thread - the last condition is required to prevent them displaying in conversations.
Code:
<xen:if is="{$post.position} == 0 AND !{$message.conversation_id}">
	Ad code
</xen:if>
11. Display in or after the first post in a thread, on each page - the last condition is required to prevent them displaying in conversations.
Code:
<xen:if is="{$post.position} % {$xenOptions.messagesPerPage} == 0 AND !{$message.conversation_id}">
	Ad code
</xen:if>
12. Display in or after a specific post in a thread - change 2 to the post ID, with the first post being 0.
Code:
<xen:if is="{$post.position} == 2">
	Ad code
</xen:if>
13. Display in or after a specific post in a thread, on each page - change 2 to the post ID, with the first post being 0.
Code:
<xen:if is="{$post.position} % {$xenOptions.messagesPerPage} == 2">
	Ad code
</xen:if>
14. Display in or after the last post in a thread - the last condition is required to prevent them displaying in conversations.
Code:
<xen:if is="{$post.position} == {$thread.reply_count} AND !{$message.conversation_id}">
	Ad code
</xen:if>
15. Display in or after the last post in a thread, on each page - the last condition is required to prevent them displaying in conversations.
Code:
<xen:if is="{$post.position} % {$xenOptions.messagesPerPage} == {$xenOptions.messagesPerPage} - 1 OR {$post.position} == {$thread.reply_count} AND !{$message.conversation_id}">
	Ad code
</xen:if>
16. Display in or after the last post in a thread, on each page, only if there are 3 or more posts on the page - change 1 for the posts per page value, with 1 being 3, 2 being 4, etc.
Code:
<xen:if is="{$post.position} % {$xenOptions.messagesPerPage} == {$xenOptions.messagesPerPage} - 1 OR {$post.position} == {$thread.reply_count} AND {$thread.reply_count} % {$xenOptions.messagesPerPage} > 1">
	Ad code
</xen:if>
17. Display to guests only, in or after the first post in a thread.
Code:
<xen:if is="!{$visitor.user_id} AND {$post.position} == 0">
	Ad code
</xen:if>
18. Display to guests only, in or after the first post in a thread, on each page.
Code:
<xen:if is="!{$visitor.user_id} AND {$post.position} % {$xenOptions.messagesPerPage} == 0">
	Ad code
</xen:if>
19. Display to guests only, in or after the first post in a thread, with 3 or more replies - change 2 to the number of replies.
Code:
<xen:if is="!{$visitor.user_id} AND {$post.position} == 0 AND {$thread.reply_count} > 2">
	Ad code
</xen:if>
20. Display to guests only, in or after the first post in a thread, on each page, with 3 or more replies - change 2 to the number of replies.
Code:
<xen:if is="!{$visitor.user_id} AND {$post.position} % {$xenOptions.messagesPerPage} == 0 AND {$thread.reply_count} > 2">
	Ad code
</xen:if>
XenForo 1.5 introduced two-step verification, so here is the updated list which includes that template:
Code:
<xen:if is="!in_array({$contentTemplate}, array('message_page', 'error', 'search_form', 'search_form_post', 'search_form_profile_post', 'search_results', 'register_form', 'register_facebook', 'register_twitter', 'register_google', 'login', 'login_two_step', 'error_with_login', 'contact'))">
There are a few new templates introduced in 1.3 which should also be restricted from having Google AdSense advertisements displayed on them.

They are the aforementioned message_page and also register_twitter and register_google.

So the array of excluded pages should now look something like:
Code:
<xen:if is="!in_array({$contentTemplate}, array('message_page', 'error', 'search_form', 'search_form_post', 'search_form_profile_post', 'search_results', 'register_form', 'register_facebook', 'register_twitter', 'register_google', 'login', 'error_with_login', 'contact'))">
In order to avoid breaching Google's ToS for AdSense, certain pages should not have ads displayed on them.
This includes error pages, for example: http://cliptheapex.com/error

This can be achieved by using a standard conditional statement like so:
Code:
<xen:if is="!in_array({$contentTemplate}, array('', 'message_page', 'error', 'search_form', 'search_form_post', 'search_form_profile_post', 'search_results', 'register_form', 'login', 'error_with_login', 'contact'))">
Ad code here
</xen:if>
The above array includes all of the standard pages I do not display ads on.

The empty string ('') is for error pages in 1.2 and earlier.

In 1.3 there is a new template - message_page.

So for 1.2 and earlier, use '', for 1.3 and later use message_page.

There is no harm in having both - adding the message_page template to the array now just means it will already be in place when you upgrade to 1.3.

Here's an actual example from my own site:
Code:
<xen:hook name="ad_below_top_breadcrumb" />

<style type="text/css">
.below-top-breadcrumb-with-sidebar-dynamic {
width: 234px;
height: 60px;
}

@media(min-width: 346px) {
	.below-top-breadcrumb-with-sidebar-dynamic {
	width: 320px;
	height: 50px;
	}
}

@media(min-width: 494px) {
	.below-top-breadcrumb-with-sidebar-dynamic {
	width: 468px;
	height: 60px;
	}
}

.below-top-breadcrumb-no-sidebar-dynamic {
width: 234px;
height: 60px;
}

@media(min-width: 346px) {
	.below-top-breadcrumb-no-sidebar-dynamic {
	width: 320px;
	height: 50px;
	}
}

@media(min-width: 494px) {
	.below-top-breadcrumb-no-sidebar-dynamic {
	width: 468px;
	height: 60px;
	}
}

@media(min-width: 754px) {
	.below-top-breadcrumb-no-sidebar-dynamic {
	width: 728px;
	height: 90px;
	}
}
</style>

<xen:if is="!{$visitor.user_id}">
	<xen:if is="!in_array({$contentTemplate}, array('', 'message_page', 'error', 'search_form', 'search_form_post', 'search_form_profile_post', 'xengallery_search_form_media', 'search_results', 'register_form', 'login', 'error_with_login', ',contact', 'thread_view', 'cta_overtaking_index'))">
		<xen:if is="@enableResponsive">
			<xen:if is="{$sidebar}">
				<div style="text-align: center; padding: 8px 0">
					<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
					<!-- Below Top Breadcrumb (With Sidebar) - Dynamic -->
					<ins class="adsbygoogle below-top-breadcrumb-with-sidebar-dynamic"
						 style="display:inline-block"
						 data-ad-client="ca-pub-1234567890123456"
						 data-ad-slot="1234567890"></ins>
					<script>
					(adsbygoogle = window.adsbygoogle || []).push({});
					</script>
				</div>
			<xen:else />
				<div style="text-align: center; padding: 8px 0">
					<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
					<!-- Below Top Breadcrumb (No Sidebar) - Dynamic -->
					<ins class="adsbygoogle below-top-breadcrumb-no-sidebar-dynamic"
						 style="display:inline-block"
						 data-ad-client="ca-pub-1234567890123456"
						 data-ad-slot="0987654321"></ins>
					<script>
					(adsbygoogle = window.adsbygoogle || []).push({});
					</script>
				</div>
			</xen:if>
		<xen:else />
			<xen:if is="{$sidebar}">
				<div style="text-align: center; padding: 8px 0">
					<script type="text/javascript">
					google_ad_client = "ca-pub-1234567890123456";
						/* Below Top Breadcrumb Narrow */
						google_ad_slot = "6789012345";
						google_ad_width = 468;
						google_ad_height = 60;
					</script>
					<script type="text/javascript"
					src="//pagead2.googlesyndication.com/pagead/show_ads.js">
					</script>
				</div>
			<xen:else />
				<div style="text-align: center; padding: 8px 0">
					<script type="text/javascript">
					google_ad_client = "ca-pub-1234567890123456";		
							/* Below Top Breadcrumb Wide */
							google_ad_slot = "5432109876";
							google_ad_width = 728;
							google_ad_height = 90;
					</script>
					<script type="text/javascript"
					src="//pagead2.googlesyndication.com/pagead/show_ads.js">
					</script>
				</div>
			</xen:if>		
		</xen:if>
	</xen:if>
</xen:if>
If, like me, you have two styles - one fixed width and one responsive, you may want to use the standard code in the fixed width style and the new asynchronous code in the responsive style.

The benefit of using different code for the fixed and fluid styles is you can specify the ad unit exactly for the fixed width and also benefit from tracking, which the asynchronous code doesn't currently support.

You could of course just enter the different code in the ad templates for each style, but if you have the styles set up as parent and child, you can simply enter it in the parent style and the child style will inherit it.


So, here's a simple example using an asynchronous ad slot for the responsive style and a standard ad slot for the fixed width style.
Code:
<style type="text/css">
.overtaking-top-dynamic {
width: 320px;
height: 50px;
}

@media(min-width: 484px) {
	.overtaking-top-dynamic {
	width: 468px;
	height: 60px;
	}
}
</style>

<xen:if is="@enableResponsive">
	<script async src="http://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
	<!-- Overtaking Top - Dynamic -->
	<ins class="adsbygoogle overtaking-top-dynamic"
		style="display:inline-block"
		data-ad-client="ca-pub-id"
		data-ad-slot="1234567890"></ins>
	<script>
	(adsbygoogle = window.adsbygoogle || []).push({});
	</script>
<xen:else />
	<script type="text/javascript">
	google_ad_client = "ca-pub-id";
	/* Overtaking Top */
	google_ad_slot = "9876543210";
	google_ad_width = 468;
	google_ad_height = 60;
	</script>
	<script type="text/javascript"
	src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
	</script>
</xen:if>
The <xen:if is="@enableResponsive"> conditional statement checks if the style is responsive.
If it is, the asynchronous code at the top is used, if not the standard code at the bottom is used.


Here's another example using the ad_message_body template, utilising several conditional statements.
This places an advert in the first post on every page (green), visible only to guests (blue).
If the style is responsive (orange), the first block of code will be used, which is the asynchronous code, otherwise the standard code will be used from the second block.
Code:
<xen:hook name="ad_message_body" />

<style type="text/css">
.message-body-dynamic
{
	width: 125px;
	height: 125px;
}

@media(min-width: 360px)
{
	.message-body-dynamic
	{
		width: 180px;
		height: 150px;
	}
}

@media(min-width: 640px)
{
	.message-body-dynamic
	{
		width: 300px;
		height: 250px;
	}
}
</style>

<xen:if is="!{$visitor.user_id}">
	<xen:if is="{$post.position} % {$xenOptions.messagesPerPage} == 0">
		<xen:if is="@enableResponsive">
			<div style="min-height: 125px; margin-left: 8px; float: right">
				<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
				<!-- Message Body - Dynamic -->
				<ins class="adsbygoogle message-body-dynamic"
					 style="display:inline-block"
					 data-ad-client="ca-pub-01234567890123456"
					 data-ad-slot="01234567890"></ins>
				<script>
				(adsbygoogle = window.adsbygoogle || []).push({});
				</script>
			</div>
		<xen:else />
			<div style="min-height: 125px; margin-left: 8px; float: right">
				<script type="text/javascript">
				google_ad_client = "ca-pub-01234567890123456";
				/* Message Body */
				google_ad_slot = "9876543210";
				google_ad_width = 300;
				google_ad_height = 250;
				</script>
				<script type="text/javascript"
				src="//pagead2.googlesyndication.com/pagead/show_ads.js">
				</script>
			</div>
		</xen:if>
	</xen:if>
</xen:if>
Note that it is recommended to not mix the ad code types on a single page; so either use all asynchronous or all standard code.
Google has created new asynchronous ad code.
This update will explain how to implement it.

See here for more details: https://support.google.com/adsense/answer/3213689

The main difference between the new asynchronous code and the existing code is you only need to create one ad unit.
To use the new code, you must create new ad units and for the ad size select Other Responsive - Responsive ad unit (BETA).

proxy.php


So how does the new code work?
Well, it uses media queries, as with the original code, but the height and width of each ad served is specified using CSS, rather than different ad units.


Here's a basic example:
Code:
<style type="text/css">
.overtaking-top-dynamic {
width: 320px;
height: 50px;
}

@media(min-width: 484px) {
	.overtaking-top-dynamic {
	width: 468px;
	height: 60px;
	}
}
</style>

<script async src="http://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- Overtaking Top - Dynamic -->
<ins class="adsbygoogle overtaking-top-dynamic"
	style="display:inline-block"
	data-ad-client="ca-pub-id"
	data-ad-slot="1234567890"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
So at the top we now have a new section for CSS.
Here you define the ad unit widths and heights based on the minimum browser width.
Google creates this automatically but you will need to customise it for your own requirements.
In this case we have:
  • Browser width 483 and below - 320x50
  • Browser width 484 and above - 468x60
Other sizes can be served simply by adding more media queries to the CSS section, defining the min-width and ad width and height accordingly.

A default size must be defined in case media queries aren't supported by the browser.

Note the CSS class in orange, which must match in the CSS section and the ad section. This is actually generated automatically based on the name you give the ad unit but it can of course be changed if you wish.


It is important that you only utilise supported ad unit widths and heights; the full list is here: https://support.google.com/adsense/answer/2953032

Note that at this time the ad units do not change dynamically as the browser width changes - a page refresh is required. Google have stated they will address that in the future.
Also, tracking of different sized ad units is not currently supported but will also be addressed in the future.
This is another example showing how different styling can be applied to ad slots based on whether the style is responsive or not and the width of the browser window.

If like me you have two styles - a non-responsive and responsive style - you may want to position your ad slots differently.

Let's take a look at the template code first:
Code:
<style type="text/css">
.CtaDbAd {
float: right;
}

<xen:if is="@enableResponsive">
	@media (max-width:910px) {
		.CtaDbAd {
		float: none;
		text-align: center;
		margin: 8px 0;
		}
	}
</xen:if>
</style>

<xen:if is="!{$visitor.user_id}">
	<xen:if is="@enableResponsive">
		<div class="CtaDbAd">
			<script type="text/javascript">
			google_ad_client = "ca-pub-id";
			width = document.documentElement.clientWidth;
			/* Overtaking Top Responsive */
			google_ad_slot = "1234567890";
			google_ad_width = 320;
			google_ad_height = 50;
				if (width > 483) {
				/* Overtaking Top */
				google_ad_slot = "1234567891";
				google_ad_width = 468;
				google_ad_height = 60;
				}
			</script>
			<script type="text/javascript"
			src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
			</script>
		</div>
	<xen:else />
		<div class="CtaDbAd">
			<script type="text/javascript">
			google_ad_client = "ca-pub-id";
			/* Overtaking Top */
			google_ad_slot = "1234567891";
			google_ad_width = 468;
			google_ad_height = 60;
			</script>
			<script type="text/javascript"
			src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
			</script>
		</div>
	</xen:if>
</xen:if>
So the first block of code is actually some CSS.
What that does is apply certain styling to any ad slot which has the CtaDbAd class applied.

On the non-responsive style and the responsive style at widths of 910px and above, the ad slot will be floated right.
However, on the responsive style, once the browser width drops below 910px, the ad slot will no longer be floated and will appear in line.

The actual ad code can be broken down as follows:
First, it is only displayed to guests: <xen:if is="!{$visitor.user_id}">
Second, the first block of code will only apply to the responsive style, displaying ad slots of 320x50 or 468x60, depending on the width.
Otherwise, if it is a non-responsive style, an ad slot of 468x60 will always be shown.
Here's another example using if and else statements.

This is in the ad_below_content template.

As the width of this area varies depending on whether there is a sidebar or not, we can factor that in to the code.

We can also use a template array (highlighted in green) to stop ads being served on some templates altogether, or to restrict them to specific templates.
Code:
<xen:hook name="ad_below_content" />

<xen:if is="!{$visitor.user_id}">
	<xen:if is="!in_array({$contentTemplate}, array('register_form', 'forum_list', 'cta_overtaking_index'))">
		<xen:if is="{$sidebar}">
			<div style="text-align: center; padding: 8px 0 8px 0">
				<script type="text/javascript">
				google_ad_client = "ca-pub-id";
				width = document.documentElement.clientWidth;
				/* Below Content Responsive */
				google_ad_slot = "1234567890";
				google_ad_width = 320;
				google_ad_height = 50;
					if (width > 483) {
					/* Below Content Narrow */
					google_ad_slot = "1234567890";
					google_ad_width = 468;
					google_ad_height = 60;
					}
				</script>
				<script type="text/javascript"
				src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
				</script>
			</div>
		<xen:else />
			<div style="text-align: center; padding: 8px 0 8px 0">
				<script type="text/javascript">
				google_ad_client = "ca-pub-id";
				width = document.documentElement.clientWidth;
				/* Below Content Responsive */
				google_ad_slot = "1234567890";
				google_ad_width = 320;
				google_ad_height = 50;
					if (width > 483) {
					/* Below Content Narrow */
					google_ad_slot = "1234567890";
					google_ad_width = 468;
					google_ad_height = 60;
					}
						if (width > 743) {
						/* Below Content Wide */
						google_ad_slot = "1234567890";
						google_ad_width = 728;
						google_ad_height = 90;
						}
				</script>
				<script type="text/javascript"
				src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
				</script>	 
			</div>
		</xen:if>
	<xen:elseif is="in_array({$contentTemplate}, array('forum_list'))"/>
		<div style="text-align: center; padding: 8px 0 8px 0">
			<script type="text/javascript">
			google_ad_client = "ca-pub-id";
			width = document.documentElement.clientWidth;
			/* Below Content Responsive */
			google_ad_slot = "1234567890";
			google_ad_width = 320;
			google_ad_height = 50;
				if (width > 351) {
				/* Forum List Bottom */
				google_ad_slot = "1234567890";
				google_ad_width = 336;
				google_ad_height = 280;
				}
			</script>
			<script type="text/javascript"
			src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
			</script>
		</div>
	</xen:if>
</xen:if>
So breaking it down, the first section of code will serve ads on all templates other than register_form, forum_list and cta_overtaking_index.

There is then a further check for the sidebar and if there is, ads of 320x50 and 468x60 will be served.
If there is no sidebar, ads of 320x50, 468x60 and 728x90 will be served.
Note it is possible to reduce or combine the code there but I have different ad slots for every ad so I have kept it separate for tracking purposes.

The last section of code applies to another array of templates and it will serve ads to any templates included in the array (although only the forum_list template is currently included).
These will be 320x50 and 336x280.

So as you can see, you can get as complex as you like when it comes to serving ads.