<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[plusquam blog]]></title><description><![CDATA[plusquam blog]]></description><link>https://blog.plusquam.studio</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1653252944767/DY2IlMbD6.png</url><title>plusquam blog</title><link>https://blog.plusquam.studio</link></image><generator>RSS for Node</generator><lastBuildDate>Sat, 18 Apr 2026 00:48:03 GMT</lastBuildDate><atom:link href="https://blog.plusquam.studio/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[How to Self-Host Google Fonts on your own WordPress Website, in 2022]]></title><description><![CDATA[Following a decision by the Munich Regional Court (in Germany) in 2022, website operators with embedded Google Fonts are increasingly receiving warnings and fines. This is because embedding dynamic web content such as Google Fonts from US web service...]]></description><link>https://blog.plusquam.studio/how-to-self-host-google-fonts-on-your-own-wordpress-website-in-2022</link><guid isPermaLink="true">https://blog.plusquam.studio/how-to-self-host-google-fonts-on-your-own-wordpress-website-in-2022</guid><category><![CDATA[admonitions]]></category><category><![CDATA[google fonts]]></category><category><![CDATA[#gdpr]]></category><category><![CDATA[WordPress]]></category><category><![CDATA[wordpress plugins]]></category><dc:creator><![CDATA[Kevin Eulenberg]]></dc:creator><pubDate>Thu, 13 Oct 2022 18:08:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1665682995847/ntu1WIOzP.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Following a decision by the Munich Regional Court (in Germany) in 2022, website operators with embedded Google Fonts are increasingly receiving warnings and fines. This is because embedding dynamic web content such as Google Fonts from US web services is illegal without the visitors' consent. Website operators can be sued for injunctive relief and damages. </p>
<p>The website operator is threatened with an administrative fine of 100 to 250,000 euros or, alternatively, an administrative detention of up to six months if the IP address of the plaintiff continues to be passed on to Google when visiting the website.</p>
<h3 id="heading-solution-to-the-problem">Solution to the problem</h3>
<p>To avoid a possible lawsuit, websites must host content such as fonts, scripts or images themselves. Alternatively, consent to share the IP address could be obtained via a consent banner, but this would be less conducive to user experience.</p>
<h3 id="heading-what-exactly-happens-when-i-load-fonts-directly-via-google">What exactly happens when I load fonts directly via Google?</h3>
<p>By using Google Fonts, which are loaded via Google's CDN, an additional Google Tracking Pixel is set, which forwards tracking information in the form of IP addresses to Google without consent. </p>
<p>You don't feel like reading, have already integrated Google Fonts on a WordPress website, and want to protect your website from any lawsuits as soon as possible?</p>
<p>Then take a look at <a target="_blank" href="https://www.youtube.com/watch?v=EYb51g3uKNI">my video tutorial below</a>.</p>
<p>If you want to know more details about the Google Fonts API problem, please read on, I have compiled all the important information for you.</p>
<p>If you can't solve your Google Fonts problem with the method shown in the video, I also recommend reading this article.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.youtube.com/watch?v=EYb51g3uKNI">https://www.youtube.com/watch?v=EYb51g3uKNI</a></div>
<h3 id="heading-who-is-affected">Who is affected?</h3>
<ol>
<li>all websites that use Google fonts and have been embedded using the standard embed method (CDN Embed) and therefore retrieve the font directly from the Google server</li>
<li>all websites that use YouTube video embeds </li>
<li>all websites which do not technically block these external calls via a cookie-banner explicitly before the consent of the user.</li>
</ol>
<p>The consequence if a reported violation occurs:
Variable fines will be currently imposed in the range between 100 and €1.000, but they can also be higher in some specific cases.<em> (Updated in October 2022)</em></p>
<h3 id="heading-who-sues-and-profits">Who sues and profits:</h3>
<p>Often, it is law firms, commercial or private persons who send a series of collective warnings to several website operators.</p>
<p>There are several ways to avoid a possible warning and at the same time to ensure a sensible usability for website visitors.</p>
<ol>
<li>do not use Google fonts or YouTube video embedding </li>
<li>make sure that Google fonts are loaded locally without the regular CDN integration</li>
<li>if YouTube videos are used, make sure that a consent is given for the playback of the video before the video is loaded.</li>
</ol>
<h2 id="heading-how-do-i-know-if-i-am-affected">How do I know if I am affected?</h2>
<p>There are<strong> two ways to quickly identify this</strong>. (this also works for all websites, regardless if this is a WordPress or non-WordPress Website)</p>
<ol>
<li><p>you can use the following "<a target="_blank" href="https://google-fonts-checker.54gradsoftware.de/en">Google Fonts Checker</a>" web app to scan your website for Google Fonts. (easiest method, relatively reliable, but no guarantee).</p>
</li>
<li><p>alternatively, you can check in your browser's network monitor whether connections to Google (gstatic) are taking place, if so, this indicates that Google fonts are loaded via the CDN and a violation of the DSGVO is taking place (advanced method, <strong>very reliable if you check it on each subpage</strong> of your Website) - I'll also explain how this works in detail in the <a target="_blank" href="https://www.youtube.com/watch?v=EYb51g3uKNI">video tutorial</a>.</p>
</li>
</ol>
<h2 id="heading-faqs-regarding-embed-google-fonts-locally">FAQ's regarding: Embed Google Fonts locally</h2>
<p><strong>Preface:</strong></p>
<p>If you have already integrated Google Fonts into one of your websites or your clients websites, you have two possibilities to proceed here: </p>
<p>The quickest and easiest solution is to use a plug-in that blocks all requests to the Google Fonts API and downloads the fonts requested from Google to store them locally on your web server. This will bypass any connection to the Google Web server.</p>
<p><strong>Is that legal? </strong>
Of course, because the entire font library is subject to the Open-source license.</p>
<p><strong>Is a plug-in solution method reliable?</strong></p>
<p>Another advantage of using the plug-in is that additional fonts caused by various other plug-ins are also intercepted and stored locally. So yes, but be careful: this requires that the developers of the theme and the plug-ins have integrated the Google Fonts implementation cleanly via the intended methods provided by WordPress. Loading CSS imports, so-called antipatterns, does not work with the method of the plug-in that is supposed to prevent you from this, as these requests are not recognized to filter them correctly by the plug-in. The same applies if Google Fonts are loaded via an added meta tag (e.g. within your header.php). </p>
<p><strong>⚠️ So please do not forget:</strong></p>
<p><em>Never blindly rely on plug and play solutions: </em> After activating the plug-in of your choice, you should double-check whether the loading of Google fonts is actually prevented by the Google server. You should also check whether there are any additional embeddings of YouTube videos or fonts on your subpages to be really sure.</p>
<h2 id="heading-4-simple-steps-to-a-local-google-web-font-embedding">4 simple steps to a local Google Web Font embedding</h2>
<ol>
<li>I recommend you to download the <a target="_blank" href="https://de.wordpress.org/plugins/host-webfonts-local/">plug-in "OMGF"</a> from the official WordPress Plug-in Store</li>
<li>activate the plug-in and navigate to the settings</li>
<li>from here, accept the default settings and click on "Save and optimize".</li>
<li>if you are using a caching plug-in, make sure you clear the cache for your changes to take effect.</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1665684158487/1QdFeL3ds.png" alt="omgf.png" /></p>
<p><strong>How do I check if all Google Fonts are loaded locally and not via the Google API?</strong></p>
<p>As mentioned above, you can use your trusted web app (e.g. "<a target="_blank" href="https://google-fonts-checker.54gradsoftware.de/en">Google Fonts Checker</a>") to check your website to make sure that the fonts are actually loaded locally. </p>
<p><em>Using your browser's network monitor to examine the fonts.</em></p>
<p>In the following example, I'll show you how you can use the Google Chrome console to quickly filter network requests for Google fonts to identify them and their origin:</p>
<ol>
<li>right-click in your web page and click on "Inspect".</li>
<li>navigate to the tab "Network" and click on the sub-tab "Fonts"</li>
<li>use the keyword "gstatic" in the search field of the console and reload the page.</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1665684230128/4Hssq36pe.png" alt="network-monitor.png" /></p>
<p>Now you will see a list of all font requests that are loaded via your website. If you don't find anything here, congratulations, from now on, all fonts will be loaded via your local web server. 
If Google Fonts are still loaded via a YouTube Video iFrame, you would also find them here.</p>
<p>⚠️ <strong>At this point, I would like to mention again that you must check the network monitor on all subpages of your website to really make sure that no more fonts are loaded from the Google server.</strong></p>
<p>You don't manage to deactivate the Google Web Fonts API despite this article? 
Then leave me a comment in this article.</p>
]]></content:encoded></item><item><title><![CDATA[New custom WordPress user roles in 2 easy steps]]></title><description><![CDATA[In this article, I want to give you a crisp guide on the topic "How to create new custom user roles in WordPress" because this problem was often brought up in my circle of developer and content manager colleagues. Why creating custom user roles can b...]]></description><link>https://blog.plusquam.studio/custom-worpress-user-roles</link><guid isPermaLink="true">https://blog.plusquam.studio/custom-worpress-user-roles</guid><category><![CDATA[WordPress]]></category><category><![CDATA[wordpress plugins]]></category><category><![CDATA[admin]]></category><category><![CDATA[Accessibility]]></category><category><![CDATA[database]]></category><dc:creator><![CDATA[Kevin Eulenberg]]></dc:creator><pubDate>Sun, 22 May 2022 20:17:19 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/dGk-qYBk4OA/upload/v1653250402280/6KogdBVML.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this article, I want to give you a crisp guide on the topic "How to create new custom user roles in WordPress" because this problem was often brought up in my circle of developer and content manager colleagues. Why creating custom user roles can be relevant, you will learn in the first paragraphs. However, if you are in a hurry, you can of course jump directly to the headline <a class="post-section-overview" href="#start">"Create a user role in 2 simple steps 🏆"</a>.</p>
<h2 id="heading-why-do-we-need-user-roles-at-all">Why do we need user roles at all?</h2>
<p>Everybody knows the problem: Several users with admin or editor rights use a WordPress site, but your customer, or you want the possibility to restrict the access rights of some specific users individually.</p>
<h2 id="heading-advanced-user-roles-access-management-can-help">Advanced user roles access management can help</h2>
<p>One problem I've often faced in real-world use is that downgrading specific user roles doesn't directly solve the problem, and quickly you realize that the default WordPress user roles aren't enough or can't be properly restricted individually. The downgrading of a user in the role "Admin" to "Editor" has as desired the consequence that the respective user cannot edit plug-ins or basic base website settings, but it may well be that the user is also no longer able to access certain settings of certain plug-ins, which are maybe needed for the everyday use of the content manager.</p>
<p>An easy to use, very well-known and useful plug-in that helps with this problem already exists and is called: "<a target="_blank" href="https://de.wordpress.org/plugins/adminimize/">Adminimize</a>". Adminimize is a great plug-in that can help you easily restrict or extend access rights to various functions and features for any specific role in WordPress. The reviews of the plug-in alone speak for themselves. Even though the plug-in hasn't been adjusted for a few major releases, it serves its purpose perfectly and is also more than adequate due to its simplicity in user experience. I must also note that "<a target="_blank" href="https://de.wordpress.org/plugins/adminimize/">Adminimize</a>" is for me one of the standard plug-ins that I use on every website of my customers.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653240591691/3EDeOw16g.jpg" alt="1.jpg" /></p>
<h2 id="heading-the-standard-user-roles-are-often-not-sufficient-for-larger-teams">The standard user roles are often not sufficient for larger teams</h2>
<p><strong>But let’s come to the next problem:</strong> If you have ever worked with a larger content team on a WordPress site, you have certainly already made the experience that the default user roles are not always sufficient. Here you might have the role of the "Editor" optimally individualized in the access rights, but other users who may need similar access corrections, too much restricted or given too many options in the WordPress admin menu. Now, before you configure more default roles, which are also limited, in their access permissions, this may already be the moment when you realize or wish: **I would like to have more custom user roles to create a custom admin menu and optimize the security of the entire WordPress site.</p>
<h2 id="heading-the-plug-in-solution-to-solve-the-problem">The plug-in solution to solve the problem</h2>
<p>Of course, you can install another plug-in that can help you simplify the process of creating new user roles. The plug-in "<a target="_blank" href="https://de.wordpress.org/plugins/user-role-editor/">User Role Editor</a>" or similar solutions can be very helpful, but they can also lead to the fact that your database is quickly inflated and that the distribution of rights, individually created user roles, of individual users quickly become confusing when deactivating these plug-ins later.</p>
<hr />
<p>(Recommended method)</p>
<h1 id="heading-create-a-user-role-in-2-simple-steps">Create a user role in 2 simple steps 🏆</h1>
<p>My personal best practice is that we first duplicate / clone the admin user role using a custom code within functions.php. Following that, we use the "<a target="_blank" href="https://de.wordpress.org/plugins/adminimize/">Adminimize</a>" plugin mentioned above to restrict the rights of the newly created admin user role.</p>
<h3 id="heading-step-1-cloning-the-admin-user-role">Step 1: Cloning the admin user role</h3>
<p>To do this, we simply open our functions.php in our WordPress project and add the following function as an action call:</p>
<pre><code><span class="hljs-comment">// CLONE ADMIN ROLE AND RENAME THIS NEW ROLE "MARKETER"</span>
add_action(<span class="hljs-string">'init'</span>, <span class="hljs-string">'cloneExistingRole'</span>);

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">cloneExistingRole</span>(<span class="hljs-params"></span>)
</span>{
    <span class="hljs-keyword">global</span> $wp_roles;
    <span class="hljs-keyword">if</span> ( ! <span class="hljs-keyword">isset</span>( $wp_roles ) )
        $wp_roles = <span class="hljs-keyword">new</span> WP_Roles();

    $admx = $wp_roles-&gt;get_role(<span class="hljs-string">'administrator'</span>);
    $wp_roles-&gt;add_role(<span class="hljs-string">'new_role'</span>, <span class="hljs-string">'Marketer'</span>, $admx-&gt;capabilities);
}
</code></pre><p>This code creates a new administrator role named "<code>Marketer</code>". If you want the role to be named differently, simply rename the string named "<code>Marketer</code>" directly in the code.</p>
<p>⚠️ Once you have added the code to "functions.php", you will need to call your website once in the web browser, as this function will be executed via a WordPress add_action "init" hook and after a pageload. Once you have done this, the newly created role will already be available to you in the WordPress backend. The above code, you should remove after the execution of the page reload again from the "functions.php" because this does not need to be re-executed.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653249669885/QrUAE-5mP.png" alt="2.png" /></p>
<h3 id="heading-step-2-restrict-the-newly-created-admin-role-with-adminimize">Step 2: Restrict the newly created admin role with "Adminimize</h3>
<p>Install and activate the "<a target="_blank" href="https://de.wordpress.org/plugins/adminimize/">Adminimize</a>" plug-in. Navigate directly to the settings of the plug-in under "Settings &gt; Adminimize". From here you can easily customize and restrict the rights of your newly created "<code>Marketer</code>" user role. This is very straightforward and convenient.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1653249725624/D22yrM0i6.png" alt="3.png" /></p>
<h2 id="heading-you-want-to-delete-your-created-user-role-again">You want to delete your created user role again? 🗑</h2>
<p>Nothing is simpler than this: if you would like to remove the user role you created, of course you can undo it.</p>
<p>To remove a role called "<code>Marketer</code>", copy the following code again into your "functions.php" and then call your website in the web browser again.</p>
<p>⚠️ Attention: If you want to delete another role you created, please change the
following "<code>Marketer</code>" string to your desired role name:</p>
<pre><code><span class="hljs-comment">// DELETE CREATED ROLE</span>
add_action(<span class="hljs-string">'init'</span>, <span class="hljs-string">'killExistingRole'</span>);

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">killExistingRole</span>(<span class="hljs-params"></span>)
</span>{
    <span class="hljs-keyword">global</span> $wp_roles;
    <span class="hljs-keyword">if</span> ( ! <span class="hljs-keyword">isset</span>( $wp_roles ) )
        $wp_roles = <span class="hljs-keyword">new</span> WP_Roles();

    $admx = $wp_roles-&gt;get_role(<span class="hljs-string">'administrator'</span>);
    $wp_roles-&gt;remove_role(<span class="hljs-string">'new_role'</span>, <span class="hljs-string">'Marketer'</span>, $adm-&gt;capabilities);
}
</code></pre><p>After the reload (simple page load in the browser) of your WordPress website, I recommend you to delete the code renewed from the "functions.php" so that it is not executed renewed.</p>
<h2 id="heading-did-you-like-this-post">Did you like this post?</h2>
<p>Then feel free to leave me a comment or like.</p>
<p>This article is also available in German language 🇩🇪, you can <a target="_blank" href="https://plusquam.studio/downloads/articles/custom-user-roles-de.pdf">download it here</a>.</p>
]]></content:encoded></item></channel></rss>