<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>pointer Archives - Alexandros Georgiou</title>
	<atom:link href="https://www.alexgeorgiou.gr/tag/pointer/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.alexgeorgiou.gr/tag/pointer/</link>
	<description>Balancing brackets for a living</description>
	<lastBuildDate>Wed, 20 Dec 2023 10:28:14 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://www.alexgeorgiou.gr/wp-content/uploads/2021/07/cropped-alexgeorgiou-icon-32x32.png</url>
	<title>pointer Archives - Alexandros Georgiou</title>
	<link>https://www.alexgeorgiou.gr/tag/pointer/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>🗨 WordPress admin pointers for dummies</title>
		<link>https://www.alexgeorgiou.gr/wordpress-admin-pointers-for-dummies/</link>
					<comments>https://www.alexgeorgiou.gr/wordpress-admin-pointers-for-dummies/#respond</comments>
		
		<dc:creator><![CDATA[alexg]]></dc:creator>
		<pubDate>Fri, 23 Apr 2021 18:46:45 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[admin]]></category>
		<category><![CDATA[pointer]]></category>
		<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">https://www.alexgeorgiou.gr/?p=337</guid>

					<description><![CDATA[<p>A complete working example of an admin pointer in WordPress. Use it to display hints to new users, introducing them to your UI.</p>
<p>The post <a href="https://www.alexgeorgiou.gr/wordpress-admin-pointers-for-dummies/">🗨 WordPress admin pointers for dummies</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p><em>Ever wondered how to create WordPress admin pointers? Here&#8217;s a few pointers:</em></p>



<h2 class="wp-block-heading">What are pointers?</h2>



<p>Admin pointers are those cool-looking &#8220;hints&#8221; that point to an element in the admin screens and show some text. The hints are meant to help new users find UI elements easily. These should be dismissible by the user.</p>



<h2 class="wp-block-heading">Why this article?</h2>



<p>Even though pointers are a thing since WordPress 3.3, there are not many resources out there showcasing pointers for developers. </p>



<p>A few articles showcasing how to use pointers do exist, but they seemed a bit too convoluted for me. The articles I found, tell you how to create entire pointer frameworks, while I wanted a guide to the no-nonsense absolute bare minimum guide to pointers.</p>



<p>Read on, and soon you&#8217;ll be creating more pointers than you can point a stick at.</p>



<h2 class="wp-block-heading">Loading the assets</h2>



<p>First, enqueue the relevant assets on the <code>in_admin_header</code> action:</p>



<pre class="wp-block-code"><code>add_action(
    'in_admin_header',
    function() {
        wp_enqueue_script( 'jquery' );
        wp_enqueue_style( 'wp-pointer' );
        wp_enqueue_script( 'wp-pointer' );
    }
);</code></pre>



<p>This will load jQuery (if it&#8217;s not already loaded), and the relevant JavaScript and CSS assets. If you&#8217;re interested, here&#8217;s the code:</p>



<p><a href="https://github.com/WordPress/WordPress/blob/master/wp-includes/js/wp-pointer.js" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">https://github.com/WordPress/WordPress/blob/master/wp-includes/js/wp-pointer.js</a></p>



<p><a href="https://github.com/WordPress/WordPress/blob/master/wp-includes/css/wp-pointer.css" target="_blank" rel="noreferrer noopener" aria-label=" (opens in a new tab)">https://github.com/WordPress/WordPress/blob/master/wp-includes/css/wp-pointer.css</a></p>



<h2 class="wp-block-heading">Printing out the custom JavaScript</h2>



<p>Once we&#8217;ve enqueued the assets, we need to also print out a JavaScript block of code in that same action, <code>in_admin_header</code>. Here&#8217;s an example of the JS code that you can hack:</p>



<pre class="wp-block-code"><code>&lt;script&gt;
jQuery(
	function() {
		jQuery('#menu-dashboard').first().pointer( 
			{
				content:
					"&lt;h3&gt;WordPress dashboard&lt;\/h3&gt;" +
					"&lt;h4&gt;Here is the admin dashboard&lt;\/h4&gt;" +
					"&lt;p&gt;But, I'm guessing, you already knew this, didn't you?&lt;/p&gt;" +
					"&lt;p&gt;If so, you can &lt;strong&gt;dismiss&lt;\/strong&gt; this pointer, and it won't ever bother you again.&lt;/p&gt;",


				position:
					{
						edge:  'top',
						align: 'left'
					},

				pointerClass:
					'wp-pointer arrow-top',

				pointerWidth: 420,
				
				close: function() {
					jQuery.post(
						ajaxurl,
						{
							pointer: 'my-pointer-slug',
							action: 'dismiss-wp-pointer',
						}
					);
				},

			}
		).pointer('open');
	}
);
&lt;/script&gt;
</code></pre>



<p>OK, there&#8217;s a lot going on here, but it&#8217;s pretty straightforward:</p>



<ul class="wp-block-list"><li>We introduce a script that runs on document ready, after the DOM is fully loaded.</li><li>We use jQuery to locate the <em>Dashboard</em> menu item by HTML ID.</li><li>On this HTML element, we run the <code>pointer()</code> jQuery function, passing it an object of arguments.</li><li>The most important argument in the options object, is the <code>content</code> field. This is the pointer&#8217;s HTML content. Notice how we need to escape the forward slashes with backward slashes.</li><li>We add a few more options to control how the pointer is displayed. These are the <code>position</code>, <code>pointerClass</code> and <code>pointerWidth</code> fields. If you&#8217;re interested to learn more about these options, check <a aria-label="here (opens in a new tab)" rel="noreferrer noopener" href="https://github.com/WordPress/WordPress/blob/5.7.1/wp-includes/js/wp-pointer.js#L70-L78" target="_blank">here</a>.</li><li>Finally, we define an action for the <code>close</code> event. This is triggered when the user clicks on &#8220;ⓧ Dismiss&#8221;. We need to tell the backend to remember that this pointer is dismissed, so it won&#8217;t be displayed again. We do an AJAX POST request, passing it two parameters: The action <code>dismiss-wp-pointer</code>, and a slug that uniquely identifies the pointer.</li></ul>



<p>This is what we get with the above example:</p>



<div class="wp-block-image"><figure class="aligncenter size-large"><img fetchpriority="high" decoding="async" width="424" height="321" src="https://www.alexgeorgiou.gr/wp-content/uploads/2021/04/image.png" alt="" class="wp-image-338" srcset="https://www.alexgeorgiou.gr/wp-content/uploads/2021/04/image.png 424w, https://www.alexgeorgiou.gr/wp-content/uploads/2021/04/image-300x227.png 300w" sizes="(max-width: 599px) calc(100vw - 50px), (max-width: 767px) calc(100vw - 70px), (max-width: 991px) 429px, (max-width: 1199px) 637px, 354px" /><figcaption>Our pointer in action!<br>(Note to self: update some plugins on my dev machine)</figcaption></figure></div>



<h2 class="wp-block-heading">Dismissing the pointer</h2>



<p>We&#8217;ve already written the code that notifies the backend that &#8220;Dismiss&#8221; was clicked. Now we just need a handler that detects this, and saves a boolean as a user meta. Let&#8217;s hook this on <code>admin_init</code>. It doesn&#8217;t need to be complicated:</p>



<pre class="wp-block-code"><code>add_action(
	'admin_init',
	function() {

		if ( isset( $_POST&#91;'action'] ) &amp;&amp; 'dismiss-wp-pointer' == $_POST&#91;'action'] ) {

			update_user_meta(
				get_current_user_id(),
				'my-pointer-slug-dismissed',
				$_POST&#91;'pointer'],
				true
			);
		}
	}
);</code></pre>



<p>Now that we have a user meta that knows if the pointer was dismissed, we can wrap the JavaScript output in a conditional:</p>



<pre class="wp-block-code"><code>if (
	! get_user_meta(
		get_current_user_id(),
		'my-pointer-slug-dismissed',
		true
	)
):
	
?&gt;
	&lt;script&gt;
	&lt;!-- pointer code goes here --&gt;
	&lt;/script&gt;
&lt;?php
endif;
</code></pre>



<p>If the user meta does not exist, then the pointer code will be sent to the browser.</p>



<h2 class="wp-block-heading">Putting it all together</h2>



<p>That&#8217;s it. The following link points to a gist that showcases the complete code, in plugin form.</p>



<p><a href="https://gist.github.com/alex-georgiou/dafb963a2773b926109cd6ba980b4722" target="_blank" rel="noreferrer noopener">https://gist.github.com/alex-georgiou/dafb963a2773b926109cd6ba980b4722</a></p>
<p>The post <a href="https://www.alexgeorgiou.gr/wordpress-admin-pointers-for-dummies/">🗨 WordPress admin pointers for dummies</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.alexgeorgiou.gr/wordpress-admin-pointers-for-dummies/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
