<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>Daniel Auener</title><link>https://www.danielauener.com/</link><description>WordPress and web development</description><item><title>New Side Project - Re:Do Workouts App. Plan, train and track your routines</title><link>https://www.danielauener.com/new-side-project-redo-workouts-app-plan-train-and-track-your-routines/</link><guid isPermaLink="false">http://www.danielauener.com/?p=1025</guid><pubDate>Tue, 17 Mar 2026 07:40:05 GMT</pubDate><description>
		&lt;p&gt;I started training Shotokan karate about four years ago.&lt;/p&gt;
&lt;p&gt;A big part of our training is simple bodyweight workouts. Our sensei comes up with great exercises, but, as in many dojos, there isn’t really a written program you can follow at home. So when I trained outside the dojo, I constantly ran into the same problems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Which exercises did we do last week?&lt;/li&gt;
&lt;li&gt;What should I train today?&lt;/li&gt;
&lt;li&gt;What was that variation again?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I looked for an app to just write down exercises and run through them during training. But most fitness apps tried to coach me, motivate me, or sell me programs. Lots of perfect bodies, lots of promises, but not much help if you already know what you want to train.&lt;/p&gt;
&lt;p&gt;So I built Re:Do. It’s basically a simple tool to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;add exercises (often just a title is enough)&lt;/li&gt;
&lt;li&gt;plan workouts across the week&lt;/li&gt;
&lt;li&gt;start a workout and follow it while training&lt;/li&gt;
&lt;li&gt;track what you actually did&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No muscles on the screen. No fitness industry nonsense. Just your exercises and your training.&lt;/p&gt;
&lt;p&gt;I’d love to hear what you think, especially if you do bodyweight training, martial arts, or similar disciplines.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://apps.apple.com/se/app/re-do-workouts/id6758432516&quot;&gt;&lt;img class=&quot;alignnone size-full wp-image-1032&quot; src=&quot;https://www.danielauener.com/assets/media/original/d4c228673a50a92ab6a4.png&quot; alt=&quot;&quot; width=&quot;170&quot; height=&quot;65&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.producthunt.com/products/re-do-workouts?embed=true&amp;amp;utm_source=badge-featured&amp;amp;utm_medium=badge&amp;amp;utm_campaign=badge-re-do-workouts&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;img src=&quot;https://www.danielauener.com/assets/media/original/eae40b503c27b606608c.svg&quot; alt=&quot;Re:Do Workouts - A workout app for people who already know what they train. | Product Hunt&quot; width=&quot;250&quot; height=&quot;54&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.danielauener.com/assets/media/original/218e1c54993c38d8c62b.png&quot;&gt;&lt;img class=&quot;alignnone  wp-image-1030&quot; src=&quot;https://www.danielauener.com/assets/media/original/218e1c54993c38d8c62b.png&quot; alt=&quot;&quot; width=&quot;278&quot; height=&quot;602&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/218e1c54993c38d8c62b.png 1242w, https://www.danielauener.com/assets/media/original/c215e58cb5a9f001d306.png 139w, https://www.danielauener.com/assets/media/original/9315cbeffeca27d62f06.png 768w, https://www.danielauener.com/assets/media/original/a55e05f08e622a4e0d11.png 473w&quot; sizes=&quot;(max-width: 278px) 100vw, 278px&quot;&gt; &lt;/a&gt;&lt;a href=&quot;https://www.danielauener.com/assets/media/original/ca77c07dd3d313330c1c.png&quot;&gt;&lt;img class=&quot;alignnone  wp-image-1028&quot; src=&quot;https://www.danielauener.com/assets/media/original/ca77c07dd3d313330c1c.png&quot; alt=&quot;&quot; width=&quot;281&quot; height=&quot;611&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/ca77c07dd3d313330c1c.png 1206w, https://www.danielauener.com/assets/media/original/cd788617192acc0b5d09.png 138w, https://www.danielauener.com/assets/media/original/28629c20b3a64c00e001.png 768w, https://www.danielauener.com/assets/media/original/cde715e53eadbd25bd2f.png 471w&quot; sizes=&quot;(max-width: 281px) 100vw, 281px&quot;&gt;&lt;/a&gt;&lt;a href=&quot;https://www.danielauener.com/assets/media/original/6fb6d338d6f3bd064e08.png&quot;&gt; &lt;img class=&quot;alignnone  wp-image-1027&quot; src=&quot;https://www.danielauener.com/assets/media/original/6fb6d338d6f3bd064e08.png&quot; alt=&quot;&quot; width=&quot;282&quot; height=&quot;613&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/6fb6d338d6f3bd064e08.png 1206w, https://www.danielauener.com/assets/media/original/9c7cfd6b065f7a2c1b71.png 138w, https://www.danielauener.com/assets/media/original/2fba248e38513ab7118d.png 768w, https://www.danielauener.com/assets/media/original/91a4e7c7177dc71bd902.png 471w&quot; sizes=&quot;(max-width: 282px) 100vw, 282px&quot;&gt;&lt;/a&gt; &lt;a href=&quot;https://www.danielauener.com/assets/media/original/7e363c3812ec20052a66.png&quot;&gt;&lt;img class=&quot;alignnone  wp-image-1029&quot; src=&quot;https://www.danielauener.com/assets/media/original/7e363c3812ec20052a66.png&quot; alt=&quot;&quot; width=&quot;282&quot; height=&quot;610&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/7e363c3812ec20052a66.png 1242w, https://www.danielauener.com/assets/media/original/695d7e219640645053e4.png 139w, https://www.danielauener.com/assets/media/original/75f08f53bf79af72c647.png 768w, https://www.danielauener.com/assets/media/original/6d6366bd1a0a92692c0d.png 473w&quot; sizes=&quot;(max-width: 282px) 100vw, 282px&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
	</description></item><item><title>The WordPresser’s Guide to the Fediverse</title><link>https://www.danielauener.com/the-wordpressers-guide-to-the-fediverse/</link><guid isPermaLink="false">http://www.danielauener.com/?p=993</guid><pubDate>Sat, 17 Dec 2022 15:55:15 GMT</pubDate><description>
		&lt;blockquote&gt;&lt;p&gt;“&lt;b&gt;Far Out in the uncharted backwaters of the unfashionable end of the Western Spiral arm of the galaxy lies a small unregarded yellow sun&lt;/b&gt;.”&lt;br&gt;
– Douglas Adams, The Hitchhikers Guide to the Galaxy&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;A little solar system, far away, insignificant and quite an odd place to be. That’s how one of my favorite books describes where we all live. I think, despite the current rise in users, Mastodon and the Fediverse still look that way to many people.&lt;/p&gt;
&lt;p&gt;My impression is that this is true for a significant part of my favorite community as well. &lt;a href=&quot;https://mastodon.chriswiegman.com/@chris&quot;&gt;Chris Wiegman&lt;/a&gt; wrote a powerful text on why &lt;a href=&quot;https://chriswiegman.com/2022/11/wordpress-should-embrace-the-fediverse/&quot;&gt;WordPress should embrace the Fediverse&lt;/a&gt;, so that is covered. I want to focus more on how to migrate and not the “why”.&lt;/p&gt;
&lt;p&gt;For everyone in the WordPress community who is just one last step away from leaving the commercialized and in many ways poisoned corporate social networks behind. Here is my guide to finding our little WordPress place on Mastodon in this huge collection of instances, blogs and applications we call the Fediverse.&lt;/p&gt;
&lt;h2&gt;Find an Instance&lt;/h2&gt;
&lt;p&gt;Mastodon is a decentralized network of instances (running the free Mastodon software) independently hosted, driven and funded by individuals with a wide range of intentions, goals and approaches. &lt;strong&gt;Sound familiar? Precisely!&lt;/strong&gt; Working with WordPress or within the WordPress community, you should feel right at home. The WordPress blogging community and the Mastodon tooting community share much of the same foundation.&lt;/p&gt;
&lt;p&gt;Take the same approach for finding an instance as for finding a blog you follow and ask yourself:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What is the instance about?&lt;/li&gt;
&lt;li&gt;Who is running it?&lt;/li&gt;
&lt;li&gt;What are the moderation rules?&lt;/li&gt;
&lt;li&gt;Who else is here?&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;WordPress Mastodon Instances&lt;/h3&gt;
&lt;p&gt;If you want to consume a lot of WordPress content and/or intend to post some WordPress stuff yourself, a WordPress-related instance might be a good choice. The chances of finding a like-minded community and meaningful discourse are good. I host the WordPress instance &lt;a href=&quot;https://wptoots.social&quot;&gt;wptoots.social&lt;/a&gt;; you’re welcome to join, but there are some other good choices:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://wpbuilds.social&quot;&gt;&lt;strong&gt;wpbuilds.social&lt;/strong&gt;&lt;/a&gt; (currently 47 active users) – hosted by Nathan Wrigley (&lt;a href=&quot;https://wpbuilds.social/@nathan&quot;&gt;@nathan@wpbuilds.social&lt;/a&gt;) maker of the WP Builds Podcast&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dewp.space&quot;&gt;&lt;strong&gt;dewp.space&lt;/strong&gt;&lt;/a&gt; (currently 30 active users) – seems like a good choice if you feel at home in the German WordPress community&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://wp-social.net&quot;&gt;wp-social.net&lt;/a&gt;&lt;/strong&gt; (currently 33 active users) – hosted by a WordPress hosting service&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://wptoots.social&quot;&gt;wptoots.social&lt;/a&gt;&lt;/strong&gt; (currently 46 active users) – hosted by me&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://fosstodon.org&quot;&gt;&lt;strong&gt;fosstodon.org&lt;/strong&gt;&lt;/a&gt; (currently 26k active users) – if your interests are more about free software in general and you want a bigger instance&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://phpc.social&quot;&gt;phpc.social&lt;/a&gt; &lt;/strong&gt;(currently 2.1k active users) – if you see things more from the PHP side&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To make your decision, I recommend starting by looking at the local timeline of an instance, if available without registration. That tells you what instance members have been up to. It also shows what you can expect regarding topics, posting frequency and tone of conversation. Take a look at the profile directory of each instance as well. And, of course, read the rules on the about page.&lt;/p&gt;
&lt;p&gt;Many instances have more detailed community guides as well. These are interesting to learn more about how moderation works and what the instance’s members expect from you. For wptoots.social you can find our guide at &lt;a href=&quot;https://community.wptoots.social&quot;&gt;community.wptoots.social&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Moving to another instance&lt;/h3&gt;
&lt;p&gt;A few words about moving to another instance. Perhaps you started on a more general instance and want to move to a WordPress-specific one. There is a documented &lt;a href=&quot;https://blog.joinmastodon.org/2019/06/how-to-migrate-from-one-server-to-another/&quot;&gt;process for moving&lt;/a&gt;, which works quite well. Moving works as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;You keep your followers even on the new instance&lt;/li&gt;
&lt;li&gt;You can export a list of people you follow and re-follow all of them easily from the new instance&lt;/li&gt;
&lt;li&gt;Old posts stay on your old instance&lt;/li&gt;
&lt;li&gt;After you have moved, the old account from your previous instance (don’t delete it) will redirect to the new account&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All in all, I think you can move without risks, especially if you don’t have a very large account.&lt;/p&gt;
&lt;h2&gt;Find people to follow&lt;/h2&gt;
&lt;p&gt;You’ve chosen your Fediverse home! Now you have to find people to follow and build a following. That can be tricky, because of the decentralized nature of Mastodon. The search function on your instance is limited to the content your instance “knows” about. That basically means what you can find in the federated timeline, which includes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Content and users on your instance&lt;/li&gt;
&lt;li&gt;Users followed by people on your instance, and their posts. These are the accounts they are are following&lt;/li&gt;
&lt;li&gt;Posts and users from relayed instances&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So if you search for WordPress, be aware that the search doesn’t show every WordPress post from across the entire Fediverse.&lt;/p&gt;
&lt;h3&gt;The WordPress community on Mastodon&lt;/h3&gt;
&lt;p&gt;If you are looking for WordPress folks to follow, I’ve got just the right thing for you. I’m curating a &lt;a href=&quot;https://wp-community-on-mastodon.wptoots.social/&quot;&gt;list of WordPress community members on Mastodon&lt;/a&gt;. Everyone on the list has at least one community badge on profiles.wordpress.org.&lt;/p&gt;
&lt;p&gt;I’m always looking for new list members. There is a description of how to get onto the list on the website. Sharing is appreciated.&lt;/p&gt;
&lt;h3&gt;Follow #Hashtags&lt;/h3&gt;
&lt;p&gt;Additionally, another good way of keeping track of specific topics is following hashtags. First search for a hashtag on your instance (e.g. #wordpress). Then, follow by clicking the small follow icon to the right, above the hashtag content.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.danielauener.com/assets/media/original/89a2831e11db1599c25d.png&quot;&gt;&lt;img class=&quot;aligncenter wp-image-1004 size-full&quot; src=&quot;https://www.danielauener.com/assets/media/original/89a2831e11db1599c25d.png&quot; alt=&quot;&quot; width=&quot;593&quot; height=&quot;75&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/89a2831e11db1599c25d.png 593w, https://www.danielauener.com/assets/media/original/4135b90b6973998468f1.png 300w&quot; sizes=&quot;(max-width: 593px) 100vw, 593px&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Find posts from users on unconnected instances&lt;/h3&gt;
&lt;p&gt;Every now and then (actually more and more) someone shares a Mastodon post or user with me in a chat or something. The problem is that following that link directs me to the user’s instance (not my own). So boosting, following and liking don’t work directly, because I don’t have an account on that instance. However, clicking on the boost icon of a post shows the following dialog:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.danielauener.com/assets/media/original/1548d5a0e6343971c91f.png&quot;&gt;&lt;img class=&quot;wp-image-1007 size-full aligncenter&quot; src=&quot;https://www.danielauener.com/assets/media/original/1548d5a0e6343971c91f.png&quot; alt=&quot;&quot; width=&quot;723&quot; height=&quot;604&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/1548d5a0e6343971c91f.png 723w, https://www.danielauener.com/assets/media/original/4592d3d799bfc33a85ed.png 300w&quot; sizes=&quot;(max-width: 723px) 100vw, 723px&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now, you only have to copy the value in the “On a different server” input field and paste it to your instance’s (or app’s) search field. The same works for following a user. Now you will see the post or user via your instance and can follow, boost, like and answer.&lt;/p&gt;
&lt;h3&gt;Find bots to fill your timeline with interesting things&lt;/h3&gt;
&lt;p&gt;If you are like me and use your social timeline as a source of news, blog-posts etc, you might be interested in finding some bots that post relevant content. Bots can be a really great way to keep track of new content, but clearly they can be very annoying as well. On &lt;a href=&quot;https://wptoots.social&quot;&gt;wptoots.social&lt;/a&gt; we run a &lt;a href=&quot;https://wpbot.wptoots.social&quot;&gt;WordPress bot&lt;/a&gt;, watching sources curated by the community on GitHub, which I think is a great addition to my timeline!&lt;/p&gt;
&lt;h2&gt;Engage with the community&lt;/h2&gt;
&lt;p&gt;Now, you know how to do things, you just have to start doing them! The first step should be to set up a nice profile. You know the drill from every other social platform. Try to make it unique and ensure it says something about you. Write a short, informative bio and use hashtags in it to show your topics.&lt;/p&gt;
&lt;p&gt;A nice way to make a statement and catch the eye of potential followers is an emoji in your nickname (where the birdsite’s verification badge is). On WordPress-related servers you might have a WordPress icon available. Here is an example on my profile:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.danielauener.com/assets/media/original/d43f7e63f686e11cbaec.png&quot;&gt;&lt;img class=&quot;wp-image-1009 size-full aligncenter&quot; src=&quot;https://www.danielauener.com/assets/media/original/d43f7e63f686e11cbaec.png&quot; alt=&quot;&quot; width=&quot;580&quot; height=&quot;480&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/d43f7e63f686e11cbaec.png 580w, https://www.danielauener.com/assets/media/original/e98c5bb01ad73acda16c.png 300w&quot; sizes=&quot;(max-width: 580px) 100vw, 580px&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Above you see that you can even use emojis in your bio, where we have a really special treat on &lt;a href=&quot;https://wptoots.social&quot;&gt;wptoots.social&lt;/a&gt;. For every existing badge on &lt;strong&gt;profiles.wordpress.org&lt;/strong&gt; we have a corresponding emoji. So I can integrate the icons from my WordPress profile page (and only those) in my Mastodon bio and show everyone what I stand for:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.danielauener.com/assets/media/original/30df15ba030eb6fd4de4.png&quot;&gt;&lt;img class=&quot;size-full wp-image-1010 aligncenter&quot; src=&quot;https://www.danielauener.com/assets/media/original/30df15ba030eb6fd4de4.png&quot; alt=&quot;&quot; width=&quot;965&quot; height=&quot;235&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/30df15ba030eb6fd4de4.png 965w, https://www.danielauener.com/assets/media/original/1ec7fdab83d756f37315.png 300w, https://www.danielauener.com/assets/media/original/a827d5bee1d2c8c750bf.png 768w&quot; sizes=&quot;(max-width: 965px) 100vw, 965px&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you’re looking for real verification (not a blue verification icon everyone can use), you might want to verify your blog or website, as you can see in my Mastodon profile above. There are quite a &lt;a href=&quot;https://ljpuk.net/2022/11/09/how-to-verify-your-wordpress-blog-with-mastodon/&quot;&gt;few&lt;/a&gt; &lt;a href=&quot;https://g13g.blog/2022/11/09/how-to-verify-your-wordpress-site-on-mastodon/&quot;&gt;manuals&lt;/a&gt; for doing &lt;a href=&quot;https://jeff.blog/2022/11/how-to-verify-your-wordpress-site-on-mastodon/&quot;&gt;that&lt;/a&gt;, and &lt;a href=&quot;https://wordpress.org/plugins/simple-mastodon-verification/&quot;&gt;some plugins&lt;/a&gt; as well.&lt;/p&gt;
&lt;h2&gt;Join the WordPress Community on Mastodon and the Fediverse&lt;/h2&gt;
&lt;p&gt;Finishing our small journey through the Fediverse for WordPress folks, I can only say: &lt;em&gt;&lt;strong&gt;Please join us, it’s incredibly fun&lt;/strong&gt;&lt;/em&gt;. In one Mastodon month I have connected and talked with more WordPress people than in several birdsite years. Concluding with Douglas Adams, of course:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;em&gt;The chances of finding out what’s really going on in the universe are so remote, the only thing to do is hang the sense of it and keep yourself occupied.&lt;br&gt;
&lt;/em&gt;– The Hitchhikers Guide to the Galaxy&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt; &lt;/p&gt;
	</description></item><item><title>10 Reasons a Mastodon Migration Makes Sense for the WordPress Community (and others)</title><link>https://www.danielauener.com/10-reasons-a-mastodon-migration-makes-sense-for-the-wordpress-community-and-others/</link><guid isPermaLink="false">http://www.danielauener.com/?p=965</guid><pubDate>Thu, 08 Dec 2022 22:12:16 GMT</pubDate><description>
		&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Mastodon_(social_network)&quot;&gt;Mastodon&lt;/a&gt;, a decentralized social media/microblogging platform, has become quite popular over the past weeks and months. There are many good reasons to consider a Mastodon migration, but for free software enthusiasts or WordPress lovers (like me), there are even more specific reasons to give Mastodon a try. I hope you find my reasons compelling, even if I’m biased because I run the WordPress-centered Mastodon instance &lt;a href=&quot;https://wptoots.social&quot;&gt;wptoots.social&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;1. You can choose a Mastodon instance relevant to the topics you are most interested in&lt;/h2&gt;
&lt;p&gt;Mastodon is decentralized and there are thousands of instances to choose from. So pick a home to start your Mastodon journey carefully! If you are specifically interested in WordPress, sign up on a WordPress-centered instance and become a part of its WordPress-centered community. You will instantly find people with the same interests!&lt;/p&gt;
&lt;p&gt;Also take into account that little instances are more at risk of shutting down, while big instances can be hit by so many users that they might get slow at times. You can move your account, including followers, to another instance at any time (your posts will be left on the “old” instance, though).&lt;/p&gt;
&lt;h2&gt;2. The local timeline&lt;/h2&gt;
&lt;p&gt;On Mastodon you have three timelines. A home, local and federated timeline.&lt;/p&gt;
&lt;p&gt;&lt;a title=&quot;Cassolotl, CC0, via Wikimedia Commons&quot; href=&quot;https://commons.wikimedia.org/wiki/File:Mastodon_timelines.png&quot;&gt;&lt;img class=&quot;aligncenter&quot; src=&quot;https://www.danielauener.com/assets/media/original/fe7c74042d8c25f7127a.png&quot; alt=&quot;Mastodon timelines&quot; width=&quot;512&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you have chosen a Mastodon instance, related to a topic you’re interested in, the local timeline might be the most interesting for you. Here you only see posts from users of your instance and, at least for the WordPress instances, they are right on topic most of the time. The home and federated timelines are a broader look into what’s going on with the people you follow and the people users on your instance follow.&lt;/p&gt;
&lt;h2&gt;3. Instance rules let you post, share and discuss in a safe environment&lt;/h2&gt;
&lt;p&gt;Every instance has its own rules. Everyone signing up agrees to them, and anyone violating them gets suspended (if moderators do their job, which they do in almost every case). So unlike many other platforms, you know what you’re signing up for and what you can expect. If you want to discuss WordPress professionally, you’ll just have to find an instance with a matching set of rules.&lt;/p&gt;
&lt;p&gt;There is an argument that instances, and users choosing instances, can contribute to even stronger discourse and opinion bubbles. I think it’s too early to say if that’s true. But my hope is that there is a big difference between actively and consciously picking a community – and being influenced by an algorithm that makes you believe the whole world thinks like you.&lt;/p&gt;
&lt;h2&gt;4. Your content is not monetized&lt;/h2&gt;
&lt;p&gt;Content you produce and thoughts that you share shouldn’t be monetized without your active approval and only with the methods you have agreed to. Period.&lt;/p&gt;
&lt;h2&gt;5. Your content is not ranked by an algorithm optimized for engagement&lt;/h2&gt;
&lt;p&gt;Engagement, likes, shares and clicks are the daily bread and butter of commercial social media platforms. Of course their algorithms are optimized to encourage engagement which often favors polarized opinions and heated discussions.&lt;/p&gt;
&lt;p&gt;They are not optimized, though, to favor more complex professional thoughts, balanced argumentation or input that broadens your professional point of view. But that’s what we can get on Mastodon with our WordPress postings.&lt;/p&gt;
&lt;h2&gt;6. Mastodon is built, owned, funded and driven by its community&lt;/h2&gt;
&lt;p&gt;The Mastodon Community is running Mastodon. It’s actually amazing that that’s working, if you think about it. But there are other examples, aren’t there? The WordPress project comes to mind and all the other FOSS projects! It would seem like there is no better fit for the WordPress Community than a Community-driven social network …&lt;/p&gt;
&lt;h2&gt;7. Mastodon is Free Software&lt;/h2&gt;
&lt;p&gt;You can’t argue with that one, can you?&lt;/p&gt;
&lt;h2&gt;8. Mastodon can’t be bought&lt;/h2&gt;
&lt;p&gt;Another obvious one, but there is more to it. Even if Mastodon could be bought (and single instances surely can), every admin in the community decides independently when to upgrade. If you don’t like the direction Mastodon is taking, you can fork it and run your own version. There is great power in that: Nothing can be changed without the explicit approval of the community. Democracy by design. And guess which other community can’t be bought either? You guessed right.&lt;/p&gt;
&lt;h2&gt;9. Most communities on Mastodon are actually nice&lt;/h2&gt;
&lt;p&gt;That might be changing over time, but for now I think this is true: Big parts of the community are positive, inclusive, accepting and open. Most people migrating are tired of the vibe of the big commercial platforms and actively working toward more constructive behavior on their new platform. And who knows? Maybe community-driven social networks are just nicer!&lt;/p&gt;
&lt;h2&gt;10. Meaningful exchange seems to be the rule not the exception on Mastodon&lt;/h2&gt;
&lt;p&gt;That’s more of a personal experience over the last weeks on my own instance. Everything I put out there (especially the WordPress and/or community-relevant stuff) is followed by meaningful comments, some good discussions, cheering and sharing. I’ve really learned a lot and find the response from my social network on Mastodon to be quite uplifting and enlightening. I’ve never felt that on the birdsite, to be honest.&lt;/p&gt;
&lt;h2&gt;Start your Mastodon migration&lt;/h2&gt;
&lt;p&gt;Convinced? Here are some starting points for your Mastodon migration:&lt;/p&gt;
&lt;p&gt;Find an instance! If you’re looking for the WordPress community you are welcome to &lt;a href=&quot;https://wptoots.social&quot;&gt;wptoots.social.&lt;/a&gt; Or try one of the other WordPress instances (I know of) &lt;a href=&quot;https://wpbuilds.social&quot;&gt;wpbuilds.social&lt;/a&gt; or &lt;a href=&quot;https://wp-social.net&quot;&gt;wp-social.net&lt;/a&gt;. If you are not only into WordPress, a bigger instance like &lt;a href=&quot;https://fosstodon.org/&quot;&gt;fosstodon.org&lt;/a&gt; might be the right thing for you.&lt;/p&gt;
&lt;p&gt;Find your community! That is incredibly difficult in the beginning and motivated me to make a &lt;a href=&quot;https://wp-community-on-mastodon.wptoots.social&quot;&gt;list&lt;/a&gt;. Everyone on it has at least one community badge on profiles.wordpress.org and has agreed to be listed.&lt;/p&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
&lt;p&gt;Share!&lt;/p&gt;
	</description></item><item><title>Mastodon WordPress Instance</title><link>https://www.danielauener.com/mastodon-wordpress-instance/</link><guid isPermaLink="false">http://www.danielauener.com/?p=946</guid><pubDate>Sat, 19 Nov 2022 06:36:40 GMT</pubDate><description>
		&lt;p&gt;While I’m at it, I thought a Mastodon WordPress instance for community members looking for a home on Mastodon would be cool.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://wptoots.social&quot;&gt;https://wptoots.social&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Mastodon as a decentralized social network seems like the perfect fit for a group as diverse and strong as the WordPress community. The instance should be able to handle a couple of hundred users, is actively maintained and has daily backups.&lt;/p&gt;
&lt;p&gt;There is even a curated list of the &lt;a href=&quot;https://wp-community-on-mastodon.wptoots.social/&quot;&gt;WordPress Community on Mastodon&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;And I promise: The instance will run indefinitely!&lt;/p&gt;
&lt;p&gt;As a little extra you can add a WordPress badge in your nickname (like Twitter’s verified icon) and show the entire fediverse what you stand for.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.danielauener.com/assets/media/original/e7abe2acb65cbb829321.png&quot;&gt;&lt;img class=&quot;alignnone size-full wp-image-952&quot; src=&quot;https://www.danielauener.com/assets/media/original/e7abe2acb65cbb829321.png&quot; alt=&quot;&quot; width=&quot;241&quot; height=&quot;66&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/e7abe2acb65cbb829321.png 241w, https://www.danielauener.com/assets/media/original/c987ea806679097e07a1.png 240w&quot; sizes=&quot;(max-width: 241px) 100vw, 241px&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I hope everyone out there who loves WordPress will share this and join! And follow me if you like:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://wptoots.social/@danielauener&quot; rel=&quot;me&quot;&gt;@danielauener@wptoots.social&lt;/a&gt;&lt;/p&gt;
	</description></item><item><title>Mastodon Instance for Kalmar started</title><link>https://www.danielauener.com/mastodon-kalmar-instance/</link><guid isPermaLink="false">http://www.danielauener.com/?p=937</guid><pubDate>Sun, 13 Nov 2022 11:13:34 GMT</pubDate><description>
		&lt;p&gt;This might even become a reboot for this sleepy blog! I’ve started a new Mastodon instance for my hometown, Kalmar:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://kalmar.social&quot;&gt;https://kalmar.social&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Aside from the technical stuff, decentralization really sparked my interest and might be something to write about in the future!&lt;/p&gt;
&lt;p&gt;Drop me a note if you have any insights, people to follow or texts to read.&lt;/p&gt;
&lt;p&gt;Photo by &lt;a href=&quot;https://unsplash.com/@einfachlaurenz?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText&quot;&gt;Laurenz Heymann&lt;/a&gt; on &lt;a href=&quot;https://unsplash.com/s/photos/kalmar?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText&quot;&gt;Unsplash&lt;/a&gt;&lt;/p&gt;
	</description></item><item><title>WordPress REST API extensions for going headless WP</title><link>https://www.danielauener.com/wordpress-rest-api-extensions-for-going-headless-wp/</link><guid isPermaLink="false">http://www.danielauener.com/?p=906</guid><pubDate>Tue, 14 May 2019 21:04:54 GMT</pubDate><description>
		&lt;p&gt;&lt;b&gt;Current WordPress REST API extension list&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#front&quot;&gt;Front-page endpoint&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#menu&quot;&gt;Menu endpoint&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#tax&quot;&gt;Taxonomy filter attribute&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#acf&quot;&gt;Integrating ACF meta fields&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#yoast&quot;&gt;Integrating Yoast meta fields&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#slug&quot;&gt;Slug endpoint for posts and pages&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you want to have all the endpoints as a plugin, there is one in the plugin directory: &lt;a href=&quot;https://wordpress.org/plugins/wuxt-headless-wp-api-extensions/&quot;&gt;WUXT Headless WordPress API Extensions&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I love the WordPress REST API and am switching more and more from theme development to a headless WP approach, with a nice front-end framework. Right now I’m favoring Nuxt.js, which is built on Vue.js (check out &lt;a href=&quot;https://github.com/northosts/wuxt&quot;&gt;wuxt&lt;/a&gt;, my very own &lt;a href=&quot;https://www.danielauener.com/nuxt-js-wordpress-wuxt/&quot;&gt;dockerized nuxt/wp development environment&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;To use WordPress’s full potential with the REST API I’ve collected and built a useful snippet library with WordPress REST API extensions. I’ll try to maintain the following list as development goes on. All of the following extensions can be embedded in the &lt;code&gt;functions.php&lt;/code&gt; file. If you’re wondering about the &lt;b&gt;wuxt_&lt;/b&gt; prefix, I’ve got the code from my Wuxt project and the prefix is as good as any other.&lt;/p&gt;
&lt;h2 id=&quot;front&quot;&gt;Front-page extension&lt;/h2&gt;
&lt;p&gt;Everything starts with a nice front-page, but there is no obvious way to get the WordPress front-page via the REST API. To read the settings, you have to be authorized, which makes things unnecessarily complicated. So here is a custom endpoint for getting the front-page.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GET: /wp-json/wp/v2/front-page&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
&amp;lt;?php

/**
 * Adds a front-page endpoint for generell front-page settings in the
 * Front-end
 */
add_action( &amp;#39;rest_api_init&amp;#39;, &amp;#39;wuxt_front_page_route&amp;#39; );


function wuxt_front_page_route() {
    register_rest_route( &amp;#39;wp&amp;#39;, &amp;#39;/v2/front-page&amp;#39;, array(
        &amp;#39;methods&amp;#39;  =&amp;gt; &amp;#39;GET&amp;#39;,
        &amp;#39;callback&amp;#39; =&amp;gt; &amp;#39;wuxt_get_front_page&amp;#39;
    ) );
}


function wuxt_get_front_page( $object ) {

    $request  = new WP_REST_Request( &amp;#39;GET&amp;#39;, &amp;#39;/wp/v2/posts&amp;#39; );

    $frontpage_id = get_option( &amp;#39;page_on_front&amp;#39; );
    if ( $frontpage_id ) {
      $request  = new WP_REST_Request( &amp;#39;GET&amp;#39;, &amp;#39;/wp/v2/pages/&amp;#39; . $frontpage_id );
    }

    $response = rest_do_request( $request );
    if ($response-&amp;gt;is_error()) {
        return new WP_Error( &amp;#39;wuxt_request_error&amp;#39;, __( &amp;#39;Request Error&amp;#39; ), array( &amp;#39;status&amp;#39; =&amp;gt; 500 ) );
    }

    $embed = $object-&amp;gt;get_param( &amp;#39;_embed&amp;#39; ) !== NULL;
    $data = rest_get_server()-&amp;gt;response_to_data( $response, $embed );

    return $data;

}

?&amp;gt;
&lt;/pre&gt;
&lt;h2 id=&quot;menu&quot;&gt;Menus&lt;/h2&gt;
&lt;p&gt;Right now, there is no way I know of for getting menus from the WordPress REST API. I’m not sure if it’s the most effective way, but here is my WordPress REST API custom endpoint for menus. It also registers a standard ‘main’ menu as default if no location is requested.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Note: Most of the work for this snippet is done by the &lt;a href=&quot;https://gist.github.com/michaeland/191ce08d22fed74da05a&quot;&gt; menu-class of Michael Cox&lt;/a&gt;, you have to include it to get the endpoint to work.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GET: /wp-json/wp/v2/menu?location=&amp;lt;location&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
&amp;lt;?php

/**
 * Adds a menu endpoint
 */
require_once(&amp;#39;/path/to/Menu.php&amp;#39;);

add_action(&amp;#39;init&amp;#39;, &amp;#39;wuxt_register_menu&amp;#39;);
add_action(&amp;#39;rest_api_init&amp;#39;, &amp;#39;wuxt_route_menu&amp;#39;);

function wuxt_register_menu()
{
    register_nav_menu(&amp;#39;main&amp;#39;, __(&amp;#39;Main meny&amp;#39;));
}

function wuxt_route_menu()
{
    register_rest_route(&amp;#39;wp&amp;#39;, &amp;#39;/v2/menu&amp;#39;, array(
        &amp;#39;methods&amp;#39; =&amp;gt; &amp;#39;GET&amp;#39;,
        &amp;#39;callback&amp;#39; =&amp;gt; &amp;#39;wuxt_get_menu&amp;#39;,
    ));
}

function wuxt_get_menu($params)
{
    $params = $params-&amp;gt;get_params();
    $theme_locations = get_nav_menu_locations();

    if (!isset($params[&amp;#39;location&amp;#39;])) {
        $params[&amp;#39;location&amp;#39;] = &amp;#39;main&amp;#39;;
    }

    if ( ! isset( $theme_locations[$params[&amp;#39;location&amp;#39;]] ) ) {
        return new WP_Error( &amp;#39;wuxt_menu_error&amp;#39;, __( &amp;#39;Menu location does not exist&amp;#39; ), array( &amp;#39;status&amp;#39; =&amp;gt; 404 ) );
    }

    $menu_obj = get_term( $theme_locations[$params[&amp;#39;location&amp;#39;]], &amp;#39;nav_menu&amp;#39; );
    $menu_name = $menu_obj-&amp;gt;name;
    $menu = new Menu( $menu_name );
    return $menu-&amp;gt;getTree();
}

?&amp;gt;
&lt;/pre&gt;
&lt;h2 id=&quot;tax&quot;&gt;Filtering Categories and taxonomies&lt;/h2&gt;
&lt;p&gt;When filtering taxonomies with a REST API request, you are stuck with OR-queries, because the category endpoint doesn’t give you the full complexity of a tax_query. That means you can get posts which are either in category A or B. The following adjustment doesn’t give you the full complexity either, but it lets you switch all tax_queries to an AND-relation, so that you can select posts which are both in category A and B. &lt;/p&gt;
&lt;p&gt;&lt;code&gt;GET: /wp-json/wp/v2/posts/?categories=1,2&amp;amp;and=true&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
&amp;lt;?php

  /**
   * Ads AND relation on rest category filter queries
   */
  add_action( &amp;#39;pre_get_posts&amp;#39;, &amp;#39;wuxt_override_relation&amp;#39; );

  function wuxt_override_relation( $query ) {

    // bail early when not a rest request
  	if ( ! defined( &amp;#39;REST_REQUEST&amp;#39; ) || ! REST_REQUEST ) {
  		return;
  	}

    // check if we want to force an &amp;quot;and&amp;quot; relation
    if ( ! isset( $_GET[&amp;#39;and&amp;#39;] ) || !$_GET[&amp;#39;and&amp;#39;] || &amp;#39;false&amp;#39; === $_GET[&amp;#39;and&amp;#39;] || !is_array( $tax_query = $query-&amp;gt;get( &amp;#39;tax_query&amp;#39; ) ) ) {
  		return;
  	}

    foreach ( $tax_query as $index =&amp;gt; $tax ) {
      $tax_query[$index][&amp;#39;operator&amp;#39;] = &amp;#39;AND&amp;#39;;
    }

  	$query-&amp;gt;set( &amp;#39;tax_query&amp;#39;, $tax_query );

  }

?&amp;gt;
&lt;/pre&gt;
&lt;h2 id=&quot;acf&quot;&gt;Loading ACF Meta-fields&lt;/h2&gt;
&lt;p&gt;Integrating meta-fields from the Advanced-Custom-Fields plugin into the REST API responses can be done with &lt;a href=&quot;https://github.com/airesvsg/acf-to-rest-api&quot;&gt;this plugin&lt;/a&gt;. If you need a simpler solution (only integrating meta fields into post-objects, not writing them), or simply a bit more control, the following snippet can get you started. It sets all ACF-fields to &lt;code&gt;show_in_rest&lt;/code&gt;, which lets them appear in the post-objects meta-section:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
&amp;lt;?php

    /**
     * Register meta fields from ACF
     */
    add_action( &amp;#39;init&amp;#39;, &amp;#39;wuxt_register_acf_meta&amp;#39; );

    function wuxt_register_acf_meta() {

        if( function_exists( &amp;#39;acf_get_field_groups&amp;#39; ) ){
            $result = array();
            $acf_field_groups = acf_get_field_groups();
            foreach( $acf_field_groups as $acf_field_group) {
                foreach($acf_field_group[&amp;#39;location&amp;#39;] as $group_locations) {
                    foreach($group_locations as $rule) {
                        foreach(acf_get_fields( $acf_field_group ) as $field) {
                            register_meta( &amp;#39;post&amp;#39;, $field[&amp;#39;name&amp;#39;], array( &amp;#39;show_in_rest&amp;#39; =&amp;gt; true ) );
                        }
                    }

                }

            }
        }

    }

?&amp;gt;
&lt;/pre&gt;
&lt;h2 id=&quot;yoast&quot;&gt;SEO-Data&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;register_meta&lt;/code&gt; trick is handy, even for other plugins. If you want to integrate data from &lt;a href=&quot;https://wordpress.org/plugins/wordpress-seo/&quot;&gt;our favorite SEO add-on&lt;/a&gt;, &lt;strong&gt;Yoast WordPress SEO&lt;/strong&gt;, into the post objects, you can do it like that:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
&amp;lt;?php

    /**
     * Register meta fields for WordPress SEO
     */
    add_action( &amp;#39;init&amp;#39;, &amp;#39;wuxt_register_yoast_meta&amp;#39; );

    function wuxt_register_yoast_meta() {
      if(in_array(&amp;#39;wordpress-seo/wp-seo.php&amp;#39;, apply_filters(&amp;#39;active_plugins&amp;#39;, get_option(&amp;#39;active_plugins&amp;#39;)))){

          $allowed_yoast_keywords = array(
              &amp;#39;_yoast_wpseo_title&amp;#39;,
              &amp;#39;_yoast_wpseo_bctitle&amp;#39;,
              &amp;#39;_yoast_wpseo_metadesc&amp;#39;,
              &amp;#39;_yoast_wpseo_focuskw&amp;#39;,
              &amp;#39;_yoast_wpseo_meta-robots-noindex&amp;#39;,
              &amp;#39;_yoast_wpseo_meta-robots-nofollow&amp;#39;,
              &amp;#39;_yoast_wpseo_meta-robots-adv&amp;#39;,
              &amp;#39;_yoast_wpseo_canonical&amp;#39;,
              &amp;#39;_yoast_wpseo_redirect&amp;#39;,
              &amp;#39;_yoast_wpseo_opengraph-description&amp;#39;,
          );

          foreach( $allowed_yoast_keywords as $field) {
              register_meta( &amp;#39;post&amp;#39;, $field, array( &amp;#39;show_in_rest&amp;#39; =&amp;gt; true ) );
          }

      }
    }

?&amp;gt;
&lt;/pre&gt;
&lt;h2 id=&quot;slug&quot;&gt;Building URLs&lt;/h2&gt;
&lt;p&gt;If you are building a front-end app on top of WordPress, you have to think about how to structure your URLs. WordPress has two default post-types (posts &amp;amp; pages) and the URLs do not distinguish which type you are requesting, so &lt;code&gt;http://wp-site.expl/something&lt;/code&gt; might lead to a page or a post, dependent on the type of the object with the slug &lt;b&gt;something&lt;/b&gt;. &lt;/p&gt;
&lt;p&gt;That means that if you want to mirror that behaviour in your app, you have to do two requests for each URL, one searching pages, one searching posts. To make that one request, use the following.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;GET: /wp-json/wp/v2/slug/&amp;lt;post-or-page-slug&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
&amp;lt;?php

/**
 * Adds a slug endpoint for getting the page or post for a given slug
 */
add_action(&amp;#39;rest_api_init&amp;#39;, &amp;#39;wuxt_slug_route&amp;#39;);


function wuxt_slug_route()
{
    register_rest_route(&amp;#39;wp&amp;#39;, &amp;#39;/v2/slug/(?P&amp;lt;slug&amp;gt;\S+)&amp;#39;, array(
        &amp;#39;methods&amp;#39;  =&amp;gt; &amp;#39;GET&amp;#39;,
        &amp;#39;callback&amp;#39; =&amp;gt; &amp;#39;wuxt_get_slug&amp;#39;
    ));
}


function wuxt_get_slug($object)
{

    $slug = $object-&amp;gt;get_param(&amp;#39;slug&amp;#39;);

    $request = new WP_REST_Request(&amp;#39;GET&amp;#39;, &amp;#39;/wp/v2/posts&amp;#39;);
    $request-&amp;gt;set_param(&amp;#39;slug&amp;#39;, $slug);

    $response = rest_do_request($request);

    if (!$response-&amp;gt;data) {

        $request = new WP_REST_Request(&amp;#39;GET&amp;#39;, &amp;#39;/wp/v2/pages&amp;#39;);
        $request-&amp;gt;set_param(&amp;#39;slug&amp;#39;, $slug);

        $response = rest_do_request($request);
    }

    if (!$response-&amp;gt;data) {
        return new WP_Error(&amp;#39;wuxt_no_such_slug&amp;#39;, __(&amp;#39;Slug does not exist&amp;#39;), array(&amp;#39;status&amp;#39; =&amp;gt; 404));
    }

    $embed = $object-&amp;gt;get_param(&amp;#39;_embed&amp;#39;) !== NULL;
    $data = rest_get_server()-&amp;gt;response_to_data($response, $embed);

    return $data[0];
}

?&amp;gt;
&lt;/pre&gt;
&lt;h2&gt;More to come …&lt;/h2&gt;
&lt;p&gt;I hope you found some of the code above useful. Send me your extensions in the comments and I will happily integrate them! &lt;/p&gt;
	</description></item><item><title>WP-CLI inside Docker via Gulp</title><link>https://www.danielauener.com/wp-cli-inside-docker-via-gulp/</link><guid isPermaLink="false">http://www.danielauener.com/?p=898</guid><pubDate>Sat, 11 May 2019 14:38:21 GMT</pubDate><description>
		&lt;p&gt;When I’m running WordPress inside a Docker container, I usually only mirror the wp-content directory from the container to the host. You shouldn’t change anything in the other WordPress directories anyway and you avoid many volume syncs. The problem with this approach is that you can’t run the wp-command from the host; you have to run WP-CLI inside Docker. That means logging in to the container, running the commands and logging out again. Assuming your container is called &lt;code&gt;wp-container&lt;/code&gt; the following commands would do that:&lt;/p&gt;
&lt;pre class=&quot;brush: bash; title: ; notranslate&quot; title=&quot;&quot;&gt;
  
docker exec -ti wp-container bash
wp plugin list
exit
  
&lt;/pre&gt;
&lt;p&gt;It’s just a little inconvenience, but why not save some commands when we can?&lt;/p&gt;
&lt;p&gt;I’m using Gulp as a task manager for most of my projects, and have added a task which forwards all commands to WP-CLI inside Docker. It even checks if the container is running and if WP-CLI is installed inside the container. If not, it will be automatically installed.&lt;/p&gt;
&lt;pre class=&quot;brush: jscript; title: ; notranslate&quot; title=&quot;&quot;&gt;
var gulp = require(&amp;#39;gulp&amp;#39;);
var spawn = require(&amp;#39;child_process&amp;#39;).spawn;

var checkContainers = function(names, done) {
  var exec = require(&amp;#39;child_process&amp;#39;).exec;
  exec(&amp;#39;docker ps --format {{.Names}}&amp;#39;, function(error, stdout, stderr) {
    done(names.map(function(name) {
      return stdout.split(&amp;quot;\n&amp;quot;).indexOf(name) &amp;gt;= 0;
    }).reduce(function(running, next) {
      return running &amp;amp;&amp;amp; next;
    }, true));
  });
};

var checkWPCli = function(container, done) {
  var exec = require(&amp;#39;child_process&amp;#39;).exec;
  exec(&amp;#39;docker exec &amp;#39; + container + &amp;#39; bash -c \&amp;#39;wp\&amp;#39;&amp;#39;, function(error, stdout, stderr) {}).on(&amp;#39;exit&amp;#39;, function(code) {
    done(127 !== code);
  });
};

var installWPCli = function(container, done) {
  var exec = require(&amp;#39;child_process&amp;#39;).exec;
  exec(&amp;#39;docker exec &amp;#39; + container + &amp;#39; bash -c \&amp;#39;apt-get update &amp;amp;&amp;amp; apt-get install -y less &amp;amp;&amp;amp; curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar &amp;amp;&amp;amp; chmod +x wp-cli.phar &amp;amp;&amp;amp; mv wp-cli.phar /usr/local/bin/wp &amp;amp;&amp;amp; wp --allow-root cli\&amp;#39;&amp;#39;, function(error, stdout, stderr) {}).on(&amp;#39;exit&amp;#39;, function(code) {
    done(0 === code);
  });
};

var runWPCli = function(container, done) {
  var command = process.argv.slice(process.argv.indexOf(&amp;#39;-c&amp;#39;) + 1);

  if (!command.length) {
    console.log(&amp;#39;ERROR: Provide a valid wp-cli command!&amp;#39;);
    return done();
  }

  var exec = require(&amp;#39;child_process&amp;#39;).exec;
  exec(&amp;#39;docker exec &amp;#39; + container + &amp;#39; bash -c \&amp;#39;wp --allow-root &amp;#39; + command.join(&amp;#39; &amp;#39;) + &amp;#39;\&amp;#39;&amp;#39;, function(error, stdout, stderr) {
    console.log(stdout);
  }).on(&amp;#39;exit&amp;#39;, function(code) {
    done();
  });
};

gulp.task( &amp;#39;wp&amp;#39;, function(done) {

  checkContainers([&amp;#39;wp-container&amp;#39;], function(containerRunning) {

    if (!containerRunning) {
      console.log(&amp;#39;ERROR: wp-container container is not running. Try &amp;quot;docker-compose up -d&amp;quot;&amp;#39;)
      return done();
    }

    checkWPCli(&amp;#39;wp-container&amp;#39;, function(wpCliRunning) {
      if (!wpCliRunning) {

        console.log(&amp;#39;WARNING: wp cli not installed, trying auto install ...&amp;#39;);

        installWPCli(&amp;#39;wp-container&amp;#39;, function(wpCliRunning) {

          console.log(&amp;#39;SUCCESS: wp cli installed!&amp;#39;);
          runWPCli(&amp;#39;wp-container&amp;#39;, done);

        });
      } else {

        runWPCli(&amp;#39;wp-container&amp;#39;, done);

      }
    });
  });

});

&lt;/pre&gt;
&lt;p&gt;So, with that gulp task in place, you will be able to run the following commands and every other WP-CLI command as well:&lt;/p&gt;
&lt;pre class=&quot;brush: bash; title: ; notranslate&quot; title=&quot;&quot;&gt;
gulp wp -c &amp;quot;plugin list&amp;quot;
gulp wp -c &amp;quot;plugin install advanced-custom-fields&amp;quot;
&lt;/pre&gt;
&lt;h2&gt;What do you think?&lt;/h2&gt;
&lt;p&gt;Is that too much hassle for running some wp-commands or would you use the gulp forward in your daily work? Let me know!&lt;/p&gt;
	</description></item><item><title>Nuxt.js + WordPress = WUXT</title><link>https://www.danielauener.com/nuxt-js-wordpress-wuxt/</link><guid isPermaLink="false">http://www.danielauener.com/?p=889</guid><pubDate>Wed, 08 May 2019 21:47:18 GMT</pubDate><description>
		&lt;p&gt;In the last couple of months I’ve worked a great deal with WordPress as a backend system, providing data to a JavaScript frontend via the REST API. As I couldn’t find a complete solution for my favorite frontend-framework, my “getting started” process always repeated the following steps&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;set up a WordPress development environment (docker)&lt;/li&gt;
&lt;li&gt;integrate JavaScript frontend in the code&lt;/li&gt;
&lt;li&gt;set up an environment for the frontend (docker)&lt;/li&gt;
&lt;li&gt;make the two environments talk to each other (not always as easy as you think)&lt;/li&gt;
&lt;li&gt;set up a simple JavaScript framework to query the WordPress API from the frontend&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As that procedure eats up a whole lot of project hours, the time was right for an easier solution. So, together with my colleague &lt;a href=&quot;https://github.com/oliwersmedjevik&quot;&gt;Oliwer&lt;/a&gt; at &lt;a href=&quot;https://www.northosts.se&quot;&gt;Northosts&lt;/a&gt; and much appreciated input and testing from my friend &lt;a href=&quot;https://github.com/samuelhorn&quot;&gt;Samuel&lt;/a&gt;, I started working on a WordPress/Nuxt.js hybrid development environment. Our goal was to provide a one-command-installation, which makes you ready to go in 5 minutes.&lt;/p&gt;
&lt;p&gt;Now we are finally ready for our first release, so say hello to &lt;a href=&quot;https://github.com/northosts/wuxt&quot;&gt;WUXT&lt;/a&gt;!&lt;/p&gt;
&lt;h2&gt;WUXT Components&lt;/h2&gt;
&lt;p&gt;WUXT combines a couple of components you almost certainly already know from other projects, adds some convenient new functionality and solves a handful of configuration problems. Here is a short overview of all components&lt;/p&gt;
&lt;p style=&quot;padding-left: 30px;&quot;&gt;&lt;strong&gt;Docker containers: &lt;/strong&gt;To provide a consistent development experience on all platforms, we use Docker (what else?). Three containers are needed, one for the WordPress database (mysql.wuxt), one for WordPress (wp.wuxt) and one for nuxt.js (front.wuxt). Everything is set up with docker-compose. We were extra careful to base everything on the official images (mysql, wordpress and node) and skip custom docker-files, which should make it a lot easier to upgrade the environment. The relevant files from the container are mirrored to the host with volumes, which makes the database persistent (_db folder), lets you access everything important in WordPress (wp-content directory) and nuxt.js (nuxt folder).&lt;/p&gt;
&lt;p style=&quot;padding-left: 30px;&quot;&gt;&lt;strong&gt;WordPress REST API extensions:&lt;/strong&gt; The WordPress API is awesome, but to use WordPress’s full potential in our nuxt.js frontend, we needed some additional functionality. Activating our WUXT-theme adds endpoints for menus, the front-page settings, getting pages and posts by slug and includes meta-data from well known plugins. We are constantly adding new endpoints to support even more use-cases.&lt;/p&gt;
&lt;p style=&quot;padding-left: 30px;&quot;&gt;&lt;strong&gt;WordPress connector in nuxt.js:&lt;/strong&gt; It’s not difficult to set up some requests to the WordPress API from nuxt.js, but we wanted a standardized way. That’s why we included the &lt;a href=&quot;https://github.com/WP-API/node-wpapi&quot;&gt;wpapi&lt;/a&gt; node module into our nuxt application (you always have access via the $wp object). Here, too, we made some adjustments, to make sure the connection to the WordPress REST API can be established both from the nuxt-container to the wp-container and from the client application to the wp-container. Of course, we also added some shortcuts to support our new endpoints for menus, front-page, custom post types etc.&lt;/p&gt;
&lt;p style=&quot;padding-left: 30px;&quot;&gt;&lt;strong&gt;Development tools:&lt;/strong&gt; Docker is so great, but sometimes it makes developers’ lives a little bit more difficult. Logging in to the container to run a WP-CLI command can be a hassle, file permissions when working with volumes might be another. To make that a little easier we added gulp tasks to give you access to WP-CLI or let you install new node-modules inside the container, without accessing it. We even provide a post-type generator for gulp, which lets you create automatically loaded, API-ready post-types in seconds.&lt;/p&gt;
&lt;p&gt;None of the above is rocket-science, but I think the combination and packaging into one, complete environment should make a difference for everyone developing with WordPress and nuxt.js. Please try it out and give us feedback, issues or some of your spare-time to make WUXT better.&lt;/p&gt;
&lt;h2&gt;Getting started&lt;/h2&gt;
&lt;p&gt;First clone the &lt;a href=&quot;https://github.com/northosts/wuxt&quot;&gt;repository&lt;/a&gt; to a directory you want, then change to that directory and simply start your containers (you need to have a running &lt;strong&gt;&lt;em&gt;Docker&lt;/em&gt;&lt;/strong&gt; installation of course):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker-compose up -d
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That starts the following containers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;MySQL&lt;/em&gt;&lt;/strong&gt; (&lt;code&gt;mysql.wuxt)&lt;/code&gt;&lt;strong&gt;&lt;em&gt; &lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;WordPress&lt;/em&gt;&lt;/strong&gt; (&lt;code&gt;wp.wuxt&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;nuxt.js&lt;/em&gt;&lt;/strong&gt; (&lt;code&gt;front.wuxt&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Your containers are available at&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Frontend: &lt;code&gt;http://localhost:3000&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Backend: &lt;code&gt;http://localhost:3080&lt;/code&gt;, &lt;code&gt;http://localhost:3080/wp-admin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Database: &lt;code&gt;docker exec -ti mysql.wuxt bash&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Set up &lt;strong&gt;&lt;em&gt;WordPress&lt;/em&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;After starting the containers for the first time you have to do a standard &lt;strong&gt;&lt;em&gt;WordPress&lt;/em&gt;&lt;/strong&gt; installation at &lt;code&gt;http://localhost:3080/install.php&lt;/code&gt;. Then log in to wp-admin and select the &lt;strong&gt;wuxt&lt;/strong&gt; theme to activate all the API extensions. Additionally you might want to activate the &lt;strong&gt;&lt;em&gt;ACF&lt;/em&gt;&lt;/strong&gt; plugin to make your meta work easier. Last but not least you have to set the permalink structure to “Post Name” in the &lt;strong&gt;&lt;em&gt;WordPress&lt;/em&gt;&lt;/strong&gt; settings.&lt;/p&gt;
&lt;p&gt;To check if everything is running, visit &lt;code&gt;http://localhost:3080&lt;/code&gt; and verify that the &lt;strong&gt;WUXT&lt;/strong&gt; info screen is showing.&lt;/p&gt;
&lt;p&gt;Then check that the REST API at &lt;code&gt;http://localhost:3080/wp-json&lt;/code&gt; is returning a JSON-object and you are good to go.&lt;/p&gt;
&lt;h3&gt;&lt;a id=&quot;user-content-setup-nuxtjs&quot; class=&quot;anchor&quot; href=&quot;https://github.com/northosts/wuxt#setup-nuxtjs&quot;&gt;&lt;/a&gt;Set up &lt;strong&gt;&lt;em&gt;nuxt.js&lt;/em&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Nuxt should have been started automatically inside the docker container. The command we use for running the &lt;strong&gt;&lt;em&gt;nuxt.js &lt;/em&gt;&lt;/strong&gt;server is &lt;code&gt;yarn dev&lt;/code&gt;. Check if the frontend is running by opening &lt;code&gt;http://localhost:3000&lt;/code&gt;. You should be greeted by the &lt;strong&gt;Wuxt&lt;/strong&gt; intro-screen.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.danielauener.com/assets/media/original/eb16d3dc52b868cf3ba8.png&quot;&gt;&lt;img class=&quot;wp-image-892 size-large aligncenter&quot; src=&quot;https://www.danielauener.com/assets/media/original/312899231ae377ff40de.png&quot; alt=&quot;&quot; width=&quot;600&quot; height=&quot;518&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/312899231ae377ff40de.png 1024w, https://www.danielauener.com/assets/media/original/ea89b2b3c74ff4ff957d.png 300w, https://www.danielauener.com/assets/media/original/953d6011ac31f39da842.png 768w, https://www.danielauener.com/assets/media/original/eb16d3dc52b868cf3ba8.png 1086w&quot; sizes=&quot;(max-width: 600px) 100vw, 600px&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Finally check if &lt;strong&gt;&lt;em&gt;BrowserSync&lt;/em&gt;&lt;/strong&gt; is running, by making a minor change to the front-page. The change should directly be visible on the front-page as well.&lt;/p&gt;
&lt;h2&gt;Feedback&lt;/h2&gt;
&lt;p&gt;Please let us know what you think about WUXT, what you did with it and what you couldn’t do. Please clone, fork, open issues, comment or contribute, it’s much appreciated.&lt;/p&gt;
	</description></item><item><title>Activate Gutenberg block-editor on specific pages or posts, or Gutenberg migration the client-friendly way</title><link>https://www.danielauener.com/activate-gutenberg-block-editor-on-specific-pages-or-posts-or-gutenberg-migration-the-client-friendly-way/</link><guid isPermaLink="false">http://www.danielauener.com/?p=871</guid><pubDate>Thu, 31 Jan 2019 23:08:01 GMT</pubDate><description>
		&lt;p&gt;Since WordPress 5.0, the Gutenberg block-editor is here and it seems like curiosity about what you can do with it slowly surpasses the panic about what Gutenberg could do to all your beloved projects. To get the block-editor into one of your existing projects, there are some hurdles to overcome:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;getting to know Gutenberg’s editing experience&lt;/li&gt;
&lt;li&gt;building at least one block-ready template&lt;/li&gt;
&lt;li&gt;deactivating the Classic Editor (not really a hurdle)&lt;/li&gt;
&lt;li&gt;and … convincing your client&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Say you tackled all these problems and your Gutenberg migration project is good to go: how do you start?&lt;/p&gt;
&lt;h2&gt;Step by Step: Gutenberg for specific posts or pages&lt;/h2&gt;
&lt;p&gt;In my (very humble) experience of one finished and one ongoing block-editor migration project, if you can’t start from scratch, you should do it step by step, post by post and page by page. First group your posts and pages by special features and make a plan about how you can build them in Gutenberg. Which blocks do you need, can you apply your own color scheme, what about forms, custom fields and short-codes etc.&lt;/p&gt;
&lt;p&gt;With that plan in place, you can now get to one pilot post and start to shape it in the Gutenberg-way. At the same time you don’t want to interfere with your client’s possible changes to other posts and you want to give them the chance to get to know the block-editor in a limited playground. So now you have to do some coding.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Deactivate Gutenberg everywhere. I know, you just activated it. But remember, you basically want to preserve the classic experience on the entire site, so that has to be the default. This time, we don’t use the plugin, though. We use this line of code in the functions.php file:
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;   
  
// Disable Gutenberg for all posts
add_filter(&amp;#39;use_block_editor_for_post&amp;#39;, &amp;#39;__return_false&amp;#39;, 5);
  
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Next step is to activate the Gutenberg block-editor for specific posts and pages. I think the best way is to use a special meta field, which I called &lt;i&gt;use_gutenberg&lt;/i&gt;. If that field is true, you just activate the Gutenberg block-editor with the appropriate filter (&lt;i&gt;use_block_editor_for_post&lt;/i&gt;).
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt; 
  
function theme_enable_gutenberg_post_meta($can_edit, $post) {

	if (empty($post-&amp;gt;ID)) return $can_edit;

	if (get_post_meta($post-&amp;gt;ID, &amp;#39;use_gutenberg&amp;#39;, true)) return true;

	return $can_edit;

}
add_filter(&amp;#39;use_block_editor_for_post&amp;#39;, &amp;#39;theme_enable_gutenberg_post_meta&amp;#39;, 10, 2);
  
&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you add the meta-field with ACF, like I did, it might look like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.danielauener.com/assets/media/original/37ed41e971bfcab98a66.png&quot;&gt;&lt;img class=&quot;alignnone size-medium wp-image-878&quot; src=&quot;https://www.danielauener.com/assets/media/original/940329095e651984093d.png&quot; alt=&quot;&quot; width=&quot;300&quot; height=&quot;239&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/940329095e651984093d.png 300w, https://www.danielauener.com/assets/media/original/37ed41e971bfcab98a66.png 315w&quot; sizes=&quot;(max-width: 300px) 100vw, 300px&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now you can transfer the group of pages and finally the entire site to Gutenberg in a very controlled and fail-safe way. Your clients will thank you!&lt;/p&gt;
&lt;p&gt;If you have thoughts about Gutenberg migrations or experience with adding the block editor to existing sites, please let me know in the comments.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
	</description></item><item><title>WordPress-blogging, always a step ahead</title><link>https://www.danielauener.com/wordpress-blogging-always-a-step-ahead/</link><guid isPermaLink="false">http://www.danielauener.com/?p=868</guid><pubDate>Thu, 31 Jan 2019 20:25:00 GMT</pubDate><description>
		&lt;p&gt;Today it’s my special honor to introduce a new WordPress-blog of a friend of mine: &lt;a href=&quot;https://wpahead.com&quot;&gt;wpahead.com&lt;/a&gt;. Its main focus is WP front-end building and I know there is a ton of expertise behind these well-written tips, articles and tutorials.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.danielauener.com/assets/media/original/ef45e523fb7a257372ce.png&quot;&gt;&lt;img class=&quot;wp-image-869 size-large aligncenter&quot; src=&quot;https://www.danielauener.com/assets/media/original/f207ba52b44ed6907097.png&quot; alt=&quot;&quot; width=&quot;600&quot; height=&quot;319&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/f207ba52b44ed6907097.png 1024w, https://www.danielauener.com/assets/media/original/fa8b3ef584a76e210313.png 300w, https://www.danielauener.com/assets/media/original/dbe085aafbeda544d893.png 768w&quot; sizes=&quot;(max-width: 600px) 100vw, 600px&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I’ve got a lot of great ideas from the tutorial about building &lt;a href=&quot;https://wpahead.com/gutenberg-blocks-advanced-custom-fields/&quot;&gt;Gutenberg-blocks with the new Advanced Custom Fields beta-version&lt;/a&gt;, and I’ll use that setup in many of my future projects.&lt;/p&gt;
&lt;p&gt;Good luck to our new star in the WordPress blogging community!&lt;/p&gt;
	</description></item><item><title>My Talk about Elasticsearch and WordPress at WordCamp Stockholm 2017</title><link>https://www.danielauener.com/my-talk-about-elasticsearch-and-wordpress-at-wordcamp-stockholm-2017/</link><guid isPermaLink="false">http://www.danielauener.com/?p=855</guid><pubDate>Sat, 25 Nov 2017 13:36:31 GMT</pubDate><description>
		&lt;p&gt;A few days ago I proudly gave my first WordCamp talk about Elasticsearch and how to integrate it into WordPress. It’s in Swedish (with a slightly embarrassing German accent) and I think it’s worth listening to. Here is the video:&lt;/p&gt;
&lt;p&gt;&lt;iframe width=&quot;600&quot; height=&quot;338&quot; src=&quot;https://www.youtube.com/embed/jJ8WEk6AAnE?feature=oembed&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;For those of you who don’t understand Swedish, there are some code-slides about ElasticPress features and integration of WP-Query. Check out all slides &lt;a href=&quot;https://docs.google.com/presentation/d/1RpUje7oSYt-XTV73JVKjIOTRqsVjUwA7Y277x4NI1zg/edit?usp=sharing&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thanks to my very supportive “hejarklack” from &lt;a href=&quot;https://wilsoncreative.se/&quot;&gt;Wilson Creative&lt;/a&gt;: &lt;a href=&quot;https://twitter.com/pixelcrook?lang=en&quot;&gt;@pixelcrook&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/sofievingstedt?lang=en&quot;&gt;@sofievingstedt&lt;/a&gt;, &lt;a href=&quot;https://github.com/wilsonrobin&quot;&gt;@wilsonrobin&lt;/a&gt; and Martin Carstedt. Many thanks also to Andreas Ek (&lt;a href=&quot;https://twitter.com/elseifab&quot;&gt;@elseifab&lt;/a&gt;) for a much appreciated pep talk (Andreas gave a really interesting talk about MVC in WordPress as well!).&lt;/p&gt;
&lt;p&gt;Last but not least, thanks to everyone who made this awesome &lt;a href=&quot;https://2017.stockholm.wordcamp.org/&quot;&gt;WordCamp&lt;/a&gt; happen!&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
	</description></item><item><title>Slow WooCommerce with Many Products</title><link>https://www.danielauener.com/slow-woocommerce-many-products/</link><guid isPermaLink="false">http://www.danielauener.com/?p=796</guid><pubDate>Sun, 05 Mar 2017 20:33:10 GMT</pubDate><description>
		&lt;p&gt;WooCommerce is the most used webshop system in the world and it’s  awesome! However, using WordPress as its application framework has some drawbacks. In particular, you might get a very slow WooCommerce with many products. When I point that out in client meetings,  I inevitably get the same questions: How many products exactly result in a slow WooCommerce frontend/backend etc – and what can you do about it?&lt;/p&gt;
&lt;p&gt;Despite all the knowledge I have about server architecture, clean theming and WordPress coding, that question isn’t so easy to answer. That’s why I set up my own little test app.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Recommendation: &lt;/strong&gt;Many slow WooCommerce sites just don’t have the right type of hosting. A good WordPress/WooCommerce hosting service with great support and performance-optimizing technical add-ons like Redis and Elasticsearch is Kinsta. Read more about their &lt;a href=&quot;https://kinsta.com/woocommerce-hosting/?kaid=LJTEEDVAIWBS&quot; rel=&quot;nofollow&quot;&gt;WooCommerce hosting here&lt;/a&gt;. &lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Slow WooCommerce with Many Products – The Test Environment&lt;/h2&gt;
&lt;p&gt;I’ve done all of the following tests on my local computer. It’s a Dell XPS 13 with the following hardware:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Intel Core i7-7500U&lt;/li&gt;
&lt;li&gt;8GB LPDDR3 1866MHz&lt;/li&gt;
&lt;li&gt;256GB PCIe Solid State Drive&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Operating System and services:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ubuntu 14.04&lt;/li&gt;
&lt;li&gt;Apache 2.4.7&lt;/li&gt;
&lt;li&gt;MySQL 5.5.54&lt;/li&gt;
&lt;li&gt;PHP 7.0.16&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The WordPress installation I’m testing with is a clean install of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;WordPress 4.7.2&lt;/li&gt;
&lt;li&gt;WooCommerce 2.6.14&lt;/li&gt;
&lt;li&gt;Twenty Seventeen Theme&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No other plugins or code adjustments.&lt;/p&gt;
&lt;p&gt;Furthermore, I wrote a small npm application, which incrementally adds products to WooCommerce by using the API. After each insertion of data, the application pauses five seconds, to give garbage collection and MySQL a break and then performs some tests, like reading products from the WooCommerce API or requesting the “Shop”-page from the front-end, while measuring both request-time and the average of the MySQL cpu and memory usage.&lt;/p&gt;
&lt;p&gt;The inserted products are simple WooCommerce products, with auto-generated lorem-ipsum titles, descriptions and a random price.&lt;/p&gt;
&lt;p&gt;Check out the test application on GitHub, feedback and contributions very welcome:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/danielauener/slow-woocommerce-tests&quot;&gt;https://github.com/danielauener/slow-woocommerce-tests&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After cloning, go to the app folder and run&lt;/p&gt;
&lt;pre class=&quot;brush: bash; title: ; notranslate&quot; title=&quot;&quot;&gt;npm install&lt;/pre&gt;
&lt;p&gt;Then adjust the configuration parameters in index.js to your environment and run the application with a simple&lt;/p&gt;
&lt;pre class=&quot;brush: bash; title: ; notranslate&quot; title=&quot;&quot;&gt;npm start&lt;/pre&gt;
&lt;p&gt;After completing the test cycle, the test data is written to a benchmark csv file in the benchmark directory of the app directory.&lt;/p&gt;
&lt;h2&gt;What’s tested&lt;/h2&gt;
&lt;p&gt;There are three questions I wanted to answer.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Is WooCommerce really getting slower with many products and how much?&lt;/li&gt;
&lt;li&gt;Is it WooCommerce slowing down the performance or is it actually WordPress, which is slow?&lt;/li&gt;
&lt;li&gt;If we can confirm a slow WooCommerce with many products, why is that happening?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Besides these general questions, I was interested in two use-cases. The obvious one was request times for the WooCommerce front-end, because that’s impacting conversions and sales. The second one was the insertion speed of new products with a big database. That one is important, because most shops with around 10000 products and more, most likely have some kind of import process, which might add load to the entire server. Since we’re talking about imports, which can go on for hours, that’s quite relevant.&lt;/p&gt;
&lt;h2&gt;Slow WooCommerce performance with 50 000 Products?&lt;/h2&gt;
&lt;p&gt;In my first test I wanted to check a really huge product database, so I could get a full picture of what’s happening. After some tries and time calculations, I decided to run with 50 000 products, starting my test tool with the following environment variables (MySQL and WP configuration in the index.js file).&lt;/p&gt;
&lt;pre class=&quot;brush: bash; title: ; notranslate&quot; title=&quot;&quot;&gt;

MYSQL_PID=4333 ITERATIONS=500 POST_INSERT_CHUNK=100 npm start

&lt;/pre&gt;
&lt;h3&gt;CPU and Meta Table&lt;/h3&gt;
&lt;p&gt;After a good night’s sleep, the test was finally through. What I could say from how my computer behaved during the test (noisy and warm), there had to be some CPU-usage, which you can see in the first image. The other two lines in the chart are the number of added posts in each step (confirming the test went as planned) and the size of the &lt;code&gt;wp_postmeta-&lt;/code&gt;table.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.danielauener.com/assets/media/original/4160c3895c844cf4c638.png&quot; rel=&quot;attachment wp-att-823&quot;&gt;&lt;img class=&quot;alignnone wp-image-823 size-full&quot; src=&quot;https://www.danielauener.com/assets/media/original/4160c3895c844cf4c638.png&quot; alt=&quot;Slow WooCommerce with 50 000 products: CPU-Usage&quot; width=&quot;1119&quot; height=&quot;506&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/4160c3895c844cf4c638.png 1119w, https://www.danielauener.com/assets/media/original/ce7ad31c1140b91b502a.png 300w, https://www.danielauener.com/assets/media/original/37081c3f5ba463368c18.png 768w, https://www.danielauener.com/assets/media/original/8349c664c4a745b830e1.png 1024w&quot; sizes=&quot;(max-width: 1119px) 100vw, 1119px&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As you can see, the size of the meta-table (yellow) is rising much faster than the size of the products-table (green), which we will discuss later. The CPU-usage seems to increase logarithmically, slowly approaching 100%.&lt;/p&gt;
&lt;p&gt;Just to clarify: the CPU-usage is measured only when the requests are done, not during the insert product calls.&lt;/p&gt;
&lt;h3&gt;Requests&lt;/h3&gt;
&lt;p&gt;The next chart I’ve created, shows, how the CPU-usage affects the front-end request times. After every product insertion cycle, test requests were made to the shop-page, which is listing the first ten products and a single product page.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.danielauener.com/assets/media/original/5d88574334f0a769783d.png&quot; rel=&quot;attachment wp-att-817&quot;&gt;&lt;img class=&quot;alignnone wp-image-817 size-full&quot; src=&quot;https://www.danielauener.com/assets/media/original/5d88574334f0a769783d.png&quot; alt=&quot;Slow WooCommerce with 50 000 products: Request Speed&quot; width=&quot;1110&quot; height=&quot;501&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/5d88574334f0a769783d.png 1110w, https://www.danielauener.com/assets/media/original/468c0d379962875c7a1c.png 300w, https://www.danielauener.com/assets/media/original/b41b3a487b6d9475b57f.png 768w, https://www.danielauener.com/assets/media/original/b14e1b352827321a0bb1.png 1024w&quot; sizes=&quot;(max-width: 1110px) 100vw, 1110px&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The overall development of the chart shows, that all the time, the single product page loading times are quite stable. The shop pages loading times increase directly from the beginning though. That’s what I would expect, because the shop-page queries the entire products table and needs to load meta data for at least ten products, while the single product page only needs to do that once.&lt;/p&gt;
&lt;p&gt;Furthermore, we can see two quite obvious changes in the chart. Around 15 000 products (step 150) the CPU approaches 50%, and we get a bigger variation in the loading times. Nonetheless, the single product times seem to be quite stable, but the shop-page times clearly increase.  The same happens again, when the CPU-usage passes 70%, around 35 000 products.&lt;/p&gt;
&lt;h3&gt;Insertion Speed&lt;/h3&gt;
&lt;p&gt;The time needed to add new products obviously increases with the number of products, which is expected. I didn’t expect such an increase, though. I would have thought, that you have to operate WooCommerce with many more products, to get from around 4 seconds per 100 products to much more than a minute.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.danielauener.com/assets/media/original/9d30bcb4bdc825e9c969.png&quot; rel=&quot;attachment wp-att-820&quot;&gt;&lt;img class=&quot;alignnone wp-image-820 size-full&quot; src=&quot;https://www.danielauener.com/assets/media/original/9d30bcb4bdc825e9c969.png&quot; alt=&quot;Slow WooCommerce with 50 000 products: Insertion Speed&quot; width=&quot;1110&quot; height=&quot;455&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/9d30bcb4bdc825e9c969.png 1110w, https://www.danielauener.com/assets/media/original/93bc58cb673373359d93.png 300w, https://www.danielauener.com/assets/media/original/b32f94379d65453c3871.png 768w, https://www.danielauener.com/assets/media/original/82ffb4fe510b3caf0b6e.png 1024w&quot; sizes=&quot;(max-width: 1110px) 100vw, 1110px&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For the last dip in insertion time around 45 000 products I have no explanation. It might be that some resources were freed on my computer, not really sure, though.&lt;/p&gt;
&lt;h2&gt;Slow WooCommerce performance with 10 000 Products?&lt;/h2&gt;
&lt;p&gt;To double-check the previous results, I ran the same tests with only 10 000 products. I both wanted to see, if the test with fewer products would lead to the same conclusions and decrease test-time for further runs. Before this new test, I restored the initial database, from before the other test, then ran the following command:&lt;/p&gt;
&lt;pre class=&quot;brush: bash; title: ; notranslate&quot; title=&quot;&quot;&gt;

MYSQL_PID=4333 ITERATIONS=100 POST_INSERT_CHUNK=100 npm start

&lt;/pre&gt;
&lt;h3&gt;CPU&lt;/h3&gt;
&lt;p&gt;The CPU-usage is rising, even with 10 000 products. It goes up to about 30%, which matches the 10 000 product value of the previous test. Meta-table and product count behave as expected.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.danielauener.com/assets/media/original/88d675e063256fa6a74b.png&quot; rel=&quot;attachment wp-att-824&quot;&gt;&lt;img class=&quot;alignnone wp-image-824 size-full&quot; src=&quot;https://www.danielauener.com/assets/media/original/88d675e063256fa6a74b.png&quot; alt=&quot;Slow WooCommerce with 10 000 products: CPU-Usage&quot; width=&quot;1045&quot; height=&quot;479&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/88d675e063256fa6a74b.png 1045w, https://www.danielauener.com/assets/media/original/9d6c8a9b3470a9917760.png 300w, https://www.danielauener.com/assets/media/original/19ea0dfeeaaa7ab6c70d.png 768w, https://www.danielauener.com/assets/media/original/001605e27113909b92ae.png 1024w&quot; sizes=&quot;(max-width: 1045px) 100vw, 1045px&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Requests&lt;/h3&gt;
&lt;p&gt;Even the requests show the same picture. The shop-page request time seems to rise in line with the CPU-usage, which was the same in the 50 000 test, below the 15 000 products mark. The single product page loads steadily between 100 and 150ms.&lt;/p&gt;
&lt;p&gt;&lt;img class=&quot;alignnone wp-image-818 size-full&quot; src=&quot;https://www.danielauener.com/assets/media/original/52ebbde752fd2d261d9b.png&quot; alt=&quot;Slow WooCommerce with 10 000 products: Request Speed&quot; width=&quot;1045&quot; height=&quot;481&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/52ebbde752fd2d261d9b.png 1045w, https://www.danielauener.com/assets/media/original/5b51c463b2a7984641bf.png 300w, https://www.danielauener.com/assets/media/original/362f23a9c8d8c53881ac.png 768w, https://www.danielauener.com/assets/media/original/89d18cfad94300398015.png 1024w&quot; sizes=&quot;(max-width: 1045px) 100vw, 1045px&quot;&gt;&lt;/p&gt;
&lt;h3&gt;Insertion Speed&lt;/h3&gt;
&lt;p&gt;The same goes for insertion speed, which shows a similar picture as above.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.danielauener.com/assets/media/original/4efc9c54aef9f119ca2d.png&quot; rel=&quot;attachment wp-att-816&quot;&gt;&lt;img class=&quot;alignnone wp-image-821 size-full&quot; src=&quot;https://www.danielauener.com/assets/media/original/30e0b2d91ac75b93e042.png&quot; alt=&quot;Slow WooCommerce with 10 000 products: Insertion Speed&quot; width=&quot;1087&quot; height=&quot;511&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/30e0b2d91ac75b93e042.png 1087w, https://www.danielauener.com/assets/media/original/cfabef23554d6fc7ff29.png 300w, https://www.danielauener.com/assets/media/original/ff7f2f536ac0929e369c.png 768w, https://www.danielauener.com/assets/media/original/78e3ed5f8b77b5fcd3fb.png 1024w&quot; sizes=&quot;(max-width: 1087px) 100vw, 1087px&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;What Causes a Slow WooCommerce with Many Products&lt;/h2&gt;
&lt;p&gt;Now, one of my questions was, what causes slow WooCommerce queries and if the problem actually is related to WooCommerce? From experience with prior projects, I knew the answer already and had a quite good idea what the reason was. However, it’s always nice to confirm your assumptions with data.&lt;/p&gt;
&lt;h3&gt;Big Meta Table = Long Loading Times&lt;/h3&gt;
&lt;p&gt;My experience was, that WooCommerce performance problems with many posts are mainly related to the size of the meta table. As we have seen above, the table is growing quite fast when you add more products. After adding 50 000 products, it contained around 650 000 rows. To test if the meta-table assumption was accurate, I added a function to my application, which removes all WooCommerce meta-fields after each product insertion cycle. The following command runs the 10 000 test with that addition.&lt;/p&gt;
&lt;pre class=&quot;brush: bash; title: ; notranslate&quot; title=&quot;&quot;&gt;

MYSQL_PID=4333 ITERATIONS=500 POST_INSERT_CHUNK=100 npm start

&lt;/pre&gt;
&lt;h3&gt;CPU&lt;/h3&gt;
&lt;p&gt;The CPU-chart already shows, that the idea seems to be correct. Without the big meta-table, the CPU-usage is slightly increasing, but almost stable, compared to before.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.danielauener.com/assets/media/original/0a20ff2a896d411743c0.png&quot; rel=&quot;attachment wp-att-822&quot;&gt;&lt;img class=&quot;alignnone wp-image-822 size-full&quot; src=&quot;https://www.danielauener.com/assets/media/original/0a20ff2a896d411743c0.png&quot; alt=&quot;Slow WooCommerce: CPU-usage without meta&quot; width=&quot;1051&quot; height=&quot;444&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/0a20ff2a896d411743c0.png 1051w, https://www.danielauener.com/assets/media/original/2346f76e430a011a4f67.png 300w, https://www.danielauener.com/assets/media/original/b25a6f25ded4d82194b2.png 768w, https://www.danielauener.com/assets/media/original/7a6089140ddf8afa61e7.png 1024w&quot; sizes=&quot;(max-width: 1051px) 100vw, 1051px&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Requests&lt;/h3&gt;
&lt;p&gt;The requests-chart gives us the same impression. The shop-page request time follows the usage values and is stable between 80 and 100 milliseconds.&lt;/p&gt;
&lt;p&gt;&lt;img class=&quot;alignnone wp-image-816&quot; src=&quot;https://www.danielauener.com/assets/media/original/4efc9c54aef9f119ca2d.png&quot; alt=&quot;Slow WooCommerce: Request times without meta&quot; width=&quot;1035&quot; height=&quot;490&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/4efc9c54aef9f119ca2d.png 1050w, https://www.danielauener.com/assets/media/original/4a8f827655f581790faf.png 300w, https://www.danielauener.com/assets/media/original/31c9f9048e4f9292c840.png 768w, https://www.danielauener.com/assets/media/original/cf88f3a26671120f8dbf.png 1024w&quot; sizes=&quot;(max-width: 1035px) 100vw, 1035px&quot;&gt;&lt;/p&gt;
&lt;h3&gt;Insertion Speed&lt;/h3&gt;
&lt;p&gt;Only the insertion speed is painting another picture. Here we have no performance advantage at all, removing the meta-fields. I’ve added the grey line of insertion times from the previous test and it actually is almost identical. That was  surprise, I have to admit. I thought there would be at least some difference.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.danielauener.com/assets/media/original/e51ce68a6368ea4059e1.png&quot; rel=&quot;attachment wp-att-819&quot;&gt;&lt;img class=&quot;alignnone wp-image-819 size-full&quot; src=&quot;https://www.danielauener.com/assets/media/original/e51ce68a6368ea4059e1.png&quot; alt=&quot;Slow WooCommerce: Inserts without meta fields&quot; width=&quot;1047&quot; height=&quot;434&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/e51ce68a6368ea4059e1.png 1047w, https://www.danielauener.com/assets/media/original/c902ba8363c330712e35.png 300w, https://www.danielauener.com/assets/media/original/761c16e0551019674bad.png 768w, https://www.danielauener.com/assets/media/original/3a4a6e729701aba3dcad.png 1024w&quot; sizes=&quot;(max-width: 1047px) 100vw, 1047px&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Conclusions&lt;/h2&gt;
&lt;p&gt;So, that was fun. But is there something we can do about it? Shouldn’t we use WooCommerce for more than 15 000 products?&lt;/p&gt;
&lt;p&gt;Yes, you should use WooCommerce, even for many products. But with the knowledge we gathered here, we are able to make some decisions early on, when building a shop, which should help us along the road.&lt;/p&gt;
&lt;p&gt;Some tips to avoid slow WooCommerce:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Check before you start building, how many products the shop will be selling, now and in the future.&lt;/li&gt;
&lt;li&gt;Avoid more meta-fields than absolutely necessary, that includes meta-fields on other post-types as well.&lt;/li&gt;
&lt;li&gt;As much as we love Advanced Custom Fields: for a big shop, you might want to skip on it. For every field you add to a product with ACF, you get 2 meta-fields in the database.&lt;/li&gt;
&lt;li&gt;Think about an eventual import process very early and test it several times, while building the shop. You need to know how much time it will take.&lt;/li&gt;
&lt;li&gt;Inform everyone about potentially long import sessions and the extra load on the servers they are causing.&lt;/li&gt;
&lt;li&gt;Use a good caching-plugin, which takes load off your server and frees resources for other stuff.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Even if you do everything right, at some point all precautions won’t help. Then you have to think about expanding your infrastructure. There are some tools which can help, like &lt;a href=&quot;https://www.elastic.co/&quot;&gt;Elasticsearch&lt;/a&gt; or &lt;a href=&quot;https://redis.io/&quot;&gt;Redis&lt;/a&gt;, and there are surely a hundred ways to code your way around WooCommerce limitations (e. g. two of my &lt;a href=&quot;https://www.danielauener.com/woocommerce-with-thousands-of-products-workarounds-for-slow-admin-panel/&quot;&gt;workarounds for the admin panel&lt;/a&gt;). And, last but not least, there is always the possibility of a bigger server or a more advanced architecture.&lt;/p&gt;
	</description></item><item><title>Redis with Node.js: Compress to Use Redis Memory Efficiently</title><link>https://www.danielauener.com/redis-with-node-js-gzip-mem-usage/</link><guid isPermaLink="false">http://www.danielauener.com/?p=781</guid><pubDate>Fri, 10 Feb 2017 13:00:47 GMT</pubDate><description>
		&lt;p&gt;In one of my bigger projects, we are using Redis with Node.js, as a buffer for large sets of monitoring data.&lt;/p&gt;
&lt;p&gt;When we deployed that from a test-case, with just one data-sending instance to about 150 instances, Redis ran out of memory quite fast. Depending on versions, operating system and some other things, that leads to either a crash of the Redis node or a significant performance decrease.&lt;/p&gt;
&lt;h2&gt;Redis with Node.js, when zipping is appropriate&lt;/h2&gt;
&lt;p&gt;It is important to know that Redis’s storage capacity is limited by its server’s memory. Basically that’s what’s making Redis so fast. That’s what the Redis FAQ tells us:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Redis is an in-memory but persistent on disk database, so it represents a different trade off where very high write and read speed is achieved with the limitation of data sets that can’t be larger than memory. (&lt;a href=&quot;https://redis.io/topics/faq&quot;&gt;Source Redis FAQ&lt;/a&gt;)&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;However, for large data sets, like ours, that leaves you with a difficult decision: Buy more expensive memory for your server or use CPU-power on your client to reduce the data-size by compressing. Which way is the right one for your specific setup, is something you have to sort out. First of all, a good starting point is &lt;a href=&quot;http://mensfeld.pl/2013/04/compressing-large-data-sets-in-redis-with-gzip-ruby-test-case/&quot;&gt;this study about a similar problem&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;On the other hand, it seems that when we have an application that uses Redis mostly for reading stuff from it, we might think about compressing the input data. However as I mentioned before – try not to overdo it and implement such a mechanism only when you really need it.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Now, did you make your decision? Read on if you want to know how to implement this with Node.js.&lt;/p&gt;
&lt;h2&gt;Compress Data for Redis with Node.js&lt;/h2&gt;
&lt;p&gt;The implementation is built on the following Node.js modules:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;redis&lt;/li&gt;
&lt;li&gt;zlib&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is how you write zipped data to redis:&lt;/p&gt;
&lt;pre class=&quot;brush: jscript; title: ; notranslate&quot; title=&quot;&quot;&gt;
var zlib = require(&amp;#39;zlib&amp;#39;),
  redis = require(&amp;#39;redis&amp;#39;),
  client = redis.createClient();

client.on(&amp;quot;error&amp;quot;, function (err) {
  console.log(&amp;quot;Error &amp;quot; + err);
});

var redisKey = &amp;#39;add_your_key_here&amp;#39;;
var redisValue = &amp;#39;Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim   ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.&amp;#39;;

zlib.deflate(redisValue, function (err, zippedValue) {

  if (err) {
    console.log(&amp;#39;Error deflating!&amp;#39;);
    return;
  }

  // you have to encode the binary zip-data to base64 to be able to read it
  // later
  client.set(redisKey, zippedValue.toString(&amp;#39;base64&amp;#39;), function (err) {

    if (err) {
      console.log(&amp;#39;Error saving to redis!&amp;#39;);
      return;
    }

    console.log(&amp;#39;Zipped value saved!&amp;#39;);

  });
});
&lt;/pre&gt;
&lt;p&gt;And that’s how you read it:&lt;/p&gt;
&lt;pre class=&quot;brush: jscript; title: ; notranslate&quot; title=&quot;&quot;&gt;
var zlib = require(&amp;#39;zlib&amp;#39;),
  redis = require(&amp;#39;redis&amp;#39;),
  client = redis.createClient();

client.on(&amp;quot;error&amp;quot;, function (err) {
  console.log(&amp;quot;Error &amp;quot; + err);
});

var redisKey = &amp;#39;add_your_key_here&amp;#39;;

client.get(redisKey, function (err, zippedValue) {

  if (err) {
    console.log(&amp;#39;Error reading from redis!&amp;#39;);
    return;
  }

  // you have to decode the base64 binary zip-data to base64
  zlib.inflate(new Buffer(zippedValue, &amp;#39;base64&amp;#39;), function (err, redisValue) {

    if (err) {
      console.log(&amp;#39;Error inflating!&amp;#39;);
      return;
    }

    console.log(redisValue);

  });
});
&lt;/pre&gt;
&lt;p&gt;Be aware of the &lt;strong&gt;base64 &lt;/strong&gt;encoding. That’s required so you are able to write and read binary zipped data in JavaScript. More information for example &lt;a href=&quot;http://stackoverflow.com/questions/20732332/how-to-store-a-binary-object-in-redis-using-node&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
	</description></item><item><title>ElasticPress &amp; WooCommerce: Deactivate Product Search Fuzziness</title><link>https://www.danielauener.com/elasticpress-woocommerce-fuzziness/</link><guid isPermaLink="false">http://www.danielauener.com/?p=774</guid><pubDate>Wed, 08 Feb 2017 20:57:04 GMT</pubDate><description>
		&lt;p&gt;I am a great fan of Elasticsearch, the &lt;a href=&quot;http://www.top-wordpress-plugins.com/plugins/elasticpress/&quot;&gt;ElasticPress plugin&lt;/a&gt; and the ElasticPress WooCommerce module. The other day, when I was working on a client’s WooCommerce shop, it was the first time I wasn’t satisfied with the quality of the search results, though.&lt;/p&gt;
&lt;p&gt;After some digging with the Debug bar and its ElasticPress extension, I could narrow down the problem to a combination of many similar titles in our database and the Elasticsearch fuzziness parameter. Of course the fantastic folks at &lt;a href=&quot;https://profiles.wordpress.org/10up/&quot;&gt;10up&lt;/a&gt; provide a filter for that in their ElasticPress plugin.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;So here is how to disable fuzziness in the search:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
function themeslug_deactivate_ep_fuzziness( $fuzz ) {
    return 0;
}
add_filter( &amp;#39;ep_fuzziness_arg&amp;#39;, &amp;#39;themeslug_deactivate_ep_fuzziness&amp;#39; );
&lt;/pre&gt;
&lt;p&gt;Of course you can even raise the fuzziness with the same method. If you want to adjust fuzziness depending on other search parameters, the filter provides two more arguments, &lt;strong&gt;&lt;code&gt;$search_fields &lt;/code&gt;&lt;/strong&gt;and &lt;strong&gt;$args&lt;/strong&gt;, which might help.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Recommendation&lt;/strong&gt;: If you want to use WordPress with Elasticsearch, you can get both with Kinsta. Read more on how to speed up WordPress with their Elasticsearch solution on the &lt;a href=&quot;https://kinsta.com/knowledgebase/wordpress-elasticsearch/?kaid=LJTEEDVAIWBS&quot; rel=&quot;nofollow&quot;&gt;Kinsta blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
	</description></item><item><title>WooCommerce with Thousands of Products: Workarounds for Slow Admin Panel</title><link>https://www.danielauener.com/woocommerce-with-thousands-of-products-workarounds-for-slow-admin-panel/</link><guid isPermaLink="false">http://www.danielauener.com/?p=768</guid><pubDate>Wed, 25 Jan 2017 09:41:12 GMT</pubDate><description>
		&lt;p&gt;It’s the WordPress plugin for webshops, without question. For a shop that is not running WooCommerce with thousands of products, it performs very well, too. However there are limitations and drawbacks running WooCommerce with many products. That’s mostly because it is built upon the WordPress database schema, which forces WooCommerce to save much data in the wp_postmeta table.&lt;/p&gt;
&lt;blockquote&gt;
&lt;h4&gt;&lt;em&gt;For a shop that is &lt;strong&gt;not&lt;/strong&gt; running WooCommerce with thousands of products, it has a very nice performance, too.&lt;/em&gt;&lt;/h4&gt;
&lt;/blockquote&gt;
&lt;p&gt;In my current installation, WooCommerce creates 26 meta-fields for each product, so the product related meta-table rows would grow beyond a million for more than 38 461 products. Adding other theme and plugin related fields, you might cross that mark much earlier. Depending on your server architecture, such a big meta-table, can make some database queries really slow.&lt;/p&gt;
&lt;blockquote&gt;
&lt;h4&gt;… product related meta-table rows would grow beyond a million for more than 38 461 products.&lt;/h4&gt;
&lt;/blockquote&gt;
&lt;p&gt;Running such a big shop should make you think about your server architecture. The odds are high that you can’t avoid an upgrade in the long run. However, sometimes a quick workaround is the only way to get things running again. Here are two quick and dirty fixes to make your admin panel faster, when running WooCommerce with thousands of products.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;WooCommerce Status Dashboard&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;With WooCommerce activated, you see an admin dashboard widget, that sums up your WooCommerce status, with sales per month, most sold product, order status and stock status. As it turns out, the stock status queries are very slow, depending on the meta-table size. Here is how to turn them off in your &lt;em&gt;&lt;strong&gt;functions.php&lt;/strong&gt;&lt;/em&gt; file:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
function themeslug_deactivate_stock_reports($from) {
 global $wpdb;
 return &amp;quot;FROM {$wpdb-&amp;amp;amp;amp;amp;gt;posts} as posts WHERE 1=0&amp;quot;;
}
add_filter( &amp;#39;woocommerce_report_low_in_stock_query_from&amp;#39;, &amp;#39;themeslug_deactivate_stock_reports&amp;#39; );
add_filter( &amp;#39;woocommerce_report_out_of_stock_query_from&amp;#39;, &amp;#39;themeslug_deactivate_stock_reports&amp;#39; ); 

&lt;/pre&gt;
&lt;p&gt;Note, that turning off these reports will result in 0-values in your dashboard!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.danielauener.com/assets/media/original/83336081cdfff6d22fd2.png&quot;&gt;&lt;img class=&quot;size-full wp-image-771 aligncenter&quot; src=&quot;https://www.danielauener.com/assets/media/original/83336081cdfff6d22fd2.png&quot; alt=&quot;woocommerce-status-dashboard-query&quot; width=&quot;620&quot; height=&quot;73&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/83336081cdfff6d22fd2.png 620w, https://www.danielauener.com/assets/media/original/bbc19bd0d3b1a107a371.png 300w&quot; sizes=&quot;(max-width: 620px) 100vw, 620px&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;h3&gt;Slow Edit WooCommerce Product for WordPress &amp;gt;= 4.4.0&lt;/h3&gt;
&lt;p&gt;Another effect of a big meta-table is the product edit page in wp-admin (it affects even the edit page of posts and pages). Since WordPress 4.4.0 an extra query is made to the meta-table, which might cause long loading times. And of course there is a hook to disable it. Place the following code in your &lt;em&gt;&lt;strong&gt;functions.php&lt;/strong&gt;&lt;/em&gt; file.&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;

function themeslug_postmeta_form_keys() {
 return false;
}
add_filter(&amp;#39;postmeta_form_keys&amp;#39;, &amp;#39;themeslug_postmeta_form_keys&amp;#39;);

&lt;/pre&gt;
&lt;p&gt;Be aware that this fix not only makes the edit page faster, it also turns off functionality in the meta-field box!&lt;/p&gt;
&lt;h3&gt;Other measures&lt;/h3&gt;
&lt;p&gt;There is much more you can do, to make WooCommerce with thousands of products faster, like optimizing your server architecture or using tools like Elasticsearch or Redis Cache. If you need to use the above workarounds, you always should consider some of these measures in the long run!&lt;/p&gt;
	</description></item><item><title>Yeah, finally loading Sidebars/Widgets with the WordPress REST API</title><link>https://www.danielauener.com/yeah-finally-loading-sidebarswidgets-with-the-wordpress-rest-api/</link><guid isPermaLink="false">http://www.danielauener.com/?p=764</guid><pubDate>Wed, 13 Jan 2016 09:00:30 GMT</pubDate><description>
		&lt;p&gt;Loading sidebars and widgets via the WordPress REST API is not supported yet, but if you need a quick workaround, the &lt;a title=&quot;WordPress REST API Sidebars Plugin &quot; href=&quot;https://github.com/martin-pettersson/wp-rest-api-sidebars&quot;&gt;&lt;em&gt;WP REST API Sidebars Plugin&lt;/em&gt;&lt;/a&gt; looks quite promising!&lt;/p&gt;
	</description></item><item><title>Manual reviews of handpicked WordPress themes</title><link>https://www.danielauener.com/manual-reviews-of-handpicked-wordpress-themes/</link><guid isPermaLink="false">http://www.danielauener.com/?p=761</guid><pubDate>Thu, 05 Mar 2015 05:10:18 GMT</pubDate><description>
		&lt;p&gt;Starting today, I will be reviewing themes at &lt;a href=&quot;http://www.bestthemesfor.com&quot;&gt;bestthemesfor.com&lt;/a&gt;.&lt;/p&gt;
	</description></item><item><title>Coding workflows: why Grunt changes our way of working </title><link>https://www.danielauener.com/coding-workflows-grunt-changes-way-working/</link><guid isPermaLink="false">http://www.danielauener.com/?p=726</guid><pubDate>Sun, 26 Jan 2014 00:55:29 GMT</pubDate><description>
		&lt;p&gt;A couple of months ago, I first heard about &lt;em&gt;Grunt&lt;/em&gt;. I wasn’t that impressed. It seemed to be like a more advanced &lt;em&gt;CodeKit&lt;/em&gt;, which was compiling my &lt;em&gt;SASS&lt;/em&gt; and &lt;em&gt;JS&lt;/em&gt; at the time. So I forgot about it, proving once again, that I’m just not an early bird :/ Of course the buzz got too big to ignore and now I am all into &lt;em&gt;Grunt&lt;/em&gt;, &lt;em&gt;Yeoman&lt;/em&gt; and even &lt;em&gt;Gulp&lt;/em&gt; like everyone else.&lt;/p&gt;
&lt;p&gt;Using &lt;em&gt;Grunt&lt;/em&gt; for some time now, I’m beginning to realize that it not only improved my workflow, but changed it. So this article is not about learning &lt;em&gt;Grunt&lt;/em&gt;, there already are &lt;a title=&quot;gruntjs automate all the things&quot; href=&quot;http://www.jorisooms.be/gruntjs-automate-all-the-things/&quot; target=&quot;_blank&quot;&gt;some&lt;/a&gt; &lt;a title=&quot;Getting started from gruntjs&quot; href=&quot;http://gruntjs.com/getting-started&quot; target=&quot;_blank&quot;&gt;of&lt;/a&gt; &lt;a title=&quot;Grunt tutorial&quot; href=&quot;http://www.brianchu.com/blog/2013/07/11/grunt-by-example-a-tutorial-for-javascripts-task-runner/&quot; target=&quot;_blank&quot;&gt;them&lt;/a&gt; out there. It is about why I think &lt;em&gt;Grunt,&lt;/em&gt; or more generally task managers like &lt;em&gt;Grunt &lt;/em&gt;will really make a difference in how web developers do their work.&lt;/p&gt;
&lt;h2&gt;A platform-independent foundation&lt;/h2&gt;
&lt;p&gt;But first some basics. One of the most important things about &lt;em&gt;Grunt&lt;/em&gt; is that it is based on &lt;em&gt;node.js &lt;/em&gt;and really runs independently of the platform. Also with n&lt;em&gt;ode.js &lt;/em&gt;comes its community, producing an impressive amount of functionality. All the node modules they are developing, from 100% javascripted ssh-clients to complete test frameworks, can be used with &lt;em&gt;Grunt&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Then there is &lt;em&gt;npm, &lt;/em&gt;the&lt;em&gt; node.js &lt;/em&gt;package manager. It lets you easily define all dependencies on a per-project basis. If you have to use the &lt;em&gt;compass&lt;/em&gt; mixin library in one project and want to use &lt;em&gt;bourbon &lt;/em&gt;in another, one line in your projects &lt;em&gt;packages.js &lt;/em&gt;and a &lt;em&gt;npm install&lt;/em&gt; fixes it&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Last but not least the &lt;em&gt;node.js &lt;/em&gt;world is all JavaScript. That is so important because all web developers, despite their back-end programming language preferences, know JavaScript. For a web developer there are basically no hurdles to getting started with &lt;em&gt;Grunt.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;All in all &lt;em&gt;node.js&lt;/em&gt; is a stable, well used and tested development foundation, with a living community and a huge amount of functionality packed in modules ready to download. Everything you need for your development workflow is already there. &lt;em&gt;Grunt&lt;/em&gt; just helps you to bundle it all together.&lt;/p&gt;
&lt;h2&gt;Coding workflows&lt;/h2&gt;
&lt;p&gt;So, why is this such a big change? Before &lt;em&gt;Grunt &lt;/em&gt;I already had a workflow. Or a kind of workflow that stayed pretty much the same for every project I was working on, but not entirely the same. This workflow even had multiple phases, like development, testing, bug-fixing and deployment and every one of them had different tasks. To remember all these at the right time can be impossible sometimes. I don’t know how many times I’ve forgotten to merge and compress CSS for deployment or to do a last coding standards check.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Grunt &lt;/em&gt;is helping with these tasks, by just letting you write them down and executing them automatically when you need them. That’s what a task-manager should do. But &lt;em&gt;Grunt, &lt;/em&gt;and that’s my point, is doing something more. It doesn’t only automate the tasks you have done before, it makes you build, rethink and structure them consciously. You have to think about what your workflow should look like in the beginning of a project and you have to refactor your workflow as the project evolves.&lt;/p&gt;
&lt;p&gt;What I mean is: with &lt;em&gt;Grunt &lt;/em&gt;we have begun to &lt;em&gt;&lt;strong&gt;code&lt;/strong&gt;&lt;/em&gt; our coding workflows&lt;strong&gt;.&lt;/strong&gt; Just as we code our tests when we do unit testing. You might think that’s no big deal, nothing a couple of Bash scripts couldn’t solve. I agree, technically it is nothing revolutionary. Yet, I think &lt;em&gt;Grunt&lt;/em&gt; will change a lot for web developers, because it is so well suited for sharing.&lt;/p&gt;
&lt;h2&gt;Sharing and evolving workflows&lt;/h2&gt;
&lt;p&gt;A Google search on &lt;em&gt;gist “gruntfile.js” &lt;/em&gt;returns more than 5000 hits. So it seems that we are not just &lt;em&gt;coding&lt;/em&gt; workflows with &lt;em&gt;Grunt&lt;/em&gt;, we’ve even started to share them. I’m convinced that’s because of the facts about &lt;em&gt;node.js&lt;/em&gt; I’ve named before and that every web developer is able to write some JavaScript tasks in no time. That is the good thing with &lt;em&gt;coding workflows. &lt;/em&gt;We are so incredibly good at improving our code. We already have a huge community, doing nothing else than improving code all the time. So, now our workflows have become formalized code, we can improve them the same way. We can share them on &lt;em&gt;GitHub, &lt;/em&gt;ask about them on &lt;em&gt;Stack Overflow, &lt;/em&gt;discuss them in our blogs or compare them to others’ workflows.&lt;/p&gt;
&lt;p&gt;So I think, over time, this will change a lot about how web developers work. &lt;span style=&quot;line-height: 1.5em;&quot;&gt;That said, the perfect finish to this article seems to be my own &lt;/span&gt;&lt;a style=&quot;line-height: 1.5em;&quot; title=&quot;My gruntfile.js&quot; href=&quot;https://gist.github.com/danielauener/8626082.js&quot; target=&quot;_blank&quot;&gt;gruntfile.js&lt;/a&gt;&lt;span style=&quot;line-height: 1.5em;&quot;&gt;, defining my current &lt;/span&gt;&lt;a style=&quot;line-height: 1.5em;&quot; title=&quot;Yeoman WordPress theme generator – kickstart a grunting SCSS theme&quot; href=&quot;https://www.danielauener.com/yeoman-wordpress-theme-generator/&quot;&gt;WordPress theme workflow&lt;/a&gt;&lt;span style=&quot;line-height: 1.5em;&quot;&gt;:&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;brush: jscript; title: ; notranslate&quot; title=&quot;&quot;&gt;
module.exports = function(grunt) {

	grunt.initConfig({

		pkg: grunt.file.readJSON(&amp;#39;package.json&amp;#39;),

		// chech our JS
		jshint: {
			options: {
				&amp;quot;bitwise&amp;quot;: true,
				&amp;quot;browser&amp;quot;: true,
				&amp;quot;curly&amp;quot;: true,
				&amp;quot;eqeqeq&amp;quot;: true,
				&amp;quot;eqnull&amp;quot;: true,
				&amp;quot;esnext&amp;quot;: true,
				&amp;quot;immed&amp;quot;: true,
				&amp;quot;jquery&amp;quot;: true,
				&amp;quot;latedef&amp;quot;: true,
				&amp;quot;newcap&amp;quot;: true,
				&amp;quot;noarg&amp;quot;: true,
				&amp;quot;node&amp;quot;: true,
				&amp;quot;strict&amp;quot;: false,
				&amp;quot;trailing&amp;quot;: true,
				&amp;quot;undef&amp;quot;: true,
				&amp;quot;globals&amp;quot;: {
					&amp;quot;jQuery&amp;quot;: true,
					&amp;quot;alert&amp;quot;: true
				}
			},
			all: [
				&amp;#39;gruntfile.js&amp;#39;,
				&amp;#39;../js/scripts.js&amp;#39;
			]
		},

		// concat and minify our JS
		uglify: {
			dist: {
				files: {
					&amp;#39;../js/scripts.min.js&amp;#39;: [
						&amp;#39;../js/scripts.js&amp;#39;
					]
				}
			}
		},

		// compile your sass
		sass: {
			dev: {
				options: {
					style: &amp;#39;expanded&amp;#39;
				},
				src: [&amp;#39;../scss/style.scss&amp;#39;],
				dest: &amp;#39;../style.css&amp;#39;
			},
			prod: {
				options: {
					style: &amp;#39;compressed&amp;#39;
				},
				src: [&amp;#39;../scss/style.scss&amp;#39;],
				dest: &amp;#39;../style.css&amp;#39;
			},
			editorstyles: {
				options: {
					style: &amp;#39;expanded&amp;#39;
				},
				src: [&amp;#39;../scss/wp-editor-style.scss&amp;#39;],
				dest: &amp;#39;../css/wp-editor-style.css&amp;#39;
			}
		},

		// watch for changes
		watch: {
			scss: {
				files: [&amp;#39;../scss/**/*.scss&amp;#39;],
				tasks: [
					&amp;#39;sass:dev&amp;#39;,
					&amp;#39;sass:editorstyles&amp;#39;,
					&amp;#39;notify:scss&amp;#39;
				]
			},
			js: {
				files: [
					&amp;#39;&amp;lt;%= jshintTag %&amp;gt;&amp;#39;
				],
				tasks: [
					&amp;#39;jshint&amp;#39;,
					&amp;#39;uglify&amp;#39;,
					&amp;#39;notify:js&amp;#39;
				]
			}
		},

		// check your php
		phpcs: {
			application: {
				dir: &amp;#39;../*.php&amp;#39;
			},
			options: {
				bin: &amp;#39;/usr/bin/phpcs&amp;#39;
			}
		},

		// notify cross-OS
		notify: {
			scss: {
				options: {
					title: &amp;#39;Grunt, grunt!&amp;#39;,
					message: &amp;#39;SCSS is all gravy&amp;#39;
				}
			},
			js: {
				options: {
					title: &amp;#39;Grunt, grunt!&amp;#39;,
					message: &amp;#39;JS is all good&amp;#39;
				}
			},
			dist: {
				options: {
					title: &amp;#39;Grunt, grunt!&amp;#39;,
					message: &amp;#39;Theme ready for production&amp;#39;
				}
			}
		},

		clean: {
			dist: {
				src: [&amp;#39;../dist&amp;#39;],
				options: {
					force: true
				}
			}
		},

		copyto: {
			dist: {
				files: [
					{cwd: &amp;#39;../&amp;#39;, src: [&amp;#39;**/*&amp;#39;], dest: &amp;#39;../dist/&amp;#39;}
				],
				options: {
					ignore: [
						&amp;#39;../dist{,/**/*}&amp;#39;,
						&amp;#39;../doc{,/**/*}&amp;#39;,
						&amp;#39;../grunt{,/**/*}&amp;#39;,
						&amp;#39;../scss{,/**/*}&amp;#39;
					]
				}
			}
		}
	});

	// Load NPM&amp;#39;s via matchdep
	require(&amp;#39;matchdep&amp;#39;).filterDev(&amp;#39;grunt-*&amp;#39;).forEach(grunt.loadNpmTasks);

	// Development task
	grunt.registerTask(&amp;#39;default&amp;#39;, [
		&amp;#39;jshint&amp;#39;,
		&amp;#39;uglify&amp;#39;,
		&amp;#39;sass:dev&amp;#39;,
		&amp;#39;sass:editorstyles&amp;#39;
	]);

	// Production task
	grunt.registerTask(&amp;#39;dist&amp;#39;, function() {
		grunt.task.run([
			&amp;#39;jshint&amp;#39;,
			&amp;#39;uglify&amp;#39;,
			&amp;#39;sass:prod&amp;#39;,
			&amp;#39;sass:editorstyles&amp;#39;,
			&amp;#39;clean:dist&amp;#39;,
			&amp;#39;copyto:dist&amp;#39;,
			&amp;#39;notify:dist&amp;#39;
		]);
	});
};
&lt;/pre&gt;
	</description></item><item><title>SASS color schemes with grunt</title><link>https://www.danielauener.com/sass-color-schemes-grunt/</link><guid isPermaLink="false">http://www.danielauener.com/?p=699</guid><pubDate>Thu, 16 Jan 2014 15:18:26 GMT</pubDate><description>
		&lt;p&gt;SASS/SCSS and Grunt are fantastic tools to organize and automate CSS development. With some easy adjustments you can even make Grunt compile your CSS for multiple color schemes.&lt;/p&gt;
&lt;h2&gt;Build your base SASS color scheme&lt;/h2&gt;
&lt;p&gt;The easiest way to prepare your files for auto-compiling SASS color schemes is to create a color variable for every color you want to change in your schemes. You should do that in a separate section of your code, so you can easily copy all color variables and create a new color scheme. The only thing you have to think of is to add the &lt;em&gt;default-&lt;/em&gt;attribute to the variables, so they can be overridden. I usually end up with a section like that in my styles:&lt;/p&gt;
&lt;pre class=&quot;brush: css; title: ; notranslate&quot; title=&quot;&quot;&gt;

/*
 * Default colors
 */

$light: #fafaf9 !default;
$dark: #111111 !default;

$color-1: #ef4f47 !default;
$color-2: #75d9c6 !default;
$color-3: #ffe851 !default;

&lt;/pre&gt;
&lt;h2&gt;Preparing additional SASS color schemes&lt;/h2&gt;
&lt;p&gt;The next step is to create all color scheme files. Create a folder called &lt;em&gt;schemes&lt;/em&gt; or something like that, and put a file with the name &lt;em&gt;color-scheme-1.scss &lt;/em&gt;in it. This file should define your color variables again (without the &lt;em&gt;default&lt;/em&gt;-attribute) and include all other styles after the variables.&lt;/p&gt;
&lt;pre class=&quot;brush: css; title: ; notranslate&quot; title=&quot;&quot;&gt;
/*
 * Color scheme 1
 */
$light: #efefef;
$dark: #222;

$color-1: red;
$color-2: green;
$color-3: blue;

@import &amp;quot;../style&amp;quot;;

&lt;/pre&gt;
&lt;p&gt;Now you can create as many SASS color scheme files as you want, just repeat this pattern in every scheme.&lt;/p&gt;
&lt;h2&gt;Automated SASS color scheme Grunt task&lt;/h2&gt;
&lt;p&gt;Finally, it’s time to set up your Grunt tasks. I assume you know how to &lt;a title=&quot;Compile SASS with grunt-contrib-sass&quot; href=&quot;https://github.com/gruntjs/grunt-contrib-sass&quot;&gt;compile SASS/SCSS via grunt&lt;/a&gt;, so the only thing to do is to add a sass-task for every scheme in your Grunt file:&lt;/p&gt;
&lt;pre class=&quot;brush: jscript; title: ; notranslate&quot; title=&quot;&quot;&gt;

sass: {
    dev: {
        src: &amp;#39;scss/style.scss&amp;#39;,
        dest: &amp;#39;style.css&amp;#39;
    },
    &amp;#39;color-scheme-1&amp;#39;: {
        src: &amp;#39;scss/schemes/color-scheme-1.scss&amp;#39;,
        dest: &amp;#39;css/color-scheme-1.css&amp;#39;
    },
    &amp;#39;color-scheme-2&amp;#39;: {
        src: &amp;#39;scss/schemes/color-scheme-2.scss&amp;#39;,
        dest: &amp;#39;css/color-scheme-2.css&amp;#39;
    }
},

&lt;/pre&gt;
&lt;p&gt;Now run&lt;/p&gt;
&lt;p&gt;&lt;code&gt;grunt sass:color-scheme-1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;and you get a &lt;em&gt;color-scheme-1.css&lt;/em&gt; file in your &lt;em&gt;css&lt;/em&gt;-directory. If you include this file instead of your default &lt;em&gt;style.css&lt;/em&gt;, you will get your layout in the scheme’s colors. Auto generate all schemes with&lt;/p&gt;
&lt;p&gt;&lt;code&gt;grunt sass&lt;/code&gt;&lt;/p&gt;
	</description></item><item><title>Yeoman WordPress theme generator - kickstart a grunting SCSS theme</title><link>https://www.danielauener.com/yeoman-wordpress-theme-generator/</link><guid isPermaLink="false">http://www.danielauener.com/?p=678</guid><pubDate>Mon, 06 Jan 2014 08:08:18 GMT</pubDate><description>
		&lt;p&gt;This post describes a super simple and time-saving Yeoman workflow to build WordPress themes. To make this post work for you, you should have a basic understanding of &lt;a title=&quot;nodejs&quot; href=&quot;http://nodejs.org/&quot; target=&quot;_blank&quot;&gt;nodejs&lt;/a&gt;, Node’s package manager &lt;a title=&quot;npm&quot; href=&quot;https://npmjs.org/&quot; target=&quot;_blank&quot;&gt;npm&lt;/a&gt;, &lt;a title=&quot;yeoman&quot; href=&quot;http://yeoman.io/&quot; target=&quot;_blank&quot;&gt;Yeoman&lt;/a&gt; workflows, &lt;a title=&quot;Grunt&quot; href=&quot;http://gruntjs.com/&quot; target=&quot;_blank&quot;&gt;Grunt&lt;/a&gt; and &lt;a title=&quot;SASS/SCSS&quot; href=&quot;http://sass-lang.com/&quot; target=&quot;_blank&quot;&gt;SASS/SCSS&lt;/a&gt;. Once you have everything up and running, you will create a Yeoman WordPress starter theme in no time. But it is not only a theme; it comes with a bunch of features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A fully functional WordPress theme with a working &lt;em&gt;grunt&lt;/em&gt; development environment.&lt;/li&gt;
&lt;li&gt;The generated theme is &lt;span style=&quot;line-height: 1.5em;&quot;&gt;tested against the &lt;/span&gt;&lt;a style=&quot;line-height: 1.5em;&quot; href=&quot;http://wordpress.org/plugins/theme-check/&quot;&gt;Theme check&lt;/a&gt;&lt;span style=&quot;line-height: 1.5em;&quot;&gt; and &lt;/span&gt;&lt;a style=&quot;line-height: 1.5em;&quot; href=&quot;http://wordpress.org/plugins/themeforest-check/&quot;&gt;Theme Forest check&lt;/a&gt;&lt;span style=&quot;line-height: 1.5em;&quot;&gt; plugins and runs without errors, warnings or recommendations, is &lt;/span&gt;&lt;span style=&quot;line-height: 1.5em;&quot;&gt;visually tested with &lt;/span&gt;&lt;a style=&quot;line-height: 1.5em;&quot; href=&quot;https://wpcom-themes.svn.automattic.com/demo/theme-unit-test-data.xml&quot;&gt;Testdata for the theme unit test&lt;/a&gt;, runs without errors or warnings in debug mode and follows the WordPress coding standards completely&lt;/li&gt;
&lt;li&gt;A pre-filled HTML documentation&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Getting started&lt;/h2&gt;
&lt;p&gt;Getting started with nodejs, npm and Yeoman is well described elsewhere, so instead of repeating all of it you will get some &lt;a title=&quot;Nodejs&quot; href=&quot;http://nodejs.org/&quot; target=&quot;_blank&quot;&gt;links&lt;/a&gt; &lt;a title=&quot;Installing nodejs&quot; href=&quot;http://howtonode.org/how-to-install-nodejs&quot; target=&quot;_blank&quot;&gt;that&lt;/a&gt; &lt;a href=&quot;http://yeoman.io/gettingstarted.html&quot; target=&quot;_blank&quot;&gt;worked&lt;/a&gt; for me. To go on, you should have the current version of nodejs, npm and yeoman running. Then you can easily install our generator from the &lt;a title=&quot;Yeoman WordPress theme generator&quot; href=&quot;https://npmjs.org/package/generator-wp-theme&quot; target=&quot;_blank&quot;&gt;npm registry&lt;/a&gt;. Note that on some setups you will have to run this command with super-user permissions:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;npm install -g generator-wp-theme&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Now you have installed the generator you can generate your first starter theme. As you might want to test it in your WordPress development environment, you should go to a running WordPress installation’s themes directory and run:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;yo wp-theme&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;That’s it! Just answer some simple questions in the terminal and the installation should run through without errors, installing the theme plus all needed local node modules.&lt;/p&gt;
&lt;h2&gt;Developing with the Yeoman WordPress theme&lt;/h2&gt;
&lt;p&gt;First of all the generated starter theme provides you with a solid base of WordPress theme templates, following among others WordPress theme directory and ThemeForest standard requirements. The functions.php file sets your theme up to support all required functions like a custom header and background. All should be ready to make your adjustments to build a perfect theme.&lt;/p&gt;
&lt;h3&gt;SASS/SCSS setup&lt;/h3&gt;
&lt;p&gt;The theme’s style.css file is compiled from a bunch of SCSS-files. To get a layout grid and some nice mixins the bourbon and neat libraries are built in. The SCSS-file names should be self-explanatory, however a short overview in inclusion order follows:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;em&gt;vendor/normalize&lt;/em&gt;&lt;/dt&gt;
&lt;dd&gt;Includes the normalizing css.&lt;/dd&gt;
&lt;dt&gt;&lt;em&gt;vendor/bourbon/bourbon&lt;/em&gt;&lt;/dt&gt;
&lt;dd&gt;Includes the great bourbon mixin library.&lt;/dd&gt;
&lt;dt&gt;&lt;em&gt;_base.scss&lt;/em&gt;&lt;/dt&gt;
&lt;dd&gt;Defines the main colors of the themes and basic HTML-element styling.&lt;/dd&gt;
&lt;dt&gt;&lt;em&gt;_grid-settings.scss&lt;/em&gt;&lt;/dt&gt;
&lt;dd&gt;Defines and includes the base setup for the themes grid. The default grid is bourbons neat.&lt;/dd&gt;
&lt;dt&gt;&lt;em&gt;_typography.scss&lt;/em&gt;&lt;/dt&gt;
&lt;dd&gt;Defines all fonts, typography related mixins and HTML-element styles. Defines even some font-size variables.&lt;/dd&gt;
&lt;dd&gt;&lt;/dd&gt;
&lt;dt&gt;&lt;em&gt;_components.scss&lt;/em&gt;&lt;/dt&gt;
&lt;dd&gt;Place the basic mixins and placeholders for the theme.&lt;/dd&gt;
&lt;dt&gt;&lt;em&gt;_wp-base.scss&lt;/em&gt;&lt;/dt&gt;
&lt;dd&gt;Defines some basic WordPress classes, like &lt;em&gt;sticky&lt;/em&gt;, &lt;em&gt;alignleft&lt;/em&gt; or &lt;em&gt;bypostauthor&lt;/em&gt;.&lt;/dd&gt;
&lt;dt&gt;&lt;em&gt;_header.scss&lt;/em&gt;&lt;/dt&gt;
&lt;dd&gt;Contains the header styles.&lt;/dd&gt;
&lt;dt&gt;&lt;em&gt;_navigation.scss&lt;/em&gt;&lt;/dt&gt;
&lt;dd&gt;Contains the navigation styles.&lt;/dd&gt;
&lt;dt&gt;&lt;em&gt;_content.scss&lt;/em&gt;&lt;/dt&gt;
&lt;dd&gt;Contains the basic content styles for posts and pages.&lt;/dd&gt;
&lt;dt&gt;&lt;em&gt;_post-formats.scss&lt;/em&gt;&lt;/dt&gt;
&lt;dd&gt;Extends the content styling with styling for multiple WordPress post formats.&lt;/dd&gt;
&lt;dt&gt;&lt;em&gt;_footer.scss&lt;/em&gt;&lt;/dt&gt;
&lt;dd&gt;Contains the footer styles.&lt;/dd&gt;
&lt;/dl&gt;
&lt;h3&gt;Grunt tasks&lt;/h3&gt;
&lt;p&gt;The generated Yeoman WordPress theme provides a working Grunt configuration. All Grunt related assets like the &lt;em&gt;gruntfile.js&lt;/em&gt; and the &lt;em&gt;package.js&lt;/em&gt; are placed in the &lt;em&gt;grunt&lt;em&gt; directory. &lt;/em&gt;&lt;/em&gt;The Yeoman generator has already set up Grunt for the theme and installed all node modules in &lt;em&gt;grunt/node_modules&lt;/em&gt;. If you want to install manually, go to the &lt;em&gt;grunt&lt;/em&gt; directory and run&lt;/p&gt;
&lt;pre&gt;npm install --save-dev&lt;/pre&gt;
&lt;p&gt;All Grunt tasks are called from the &lt;em&gt;grunt&lt;/em&gt; directory. You can manage the following available tasks, by running these commands:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;em&gt;grunt&lt;/em&gt;&lt;/dt&gt;
&lt;dd&gt;Is running the default task-list, which is the same as running &lt;em&gt;grunt jshint&lt;/em&gt;, &lt;em&gt;grunt uglify&lt;/em&gt; and &lt;em&gt;grunt sass&lt;/em&gt;.&lt;/dd&gt;
&lt;dt&gt;&lt;em&gt;grunt jshint&lt;/em&gt;&lt;/dt&gt;
&lt;dd&gt;Checks the JavaScript files and gives you some hints.&lt;/dd&gt;
&lt;dt&gt;&lt;em&gt;grunt uglify&lt;/em&gt;&lt;/dt&gt;
&lt;dd&gt;Takes the JavaScript files and concatenates and minifies them into one file: &lt;em&gt;js/scripts.min.js&lt;/em&gt;, which is included in the theme.&lt;/dd&gt;
&lt;dt&gt;&lt;em&gt;grunt sass:dev&lt;/em&gt;&lt;/dt&gt;
&lt;dd&gt;Is compiling all the scss files to one &lt;em&gt;expanded&lt;/em&gt; style.css in the theme’s root directory.&lt;/dd&gt;
&lt;dt&gt;&lt;em&gt;grunt sass:prod&lt;/em&gt;&lt;/dt&gt;
&lt;dd&gt;Is compiling all the scss files to one &lt;em&gt;compressed&lt;/em&gt; style.css in the theme’s root directory.&lt;/dd&gt;
&lt;dt&gt;&lt;em&gt;grunt watch&lt;/em&gt;&lt;/dt&gt;
&lt;dd&gt;Watches the scss and js files for changes and runs the above tasks automatically, plus giving you a cross-OS desktop notice on success.&lt;/dd&gt;
&lt;dt&gt;&lt;em&gt;grunt dist&lt;/em&gt;&lt;/dt&gt;
&lt;dd&gt;Runs &lt;em&gt;grunt uglify&lt;/em&gt; and &lt;em&gt;grunt sass:prod&lt;/em&gt;, takes all the production relevant theme files and places them in the &lt;em&gt;dist&lt;/em&gt; directory under the theme’s root. Now the &lt;em&gt;dist&lt;/em&gt; directory contains a production ready theme, which can be uploaded to a live server.&lt;/dd&gt;
&lt;dt&gt;&lt;em&gt;grunt phpcs&lt;/em&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;b&gt;Requires PHP CodeSniffer with WordPress standard installed in the development environment.&lt;/b&gt;&lt;br&gt;
Checks the theme’s PHP files against the WordPress coding standards.&lt;/dd&gt;
&lt;/dl&gt;
&lt;h2&gt;Documentation&lt;/h2&gt;
&lt;p&gt;In case you want to upload your theme to some marketplace or theme directory, Yeoman WordPress theme generator even creates HTML documentation for you. The documentation is based on the &lt;a title=&quot;Theme forrest documentation template&quot; href=&quot;http://blog.themeforest.net/site-news/building-better-template-documentation/&quot; target=&quot;_blank&quot;&gt;Theme forrest documentation template&lt;/a&gt; It’s located in the &lt;em&gt;doc&lt;em&gt; directory&lt;/em&gt;&lt;/em&gt; and already covers some base information about your theme. You just have to complete it with your specific information and your theme is documented as well.&lt;/p&gt;
&lt;h2&gt;Now, make themes!&lt;/h2&gt;
&lt;p&gt;With the Yeoman WordPress theme generator (&lt;a title=&quot;generator-wp-grunted-theme&quot; href=&quot;https://github.com/danielauener/generator-wp-grunted-theme&quot;&gt;generator-wp-grunted-theme&lt;/a&gt;), you should get everything you need, to build great themes. Be welcome to let me know if you have done so, or even better if you want to add an important task, find a bug or have an improvement idea.&lt;/p&gt;
	</description></item><item><title>Use echo inside a PHP one-line if statement</title><link>https://www.danielauener.com/use-echo-inside-php-one-line-statement/</link><guid isPermaLink="false">http://www.danielauener.com/?p=673</guid><pubDate>Tue, 03 Dec 2013 11:55:41 GMT</pubDate><description>
		&lt;p&gt;I got some great answers on my latest Stack Overflow question on why echo doesn’t work inside a one-line if statement in PHP.&lt;/p&gt;
&lt;p&gt;&lt;a title=&quot;Use echo inside a PHP one-line if statement&quot; href=&quot;http://stackoverflow.com/questions/20346451/use-echo-inside-php-one-line-if-statement&quot; target=&quot;_blank&quot;&gt;http://stackoverflow.com/questions/20346451/use-echo-inside-php-one-line-if-statement&lt;/a&gt;&lt;/p&gt;
	</description></item><item><title>WordPress history</title><link>https://www.danielauener.com/667/</link><guid isPermaLink="false">http://www.danielauener.com/?p=667</guid><pubDate>Thu, 21 Nov 2013 19:59:37 GMT</pubDate><description>
		&lt;p&gt;Can’t wait to read the rest: great preview of an upcoming book about the history of WordPress.&lt;br&gt;
&lt;a href=&quot;http://wordpress.org/about/history/chapter3.pdf&quot;&gt;http://wordpress.org/about/history/chapter3.pdf&lt;br&gt;
&lt;/a&gt;#wordpress #history&lt;/p&gt;
	</description></item><item><title>Shaun Andrews on improving WordPress Widgets</title><link>https://www.danielauener.com/shaun-andrews-improving-wordpress-widgets/</link><guid isPermaLink="false">http://www.danielauener.com/?p=663</guid><pubDate>Tue, 12 Nov 2013 10:58:16 GMT</pubDate><description>
		&lt;p&gt;Some great thoughts on improving WordPress Widgets. The admin-UI changes are totally convincing. I’d like to see some thoughts on how to solve the “How do I install widgets” problem. The comments, too, on widgets per post are absolutely worth reading.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.shaunandrews.com/wordpress-widgets-initial-thoughts/&quot; title=&quot;Improve WordPress Widgets&quot; target=&quot;_blank&quot;&gt;http://www.shaunandrews.com/wordpress-widgets-initial-thoughts/&lt;/a&gt;&lt;/p&gt;
	</description></item><item><title>Great Grunt, goodbye CodeKit.</title><link>https://www.danielauener.com/great-grunt-goodbye-codekit/</link><guid isPermaLink="false">http://www.danielauener.com/?p=658</guid><pubDate>Thu, 07 Nov 2013 18:44:24 GMT</pubDate><description>
		&lt;p&gt;I’m into Grunt now. Goodbye, CodeKit. #grunt #codekit&lt;/p&gt;
	</description></item><item><title>WordPress register with email only, using Gravity Forms and User Registration add-on</title><link>https://www.danielauener.com/wordpress-register-with-email-only-using-gravity-forms-user-registration-add/</link><guid isPermaLink="false">http://www.danielauener.com/?p=653</guid><pubDate>Thu, 07 Nov 2013 18:33:01 GMT</pubDate><description>
		&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
&amp;lt;?php

/**
 * WordPress register with email only, make it possible to register with email 
 * as username in a multisite installation
 * @param  Array $result Result array of the wpmu_validate_user_signup-function
 * @return Array         Altered result array
 */
function custom_register_with_email($result) {

	if ( $result[&amp;#39;user_name&amp;#39;] != &amp;#39;&amp;#39; &amp;amp;&amp;amp; is_email( $result[&amp;#39;user_name&amp;#39;] ) ) {

		unset( $result[&amp;#39;errors&amp;#39;]-&amp;gt;errors[&amp;#39;user_name&amp;#39;] );

	}

	return $result;
}
add_filter(&amp;#39;wpmu_validate_user_signup&amp;#39;,&amp;#39;custom_register_with_email&amp;#39;);

?&amp;gt;
&lt;/pre&gt;
&lt;h2&gt;The snippet’s story&lt;/h2&gt;
&lt;p&gt;A few days ago, I implemented a custom user registration with WordPress. I used Gravity Forms with the User Registration add-on, which worked fine when the user had to choose a username manually. But we also wanted a quick-registration option on the homepage, which we wanted to work with only one form-field asking for an email-address. So I built a Gravity Form with just an email field and added a User Registration with the email-field linked both as the required user’s email and username. &lt;/p&gt;
&lt;p&gt;This works fine with a single install, but with a multi-site installation the &lt;em&gt;wpmu_validate_user_signup&lt;/em&gt;-function is used and we got an “&lt;em&gt;Only lowercase letters (a-z) and numbers are allowed.&lt;/em&gt;” error-message. The above filter fixes this issue by undoing this validation error and forcing WordPress to accept an email address as username.&lt;/p&gt;
	</description></item><item><title>Polyfill alternative with SASS</title><link>https://www.danielauener.com/polyfill-alternative-sass/</link><guid isPermaLink="false">http://www.danielauener.com/?p=643</guid><pubDate>Mon, 21 Oct 2013 11:47:11 GMT</pubDate><description>
		&lt;p&gt;When polyfills just don’t feel right: automatically build your IE-fix CSS with SASS. &lt;a href=&quot;http://t.co/cbnrMg5UDZ&quot;&gt;http://t.co/cbnrMg5UDZ&lt;/a&gt; and &lt;a href=&quot;http://t.co/KLpM1eNKtC&quot;&gt;http://t.co/KLpM1eNKtC&lt;/a&gt; #ie8 #css #sass&lt;/p&gt;
	</description></item><item><title>Build a fully customized WordPress login: Those annoying redirects</title><link>https://www.danielauener.com/build-fully-customized-wordpress-login-annoying-redirects/</link><guid isPermaLink="false">http://www.danielauener.com/?p=634</guid><pubDate>Thu, 17 Oct 2013 11:07:22 GMT</pubDate><description>
		&lt;p&gt;I’ve built quite a few custom login-forms in WordPress. There are, as always, a lot of ways to realize that, but nearly all the clients I worked with, had similar requirements: On the one hand they wanted to preserve the usual WordPress login-form to let administrators, editors and authors sign in to wp-admin. On the other hand they wanted another usergroup to sign in to their site via a fully customized WordPress login-screen, to download protected documents or whatever.&lt;/p&gt;
&lt;h2&gt;Customized WordPress login-form&lt;/h2&gt;
&lt;p&gt;Generally the problem is solved fairly easily, using the WordPress-API. You can print out a standard login-form by using &lt;a href=&quot;http://codex.wordpress.org/Function_Reference/wp_login_form&quot; title=&quot;WordPress API: wp_login_form &quot; target=&quot;_blank&quot;&gt;wp_login_form&lt;/a&gt; wherever in your theme you want it. There is even a way to specify the page, the user should be redirected to after a successful login. Here is an example, redirecting you to the home page:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
&amp;lt;?php
    wp_login_form( array(
        &amp;#39;redirect&amp;#39; =&amp;gt; get_bloginfo(&amp;#39;url&amp;#39;), 
        &amp;#39;form_id&amp;#39; =&amp;gt; &amp;#39;sign-in&amp;#39;,
        &amp;#39;label_log_in&amp;#39; =&amp;gt; __( &amp;#39;Sign in&amp;#39; ),
    ) );
?&amp;gt;
&lt;/pre&gt;
&lt;p&gt;If you need to adjust the HTML-output, you can build your own sign in form markup by saving a file named &lt;strong&gt;searchform.php&lt;/strong&gt; in your theme folder. Then you are just a few stylesheet-rules away from your customized form, with working login. &lt;/p&gt;
&lt;h2&gt;Handling login-fails&lt;/h2&gt;
&lt;p&gt;The problems begin when you fail to log in, because writing in a wrong username and/or password doesn’t redirect you to your customized form, it redirects you to the wp-admin site. Since the signing-in user is not supposed to log in to wp-admin, this redirect doesn’t make any sense. But again we find a straightforward solution in the WordPress-API. Add these lines to your functions.php:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
function custom_login_failed( $username ) {
    $referrer = $_SERVER[&amp;#39;HTTP_REFERER&amp;#39;];

    if ( !empty($referrer) &amp;amp;&amp;amp; !strstr($referrer,&amp;#39;wp-login&amp;#39;) &amp;amp;&amp;amp; !strstr($referrer,&amp;#39;wp-admin&amp;#39;) ) {
	
        // redirect to your login page, you might want to add a parameter login_failed
        // to show an error message or something like that
        wp_redirect( ... );
	exit;
    }
}
add_action( &amp;#39;wp_login_failed&amp;#39;, &amp;#39;custom_login_failed&amp;#39; );
&lt;/pre&gt;
&lt;p&gt;You might think that’s all, but not so fast …&lt;/p&gt;
&lt;h2&gt;Handling empty logins&lt;/h2&gt;
&lt;p&gt;There is yet another way to get redirected to the wp-admin login form, and that is when you just don’t enter anything. Submit the form with an empty username and password field and you are on wp-admin again. That is because the &lt;strong&gt;wp_authenticate&lt;/strong&gt; function, which handles redirection, ignores &lt;em&gt;empty_username&lt;/em&gt; and &lt;em&gt;empty_password&lt;/em&gt; as error codes and that is why our &lt;em&gt;wp_login_failed&lt;/em&gt; action never fires. The solution is to change these error codes, if the user logs in from another site than wp-admin or wp-login.php. This is done by the following filter function (note the filter priority, which is important here).&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
function custom_authenticate( $user, $username, $password ) {

    if ( is_wp_error( $user ) &amp;amp;&amp;amp; isset( $_SERVER[ &amp;#39;HTTP_REFERER&amp;#39; ] ) &amp;amp;&amp;amp; !strpos( $_SERVER[ &amp;#39;HTTP_REFERER&amp;#39; ], &amp;#39;wp-admin&amp;#39; ) &amp;amp;&amp;amp; !strpos( $_SERVER[ &amp;#39;HTTP_REFERER&amp;#39; ], &amp;#39;wp-login.php&amp;#39; ) ) {
    	$referrer = $_SERVER[ &amp;#39;HTTP_REFERER&amp;#39; ];
    	foreach ( $user-&amp;gt;errors as $key =&amp;gt; $error ) {
    		if ( in_array( $key, array( &amp;#39;empty_password&amp;#39;, &amp;#39;empty_username&amp;#39;) ) ) {
    			unset( $user-&amp;gt;errors[ $key ] );
    			$user-&amp;gt;errors[ &amp;#39;custom_&amp;#39;.$key ] = $error;
    		}
    	}
    }

    return $user;
}
add_filter(&amp;#39;authenticate&amp;#39;,&amp;#39;custom_authenticate&amp;#39;, 31, 3);
&lt;/pre&gt;
&lt;h2&gt;Other ways?&lt;/h2&gt;
&lt;p&gt;I know of one alternative to the above code: Since &lt;em&gt;wp_authenticate&lt;/em&gt; is a pluggable function, you could simply overwrite it. But you can only do this with a plugin, so you have to add a plugin to your site and activate it, which I think is a bit more hassle. &lt;/p&gt;
&lt;p&gt;Is there another way you know of? Please let me know in the comments.&lt;/p&gt;
	</description></item><item><title>Problems we don&apos;t have?</title><link>https://www.danielauener.com/problems-dont/</link><guid isPermaLink="false">http://www.danielauener.com/?p=630</guid><pubDate>Tue, 15 Oct 2013 19:35:34 GMT</pubDate><description>
		&lt;p&gt;Inspiring read on how much we should struggle to support outdated browsers. Favorite quote: “Problem 3: IE6 and 7 … what &lt;strong&gt;are&lt;/strong&gt; you doing?”&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.rachelandrew.co.uk/archives/2012/03/21/stop-solving-problems-you-dont-yet-have/&quot; title=&quot;stop solving problems you dont yet have&quot; target=&quot;_blank&quot;&gt;» Stop solving problems you don’t yet have&lt;/a&gt;&lt;/p&gt;
	</description></item><item><title>New blog layout</title><link>https://www.danielauener.com/new-blog-layout/</link><guid isPermaLink="false">http://www.danielauener.com/?p=617</guid><pubDate>Sun, 13 Oct 2013 14:15:11 GMT</pubDate><description>
		&lt;p&gt;My blog just got back from a trip in a flying DeLorean, and finally landed in 2013 – @pixelcrook, you are my hero. http://www.danielauener.com &lt;/p&gt;
	</description></item><item><title>WordPress pagination: Simple and reusable without a plugin</title><link>https://www.danielauener.com/simple-reuseable-wordpress-pagination-without-a-plugin/</link><guid isPermaLink="false">http://www.danielauener.com/?p=447</guid><pubDate>Wed, 22 May 2013 19:34:13 GMT</pubDate><description>
		&lt;p&gt;Pagination might be one of the most common UI patterns on the web. The concept of showing just a limited number of articles, posts or whatever and making the reader click through the rest, comes in quite a few variations. Google’s search results come to mind or more advanced infinite scroll solutions. Naturally, WordPress implements this concept and I have to admit that, for some time, I found it quite difficult to use, especially with custom queries.&lt;/p&gt;
&lt;p&gt;As is so often the case, the difficulties weren’t caused by the API-implementation or documentation, but by my not reading it. So, after realizing that, there was nothing left to do but work it out and here is the solution I use in my starter-theme. It contains a file named &lt;code&gt;pagination.php&lt;/code&gt;, with the following content.&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
&amp;lt;?php 
     
     global $paginated_query;
     global $wp_query;

     if ( !$paginated_query ):
     	$paginated_query = $wp_query;
     endif;

     if ( $paginated_query-&amp;gt;max_num_pages &amp;gt; 1 ) : ?&amp;gt;
          &amp;lt;div class=&amp;quot;pagination&amp;quot;&amp;gt;
              if ( !$current_page = get_query_var(&amp;#39;paged&amp;#39;) ) :
                  $current_page = 1;
              endif;

              echo paginate_links(array(
                  &amp;#39;base&amp;#39; =&amp;gt; get_pagenum_link(1) . &amp;#39;%_%&amp;#39;,
                  &amp;#39;current&amp;#39; =&amp;gt; $current_page,
                  &amp;#39;total&amp;#39; =&amp;gt; $total    
              )); ?&amp;gt;
          &amp;lt;/div&amp;gt;&amp;lt;?php
     endif;

?&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The great thing is that the &lt;code&gt;paginate_links&lt;/code&gt; function does all the page-logic for you, if you just provide it with a current page number and the total number of pages. So if you want to paginate your main loop, all you have to do is to include this file. Since we don’t define a &lt;code&gt;$paginated_query&lt;/code&gt;, the parameters will be taken from the global &lt;code&gt;$wp_query&lt;/code&gt;. &lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
&amp;lt;?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?&amp;gt;
...
&amp;lt;?php endwhile; endif; ?&amp;gt;
&amp;lt;?php get_template_part(&amp;quot;pagination); ?&amp;gt;
&lt;/pre&gt;
&lt;p&gt;But it’s quite easy, even with a custom query. Here you have to define the &lt;code&gt;$paginated_query&lt;/code&gt; variable, before including &lt;code&gt;pagination.php&lt;/code&gt; and giving the paged param to the WP_Query-object, so the requested page can be queried. &lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
&amp;lt;?php 
    $custom_query = new WP_Query( array(
        &amp;#39;post_type&amp;#39; =&amp;gt; &amp;#39;page&amp;#39;,
        &amp;#39;posts_per_page&amp;#39; =&amp;gt; 3,
        &amp;#39;paged&amp;#39; =&amp;gt; ( !$current_page = get_query_var(&amp;#39;paged&amp;#39;) ) ? 1 : $current_page
    ) );
?&amp;gt;
&amp;lt;?php if ( $custom_query-&amp;gt;have_posts() ) : while ( $custom_query-&amp;gt;have_posts() ) : $custom_query-&amp;gt;the_post(); ?&amp;gt;
...
&amp;lt;?php endwhile; endif; ?&amp;gt;
&amp;lt;?php 
    $paginated_query = $custom_query;
    get_template_part(&amp;quot;pagination); 
?&amp;gt;
&lt;/pre&gt;
&lt;p&gt;That’s how I do it, but I’m always interested in other solutions. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Please comment if you have a better or alternative solution&lt;/strong&gt;!&lt;/p&gt;
	</description></item><item><title>Related post thumbnails in Simply Related Posts widget</title><link>https://www.danielauener.com/simply-related-post-thumbnails/</link><guid isPermaLink="false">http://www.danielauener.com/?p=444</guid><pubDate>Fri, 03 May 2013 19:11:40 GMT</pubDate><description>
		&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
	function my_related_posts_thumbnail( $title, $post, $instance ) {
		if ( has_post_thumbnail( $post-&amp;gt;ID ) ) {
			$title = get_the_post_thumbnail($post-&amp;gt;ID).$title;
		}
		return $title;
	}
	add_filter( &amp;#39;simply_related_posts_title&amp;#39;, &amp;#39;my_related_posts_thumbnail&amp;#39;, 10, 3 );
&lt;/pre&gt;
&lt;h2&gt;The snippet’s story&lt;/h2&gt;
&lt;p&gt;If you are using my &lt;a href=&quot;https://www.danielauener.com/simply-related-posts-1-2-plugin-update/&quot; title=&quot;Plugin update: Simply Related Posts 1.2&quot;&gt;Simply Related Posts&lt;/a&gt; plugin, you might want to have related post thumbnails. The code above is simply adding the post-thumbnail before the related post titles, if it exists. It implements the &lt;code&gt;simply_related_posts_title&lt;/code&gt; filter, to add thumbnails to the printed title. Of course, you can add not only thumbnails, but any other kind of information to the title, by using that filter.&lt;/p&gt;
&lt;p&gt;Works with Simply Related Posts version 1.2 and later. &lt;/p&gt;
	</description></item><item><title>Extend WP_Query with custom parameters</title><link>https://www.danielauener.com/extend-wp_query-with-custom-parameters/</link><guid isPermaLink="false">http://www.danielauener.com/?p=442</guid><pubDate>Thu, 02 May 2013 20:44:55 GMT</pubDate><description>
		&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
function check_custom_query_param( $query ) {
    if ( isset($query-&amp;gt;query_vars[&amp;#39;custom_param&amp;#39;]) &amp;amp;&amp;amp; $query-&amp;gt;query_vars[&amp;#39;custom_param&amp;#39;]) {
        $query-&amp;gt;custom_param = true;
    }
}
add_action( &amp;#39;pre_get_posts&amp;#39;, &amp;#39;check_custom_query_param&amp;#39; );


function change_where_query( $where, &amp;amp;$wp_query ) {
    global $wpdb;	
    if ( property_exists ( $wp_query , &amp;#39;custom_query&amp;#39; ) &amp;amp;&amp;amp; $wp_query-&amp;gt;custom_query ) {
    	// change the where query
    }
    return $where;
}
add_filter(&amp;#39;posts_where&amp;#39;, &amp;#39;change_where_query&amp;#39;, 10, 2);
&lt;/pre&gt;
&lt;h2&gt;The snippet’s story&lt;/h2&gt;
&lt;p&gt;A few weeks ago I wanted to pass a custom parameter to the WP_Query object to change the where-query if the param was true. The problem was that to extend WP_Query with a parameter, you have to circumvent the filtering of the query options. I solved this by hooking into the &lt;code&gt;pre_get_posts&lt;/code&gt; action. There the custom parameter is still available and we can easily add it to the filtered query object.&lt;/p&gt;
	</description></item><item><title>Simply Related Posts 1.2: plugin update</title><link>https://www.danielauener.com/simply-related-posts-1-2-plugin-update/</link><guid isPermaLink="false">http://www.danielauener.com/?p=440</guid><pubDate>Thu, 02 May 2013 20:17:24 GMT</pubDate><description>
		&lt;p&gt;&lt;strong&gt;Update: Simply Related Posts 1.3 comes with a Serbian translation! Thanks to Borisa Djuraskovic from &lt;a href=&quot;http://www.webhostinghub.com/&quot; rel=&quot;nofollow&quot;&gt;http://www.webhostinghub.com&lt;/a&gt;!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I’ve just released Simply Related Posts 1.2, a new version of my &lt;a title=&quot;Simply Related Posts, a WordPress Widget Plugin to relate Posts by taxonomy the easy way&quot; href=&quot;https://www.danielauener.com/simply-related-posts/&quot;&gt;Simply Related Posts plugin&lt;/a&gt;. Now it supports pages, attachment-pages and custom post-types, which makes it a lot more flexible. Additionally I’ve added a filter to the related post-title, so you can &lt;a title=&quot;Related post thumbnails in Simply Related Posts widget&quot; href=&quot;https://www.danielauener.com/simply-related-post-thumbnails/&quot;&gt;add thumbnails&lt;/a&gt;, excerpts or anything else you can think of.&lt;/p&gt;
&lt;p&gt;Test Simply Related Posts 1.2 now, &lt;a title=&quot;Simply related posts plugin in the WordPress plugin directory&quot; href=&quot;http://wordpress.org/plugins/simply-related-posts/&quot; target=&quot;_blank&quot;&gt;download it from the plugin directory&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As always, post your questions, feedback etc. here below in the comments section!&lt;/p&gt;
	</description></item><item><title>WordPress as a CMS - Ways of organizing your content to achieve multi-level navigation for static-page websites.</title><link>https://www.danielauener.com/wordpress-as-a-cms-ways-of-organizing-your-content-to-achieve-multi-level-navigation-for-static-page-websites/</link><guid isPermaLink="false">http://www.danielauener.com/?p=364</guid><pubDate>Sun, 07 Apr 2013 14:10:19 GMT</pubDate><description>
		&lt;p&gt;If you are using WordPress as a blog, organizing your content is quite straightforward. You categorize and tag your posts, create nav-menus, to link the most important categories, use archive or calendar widgets and order your posts by publishing date (which is the default). Using WordPress as a CMS for a common website and building the navigation, often requires a bit more structural planning. The thing is that there are multiple strategies, which might be right or wrong depending on your demands. In this article I want to present a list of the approaches I use.&lt;/p&gt;
&lt;h2&gt;Inbuilt and custom post types&lt;/h2&gt;
&lt;p&gt;But first some words about the standard post types built into WordPress. When I build a website with WordPress, I naturally use pages for all static content, but in the beginning I even tried to use the standard &lt;em&gt;posts&lt;/em&gt; post type for all continuously updated content like news sections, upcoming events and so on.&lt;/p&gt;
&lt;p&gt;However, after some time I realized that posts really only should be used for blog content and nothing else. All the other stuff should be implemented as a custom post type. There are two simple reasons: Your client might decide to integrate a blog with the website in the future and by that time the posts section is bloated with other content. Secondly, my experience is that custom post types for events or newsfeeds are just more usable and purposeful than the standard posts, especially when there is some extra functionality needed, like start/end-date for an event.&lt;/p&gt;
&lt;p&gt;So, when you are implementing one of the following strategies, make sure that you choose your post types well.&lt;/p&gt;
&lt;h2&gt;One-level menu&lt;/h2&gt;
&lt;p&gt;The easiest variant of content structure is just a bunch of pages without any hierarchy. Typically you would create a menu, under &lt;em&gt;Appearance-&amp;gt;Menus&lt;/em&gt; in the admin interface, and add all relevant pages to it. Here is an example of how to embed a simple menu into a theme:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
wp_nav_menu( array( &amp;#39;theme_location&amp;#39; =&amp;gt; &amp;#39;main-menu&amp;#39; ) );
&lt;/pre&gt;
&lt;p&gt;For many small businesses this content structure is appropriate. Often it is quite easy to determine the few sections of content the website’s user will be interested in, e.g. “General information”, “References” and “Contact information”. You will both get an easily navigated site and a very simple backend.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When not to use it&lt;/strong&gt;: There aren’t any drawbacks. If the content structure stays as simple as described above, there will be no problems.&lt;/p&gt;
&lt;h2&gt;Multi-level menu&lt;/h2&gt;
&lt;p&gt;Now, not every website works with a simple structure and not every client is satisfied with only telling the stuff visitors want to know. Sometimes clients want their websites to present the whole company structure and in these cases you need a hierarchical navigation, perhaps with a dropdown menu.&lt;/p&gt;
&lt;p&gt;The good thing is that there is support for multi-level menus in WordPress and implementing them, can be quite simple. In the back-end it is as easy as doing some drag&amp;amp;drop actions to create a hierarchical menu of your pages and the simplest way to implement it in your theme is just the same as with one-level menus. You might add a &lt;em&gt;depth&lt;/em&gt; parameter, to limit the number of levels in your navigation.&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
wp_nav_menu( array(
    &amp;#39;theme_location&amp;#39; =&amp;gt; &amp;#39;main-menu&amp;#39;,
    &amp;#39;depth&amp;#39; =&amp;gt; 2
) );
&lt;/pre&gt;
&lt;p&gt;This would print a nested list representing your hierarchical menu and with some &lt;a href=&quot;http://alistapart.com/article/dropdowns&quot;&gt;suckerfish magic&lt;/a&gt; you make it a dropdown in minutes. You can even build a nested navigation where every page contains a submenu with pages on the same level, by printing the whole menu on every page and hiding the irrelevant portions of the menu with CSS.&lt;/p&gt;
&lt;p&gt;But there are drawbacks. The big problem I see with multi-level menus is, that your menu doesn’t organize your content. Even if you have built a well structured menu, your pages section in the admin-interface isn’t organized at all, it’s just a very long list of pages. I see this as a real usability issue for our clients and there are only two (suboptimal) solutions I can see. The first is telling your client to use the search field, because the structure shown on the website is not represented in the pages section. The other is to hierarchically organize your pages the same way you did it with the menu and mirroring all changes in future, which could be a big amount of extra work.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When not to use it:&lt;/strong&gt; If there are many pages and you don’t want your client to do the extra work of organizing both menus and pages. Or if you want to implement submenus/breadcrumbs without printing the irrelevant parts and hiding them with CSS.&lt;/p&gt;
&lt;h2&gt;Multi-level pages&lt;/h2&gt;
&lt;p&gt;If multi-level menus don’t work for you, you could abandon menus and only organize by page hierarchy. Compared to the really easy way you drag and drop menus, it is a somewhat clumsy method, to enter the editor of every page and choose a parent, but it works. Here is how to create a menu just from the page structure:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
&amp;lt;ul&amp;gt;
    &amp;lt;?php
        wp_list_pages( array(
            &amp;#39;title_li&amp;#39; =&amp;gt; null
        ) );
    ?&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The advantage over menus is that you directly can access the page’s parents and children and thus know on which menu level you are operating with your page template. This makes it possible to build all kinds of custom navigation elements like submenus or breadcrumbs. Here is the code to print a submenu with links to pages on the same level as the current page.&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
&amp;lt;ul&amp;gt;
    &amp;lt;?php
        wp_list_pages( array(
            &amp;#39;title_li&amp;#39; =&amp;gt; null,
            &amp;#39;child_of&amp;#39; =&amp;gt; get_post( get_the_ID() )-&amp;gt;post_parent
        ) );
    ?&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/pre&gt;
&lt;p&gt;One thing to remember is that you can’t add one page in multiple places like you can with menus, because you are generating the menu directly from the page hierarchy. In case you need, say a contact page, in two places on the menu you have to create two contact pages.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When not to use it:&lt;/strong&gt; If your client doesn’t feel comfortable with the way you structure pages or you want to link pages in multiple places in your menu this approach isn’t the best.&lt;/p&gt;
&lt;h2&gt;Integrate categories with pages and menus&lt;/h2&gt;
&lt;p&gt;You can even use categories to organize your pages. You could use the built in categories, but I think it’s better to create your own taxonomy, mostly because of the reasons discussed above, why you shouldn’t use posts for something else than blogging. Here is some code to add a custom taxonomy to categorize pages, to include in the &lt;em&gt;functions.php&lt;/em&gt;:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
add_action( &amp;#39;init&amp;#39;, &amp;#39;add_page_categories&amp;#39; );

function add_page_categories() {
   register_taxonomy(
      &amp;#39;page-category&amp;#39;,
      &amp;#39;page&amp;#39;,
      array(
         &amp;#39;label&amp;#39; =&amp;gt; &amp;#39;Page Category&amp;#39;,
         &amp;#39;rewrite&amp;#39; =&amp;gt; array( &amp;#39;slug&amp;#39; =&amp;gt; &amp;#39;page_cat&amp;#39; ),
         &amp;#39;hierarchical&amp;#39; =&amp;gt; true
      )
   );
}
&lt;/pre&gt;
&lt;p&gt;Now you can select the categories for every page and add them to a (multi-level) menu. The advantage over simple multi-level menus is that the categories add some structure to the pages section, even if you don’t get the whole hierarchy. In my opinion the checkbox to select the category is slightly more usable than the child/parent selection lists, which are building the page hierarchy.&lt;/p&gt;
&lt;p&gt;And there is another thing about this way of building a menu: you can list multiple pages under one menu-item, which is kind of sabotaging the static content thought. However, it can make sense in some situations, for example a contact page which is intended to list all employees and you add one page for everyone instead of listing them in one page’s content block.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When not to use it&lt;/strong&gt;: If your client isn’t familiar with the WordPress UI it might be one more hurdle to learn not only page editing and building menus, but also using the category checkboxes.&lt;/p&gt;
&lt;h2&gt;One-level menu plus page-hierarchy&lt;/h2&gt;
&lt;p&gt;This last approach to multi-level navigation uses both menus and page hierarchy. The idea is to only use a menu for the first navigation level, so you can easily rearrange and fully control your main menu. Then, all the pages linked in your main menu are used as parents for subpages, so the multiple levels get implemented by the page hierarchy. The next two pieces of code show how to print the main navigation with the &lt;em&gt;wp_nav_menu&lt;/em&gt; function and how to output a submenu by using &lt;em&gt;wp_list_pages&lt;/em&gt;.&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
&amp;lt;!-- main-menu, only add parents --&amp;gt;
&amp;lt;?php
    wp_nav_menu( array(
        &amp;#39;theme_location&amp;#39; =&amp;gt; &amp;#39;main-menu&amp;#39;,
        &amp;#39;depth&amp;#39; =&amp;gt; 1
    ) );
?&amp;gt;
&amp;lt;!-- end main-menu --&amp;gt;
...
&amp;lt;!-- sub-menu --&amp;gt;
&amp;lt;ul&amp;gt;
    &amp;lt;?php
        wp_list_pages( array(
            &amp;#39;title_li&amp;#39; =&amp;gt; null,
            &amp;#39;child_of&amp;#39; =&amp;gt; get_post( get_the_ID() )-&amp;gt;post_parent
        ) );
    ?&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;!-- end sub-menu --&amp;gt;
&lt;/pre&gt;
&lt;p&gt;I use this solution a lot because it solves a whole bunch of problems I discussed earlier in this article:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;you get the flexibility of menus for your main navigation&lt;/li&gt;
&lt;li&gt;you get the structural advantages of hierarchical pages&lt;/li&gt;
&lt;li&gt;you don’t have to build the hierarchy two times&lt;/li&gt;
&lt;li&gt;you can present a clean and logical structure to your clients&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;When not to use it&lt;/strong&gt;: If you want to build a simple dropdown-menu and can be sure that there won’t be any more complicated navigation requirements, multi-level menus would be the better choice.&lt;/p&gt;
&lt;h2&gt;Bottom line&lt;/h2&gt;
&lt;p&gt;WordPress as a CMS has quite a few possibilities to organize your content and build a navigation. Of all approaches I’ve shown I think I would prefer the last one, main menu plus page hierarchy, in most cases where a multi-level navigation is needed. It uses both the strengths of menus and page hierarchy, is easy to implement with the WordPress API and extendable if new navigation functionality is needed. From a usability point of view it makes use of the WordPress UI in the most common and intuitive way.&lt;/p&gt;
	</description></item><item><title>Provide WordPress theme color schemes as a feature of your theme</title><link>https://www.danielauener.com/provide-wordpress-theme-color-schemes-as-a-feature-to-your-theme/</link><guid isPermaLink="false">http://www.danielauener.com/?p=428</guid><pubDate>Fri, 05 Apr 2013 20:15:12 GMT</pubDate><description>
		&lt;p&gt;WordPress themes are amazing and since WordPress 3.4 there is an inbuilt customizer to make individual changes as easy as possible. One commonly used feature of the customizer is changing the background color or other basic colors of the theme. That is really great, but I like to think that there are a lot of bloggers like me out there, without any talent regarding colors or design. For all of us, manual color customization tends to produce ugly blogs. So I think it would be great to have preconfigured WordPress theme color schemes. &lt;/p&gt;
&lt;p&gt;My “Color Scheme every Theme” plugin is built to help us to customize the colors of our blogs. It makes it easy to extract the colors of every theme (if it is built with css) and to change them from the admin interface. So, if you want to ask one of your designer friends for help, he or she doesn’t have to go through hundreds of lines of css, it’s enough to change the extracted color scheme via the admin interface, no coding involved.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Embedding preconfigured color schemes in the themes you are selling&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I think that’s a really nice feature, but I think even more important is the possibility to embed as many preconfigured color schemes as you want in a theme. So, if you are a theme developer, generate some perfectly matching color schemes before you upload your theme to a marketplace of your choice, make a light and dark variant, a greyscaled and colored one or a variant for all four seasons. Then, embed those in your theme and make it even more valuable for your customers.&lt;/p&gt;
	</description></item><item><title>Color Scheme every Theme 2.0: Plugin Update</title><link>https://www.danielauener.com/color-scheme-every-theme-2-0-plugin-update/</link><guid isPermaLink="false">http://www.danielauener.com/?p=407</guid><pubDate>Sun, 24 Mar 2013 10:18:17 GMT</pubDate><description>
		&lt;p&gt;Color Scheme every Theme 2.0 (&lt;a title=&quot;New WordPress Plugin: Color Scheme every Theme&quot; href=&quot;https://www.danielauener.com/color-scheme-every-theme/&quot; target=&quot;_blank&quot;&gt;read about v1.0 here&lt;/a&gt;) makes it even easier to create color schemes for WordPress themes.&lt;/p&gt;
&lt;p&gt;&lt;a title=&quot;Version 2.0 of color scheme every theme plugin&quot; href=&quot;http://wordpress.org/extend/plugins/color-scheme-every-theme/&quot;&gt;Get version 2.0 on wordpress.org&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;After the release of version 1.0, some bug-fixing and the release of two minor versions I had got so much feedback that I thought it was time to implement the two feature requests most users suggested:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Editing color schemes directly in the admin interface, instead of having to add code in the &lt;em&gt;functions.php&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;An option to make the css for all schemes available in the theme, to make it possible to change the scheme not only via the admin interface, but even on the front-end.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This resulted in a completely new options page, see a screenshot below:&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://www.danielauener.com/assets/media/original/3580d8351a4443c4f106.png&quot;&gt;&lt;img class=&quot; wp-image-408 aligncenter&quot; alt=&quot;screenshot-2&quot; src=&quot;https://www.danielauener.com/assets/media/original/3580d8351a4443c4f106.png&quot; width=&quot;525&quot; height=&quot;246&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/3580d8351a4443c4f106.png 1094w, https://www.danielauener.com/assets/media/original/de4d0ddb14fe4c3c5f45.png 300w, https://www.danielauener.com/assets/media/original/9e5a962b0f032c7f1daa.png 1024w&quot; sizes=&quot;(max-width: 525px) 100vw, 525px&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here you have the option to edit the scheme directly in the admin interface. Just click on a color and change it in the &lt;em&gt;Change color &lt;/em&gt;input field, hit enter, pick the next color you want to change. Don’t forget to save the schemes when you are done.&lt;/p&gt;
&lt;p&gt;If you want to use the &lt;em&gt;Dynamic theme colors&lt;/em&gt; option and used version 1.0 of the plugin, you have to regenerate the schemes.&lt;/p&gt;
&lt;p&gt;There is still the possibility to permanently add a scheme to your theme by copying it to the &lt;em&gt;functions.php&lt;/em&gt; of that theme. If you want to do that, just create the new theme via the admin interface, save and click on the &lt;em&gt;&amp;lt; embed in theme &amp;gt; &lt;/em&gt;link, which opens a textarea with the code you have to add in it.&lt;/p&gt;
	</description></item><item><title>WordPress color scheme plugin: Color Scheme every Theme</title><link>https://www.danielauener.com/color-scheme-every-theme/</link><guid isPermaLink="false">http://www.danielauener.com/?p=386</guid><pubDate>Mon, 25 Feb 2013 22:10:15 GMT</pubDate><description>
		&lt;p&gt;&lt;strong&gt;Download on wordpress.org: &lt;a title=&quot;Download: Color Scheme every Theme plugin&quot; href=&quot;http://wordpress.org/extend/plugins/color-scheme-every-theme/&quot; target=&quot;_blank&quot;&gt;Color Scheme every Theme&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;WordPress 3.4 gave us a tool for theme customization, and I really like the idea. Changing the background color or adding a header image makes even the most downloaded theme on the internet unique. So I had this idea of not only changing the background color, but changing the whole color scheme of a theme and thus building for example a green, red and blue variant of a theme or a dark and a light version. A WordPress color scheme plugin, that would both be great for users, to adjust their downloaded themes, and for theme developers, to provide their themes with multiple color schemes.&lt;/p&gt;
&lt;h2&gt;Three simple steps to make your own color scheme&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Generating the css&lt;/em&gt;&lt;/strong&gt; – The first step, after installing and activating the plugin, is scanning your current theme for color-relevant css. Go to the plugin’s settings page under &lt;em&gt;Settings -&amp;gt; Color scheme every theme&lt;/em&gt; and click the generate button. This will scan all the css files in your current theme for colors, generate code to overwrite the default colors and provide you with a color scheme template to add to your &lt;em&gt;functions.php&lt;/em&gt;. After clicking the generate button you will see two textfields. The first with the color scheme template …
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
if ( function_exists( &amp;#39;cset_add_color_scheme&amp;#39; ) ) {
	cset_add_color_scheme( &amp;#39;scheme-name&amp;#39;, array(
		&amp;#39;$color-1&amp;#39; =&amp;amp;gt; &amp;#39;#111111&amp;#39;,
		&amp;#39;$color-2&amp;#39; =&amp;amp;gt; &amp;#39;#111111&amp;#39;,
		&amp;#39;$color-3&amp;#39; =&amp;amp;gt; &amp;#39;#111111&amp;#39;,
		&amp;#39;$color-4&amp;#39; =&amp;amp;gt; &amp;#39;#111111&amp;#39;,
		&amp;#39;$color-5&amp;#39; =&amp;amp;gt; &amp;#39;#111111&amp;#39;,
		&amp;#39;$color-6&amp;#39; =&amp;amp;gt; &amp;#39;#111111&amp;#39;,
	) );
}
&lt;/pre&gt;
&lt;p&gt;… and the second with the default colors, found in your theme.&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
/**
 * Default colors
 *
 * $color-1: #efefef;
 * $color-2: rgba(0,0,0,0.5);
 * $color-3: rgba(0,0,0,0);
 * $color-4: #fff;
 * $color-5: #000;
 * $color-6: #222;
 */
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Adding a scheme to the functions.php&lt;/em&gt;&lt;/strong&gt; – Now you only have to add one or more color schemes to your themes &lt;em&gt;functions.php&lt;/em&gt;. Just copy and paste the first code-snippet and change the colors as you like. Allowed are all valid css color definitions, including rgb/rgba and hsl/hsla.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;em&gt;Choosing a scheme&lt;/em&gt;&lt;/strong&gt; – It’s almost done, the last step is going to the customize section of your theme and choosing the color scheme. Click in the admin menu on &lt;em&gt;Appearance -&amp;gt; Themes&lt;/em&gt; and then on the &lt;em&gt;Customize&lt;/em&gt; link of the current theme.&lt;img class=&quot;alignnone size-full wp-image-387&quot; alt=&quot;screenshot-1&quot; src=&quot;https://www.danielauener.com/assets/media/original/138461c66898a5f55d5a.png&quot; width=&quot;392&quot; height=&quot;462&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/138461c66898a5f55d5a.png 392w, https://www.danielauener.com/assets/media/original/fe581e1fa9dc0e89ebb3.png 254w&quot; sizes=&quot;(max-width: 392px) 100vw, 392px&quot;&gt;
&lt;p&gt;Now you should see the schemes you created in the &lt;em&gt;Color Schemes section&lt;/em&gt;, choose one and see a live preview to the right and save if you want to publish the new scheme.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Next development steps&lt;/h2&gt;
&lt;p&gt;This plugin is really not much more than a working prototype. I have some ideas, to make it really great.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Making the generator work for other themes than the currently activated (even parent/child themes).&lt;/li&gt;
&lt;li&gt;Saving color schemes in the options, so there are no changes to the &lt;em&gt;functions.php&lt;/em&gt; needed.&lt;/li&gt;
&lt;li&gt;Generating random color schemes or automatically making the default scheme ‘warmer’ or ‘colder’.&lt;/li&gt;
&lt;li&gt;Testing, bugfixing and discussing&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Troubleshooting&lt;/h2&gt;
&lt;p&gt;If there is something not working, you are welcome to contact me via the comment section of this article or twitter. But check some things first, to make it easier for me to locate the problem:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Check if your WordPress version is 3.4 or higher and if your PHP version is 4.3.0 or higher.&lt;/li&gt;
&lt;li&gt;To overwrite the color scheme of your theme, the plugin does save a file in the &lt;code&gt;wp-content/uploads/&lt;/code&gt; directory. So this directory must have write permissions set.&lt;/li&gt;
&lt;li&gt;Set the &lt;code&gt;WP_DEBUG&lt;/code&gt; constant in your wp-config.php file to true and see if there are any errors shown when you use the plugin.&lt;/li&gt;
&lt;li&gt;Try to deactivate all other plugins. If the problem disappears I have to know which plugins you use, to help.&lt;/li&gt;
&lt;li&gt;Give me as much information about your system as possible, when you contact me.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;What do you think?&lt;/h2&gt;
&lt;p&gt;Of course I want to hear what your thoughts and experiences are. Is this plugin usable for you, would you like to see some features it doesn’t have at the moment or do you have some color schemes, you want to share? Please comment or contact me on twitter and let me know what you think!&lt;/p&gt;
	</description></item><item><title>WordPress custom image size crop: How to fix it</title><link>https://www.danielauener.com/wordpress-custom-image-size-crop-how-to-fix/</link><guid isPermaLink="false">http://www.danielauener.com/?p=366</guid><pubDate>Wed, 30 Jan 2013 19:40:37 GMT</pubDate><description>
		&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
if (function_exists(&amp;#39;add_image_size&amp;#39;)) {
   add_image_size( &amp;#39;dummy-1&amp;#39;, 940, 450, true );
   add_image_size( &amp;#39;dummy-2&amp;#39;, 480, 0 );
}

global $_wp_additional_image_sizes;
foreach ( $_wp_additional_image_sizes as $name =&amp;gt; $image_size ){
    update_option( $name.&amp;quot;_size_w&amp;quot;, $image_size[&amp;#39;width&amp;#39;] );
    update_option( $name.&amp;quot;_size_h&amp;quot;, $image_size[&amp;#39;height&amp;#39;] );
    update_option( $name.&amp;quot;_crop&amp;quot;, $image_size[&amp;#39;crop&amp;#39;] );
}

add_filter( &amp;#39;intermediate_image_sizes&amp;#39;, &amp;#39;regenerate_custom_image_sizes&amp;#39; );
function regenerate_custom_image_sizes( $sizes ){
    global $_wp_additional_image_sizes;
    foreach ( $_wp_additional_image_sizes as $name =&amp;gt; $size ){
        $sizes[] = $name;
    }
    return $sizes;
}
&lt;/pre&gt;
&lt;h2&gt;WordPress custom image size crop: The snippet’s story&lt;/h2&gt;
&lt;p&gt;If you are using custom image sizes in your WordPress theme you likely know the problem. Cropping, rotating or flipping an image via the WordPress image editor works only on the original. After editing, the image is not available in your custom sizes anymore, all you get in your theme is the edited version in original size.&lt;/p&gt;
&lt;p&gt;I thought that there has to be a simple solution to this problem, because it is pretty basic after all. But a quick Google search only turned up code that didn’t work. Finally I found some code on &lt;a title=&quot;Pastebin&quot; href=&quot;http://pastebin.com/yp9378J4&quot; target=&quot;_blank&quot;&gt;pastebin&lt;/a&gt; that pointed me in the right direction.&lt;/p&gt;
&lt;p&gt;Copy and paste the above code into your functions.php, adjust the image sizes and even your cropped images should be available in your custom sizes.&lt;/p&gt;
	</description></item><item><title>HTML5 wp_nav_menu without using a list in WordPress</title><link>https://www.danielauener.com/html5-wp_nav_menu/</link><guid isPermaLink="false">http://www.danielauener.com/?p=369</guid><pubDate>Wed, 30 Jan 2013 12:14:17 GMT</pubDate><description>
		&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
$menuParameters = array(
    &amp;#39;echo&amp;#39; =&amp;gt; false,
    &amp;#39;items_wrap&amp;#39; =&amp;gt; &amp;#39;&amp;lt;nav&amp;gt;%3$s&amp;lt;/nav&amp;gt;&amp;#39;,
);
echo strip_tags(wp_nav_menu( $menuParameters ), &amp;#39;&amp;lt;a&amp;gt;&amp;lt;nav&amp;gt;&amp;#39; );&lt;/pre&gt;
&lt;p&gt;Result:&lt;/p&gt;
&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;
&amp;lt;nav&amp;gt;
    &amp;lt;a href=&amp;quot;...&amp;quot;&amp;gt;...&amp;lt;/a&amp;gt;
    &amp;lt;a href=&amp;quot;...&amp;quot;&amp;gt;...&amp;lt;/a&amp;gt;
    &amp;lt;a href=&amp;quot;...&amp;quot;&amp;gt;...&amp;lt;/a&amp;gt;
&amp;lt;/nav&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Source: &lt;a href=&quot;http://css-tricks.com/snippets/wordpress/remove-li-elements-from-output-of-wp_nav_menu/&quot; target=&quot;_blank&quot; title=&quot;Remove LI Elements From Output of wp_nav_menu&quot;&gt;Remove LI Elements From Output of wp_nav_menu&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;HTML5 wp_nav_menu: The snippet’s story&lt;/h2&gt;
&lt;p&gt;This is how you build HTML5 navigation without lists in WordPress. I slightly changed the code I found on CSS-Tricks. I had to post this after today’s reading of &lt;a title=&quot;Navigation in Lists: To Be or Not To Be &quot; href=&quot;http://css-tricks.com/navigation-in-lists-to-be-or-not-to-be/&quot; target=&quot;_blank&quot;&gt;“Navigation in Lists: To Be or Not To Be”&lt;/a&gt; by Chris Coyier. &lt;/p&gt;
	</description></item><item><title>WordPress plugin best practices, my three golden Rules</title><link>https://www.danielauener.com/wordpress-plugin-best-practices-my-three-golden-rules/</link><guid isPermaLink="false">http://www.danielauener.com/?p=344</guid><pubDate>Fri, 25 Jan 2013 09:19:33 GMT</pubDate><description>
		&lt;p style=&quot;text-align: center;&quot;&gt;&lt;strong&gt;“A man must have a code” –&lt;/strong&gt;&lt;em&gt; Bunk in The Wire&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I recently uploaded my first plugin to the WordPress Plugin Directory, wrote some plugins at work and most importantly used a lot of the plugins out there. So I thought the time has come, to step back and think of what I’ve learned about plugin development and I came up with my personal WordPress plugin best practices, my three golden rules:&lt;em&gt;&lt;br&gt;
&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;WordPress plugin best practices no. 1: Do not try to improve the UI&lt;/h2&gt;
&lt;p&gt;The first rule is simple, don’t touch the standard WordPress UI. There might be ways of doing things better, there might be nicer looking checkboxes and coloring up things would surely give the admin interface a friendlier touch. But, there are better ways to &lt;a title=&quot;Suggest new WordPress features&quot; href=&quot;http://wordpress.org/extend/ideas/&quot; target=&quot;_blank&quot;&gt;communicate your ideas&lt;/a&gt; than just making up new UI-styles in your plugin. I think &lt;strong&gt;one reason why WordPress is as big as it is, is consistent UI-design&lt;/strong&gt;, don’t mess with it.&lt;/p&gt;
&lt;h2&gt;WordPress plugin best practices no. 2: Leave theme developers in control&lt;/h2&gt;
&lt;p&gt;Whatever your plugin is doing, it is probably affecting the current theme in some way. And that makes you the theme developer’s friend – or most hated enemy. &lt;strong&gt;Theme developers want to control all of their theme&lt;/strong&gt;, HTML output, css-classes, javascripts, language and so on. They don’t want a plugin to inject uncontrollable bits of code into their theme.&lt;/p&gt;
&lt;p&gt;So treat them as grown-ups and let them be responsible for their theme. Give them hooks, filters and functions to control the output, admin options to let them deactivate automatically enqueued scripts and styles, prepare for localization and anything else you can think of.&lt;/p&gt;
&lt;h2&gt;WordPress plugin best practices no. 3: A plugin does what it has to do, nothing more&lt;/h2&gt;
&lt;p&gt;Keep your plugin as simple as possible, do not bloat it with functionality just because you can. Every plugin adds complexity to the admin interface and every plugin has to get along with other plugins. Therefore &lt;strong&gt;“as simple as possible” even means fewer bugs, fewer confused users and less support&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Ask yourself questions like these: Does my nice little widget really need your own stats section or global settings? Are custom database tables really necessary? Am I using the plugin API as much as possible? Is there really no way around these custom database queries? And so on …&lt;/p&gt;
&lt;p&gt;Keep these WordPress plugin best practices in mind when writing your next plugin and I’m sure it will be a success.&lt;/p&gt;
	</description></item><item><title>Simply Related Posts, a WordPress Widget Plugin to relate Posts by taxonomy the easy way</title><link>https://www.danielauener.com/simply-related-posts/</link><guid isPermaLink="false">http://www.danielauener.com/?p=325</guid><pubDate>Tue, 15 Jan 2013 19:05:04 GMT</pubDate><description>
		&lt;p&gt;I know, there are a lot of widgets out there, to print related posts, but none of them I tested really suited my needs. First of all I think  a widget shouldn’t have a whole bunch of global settings, rather no global settings at all, I mean, it’s just a widget. But, even if I don’t like a huge settings page, just to run a little widget, there has to be some flexibility to let me adjust every widget-instance to my needs.&lt;/p&gt;
&lt;h2&gt;The Simply Related Posts Widget&lt;/h2&gt;
&lt;p&gt;In the case of related posts I couldn’t find a widget that really did what I wanted so I built my own. There are no global settings, but every widget instance has four options:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The title of the widget (default: Related Posts). It&lt;em&gt;&lt;strong&gt; is similar to all other widget titles&lt;/strong&gt;&lt;/em&gt; and gets printed before the widget-content.&lt;/li&gt;
&lt;li&gt;The taxonomy whose terms relate the posts (default: Tags). A post is related to another post, as soon as they share one or more terms of a taxonomy. This can be the standard taxonomies Tags and Categories, or Custom taxonomies. Here you&lt;em&gt;&lt;strong&gt;choose which taxonomy is the relating one&lt;/strong&gt;&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;How many related posts to show (default 5). Quite simple, put the &lt;strong&gt;&lt;em&gt;maximal number of related posts&lt;/em&gt;&lt;/strong&gt; you want to be visible here.&lt;/li&gt;
&lt;li&gt;Terms to exclude (default: none). Sometimes there are terms in a taxonomy, which are related to almost every post. The tag &lt;em&gt;wordpress &lt;/em&gt;in my blog is such an example. If you have such &lt;em&gt;&lt;strong&gt;tags you should exclude&lt;/strong&gt;&lt;/em&gt; them, because they relate basically all posts, which would make the widget quite useless&lt;img class=&quot;size-full wp-image-326 aligncenter&quot; alt=&quot;screenshot-1&quot; src=&quot;https://www.danielauener.com/assets/media/original/81f46507396810981efc.png&quot; width=&quot;261&quot; height=&quot;297&quot;&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;&lt;/h2&gt;
&lt;h2&gt;Installing&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Download the plugin from the directory: &lt;a title=&quot;A simple related posts by taxonomy widget&quot; href=&quot;http://wordpress.org/extend/plugins/simply-related-posts/&quot; target=&quot;_blank&quot;&gt;Simply Related Posts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Unpack and upload the &lt;code&gt;simply-related-posts&lt;/code&gt; folder to the &lt;code&gt;/wp-content/plugins/&lt;/code&gt;directory&lt;/li&gt;
&lt;li&gt;Activate the plugin through the ‘Plugins’ menu in WordPress&lt;/li&gt;
&lt;li&gt;Go to the ‘Appearance/Widgets’ area, add the ‘Simply Related Posts’ widget to a widget area.&lt;/li&gt;
&lt;li&gt;Configure your settings&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Feedback&lt;/h2&gt;
&lt;p&gt;Of course I want your feedback: Bugs or feature requests are welcome in the comments of this post or via &lt;a title=&quot;Contact me via twitter&quot; href=&quot;http://twitter.com/danielauener&quot; target=&quot;_blank&quot;&gt;twitter&lt;/a&gt; and I appreciate every &lt;a title=&quot;Review Simply Related Posts plugin&quot; href=&quot;http://wordpress.org/support/view/plugin-reviews/simply-related-posts&quot; target=&quot;_blank&quot;&gt;review&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For now the code is available via svn from the plugin directory:&lt;br&gt;
&lt;a title=&quot;SVN repo&quot; href=&quot;http://plugins.svn.wordpress.org/simply-related-posts/&quot; target=&quot;_blank&quot;&gt;&lt;strong&gt;http://plugins.svn.wordpress.org/simply-related-posts/&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now, there is even a github repository:&lt;br&gt;
&lt;strong&gt;&lt;a title=&quot;Git repo&quot; href=&quot;https://github.com/danielauener/wp-simply-related-posts&quot; target=&quot;_blank&quot;&gt;http://github.com/danielauener/wp-simply-related-posts&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
	</description></item><item><title>Related Posts without Plugin: A Taxonomy and a few Lines of Code</title><link>https://www.danielauener.com/related-posts-without-plugin/</link><guid isPermaLink="false">http://www.danielauener.com/?p=313</guid><pubDate>Fri, 11 Jan 2013 19:28:59 GMT</pubDate><description>
		&lt;p&gt;There are quite a few solutions to relate posts in WordPress. Most of them are plugins, adding a post2post table, some using taxonomies or post_metadata. A few days ago, I built a website for one of our clients, who wanted to manually relate posts to each other. The existing plugins didn’t properly match the requirements, so I had to implement related posts without a plugin. &lt;/p&gt;
&lt;p&gt;My approach was quite simple, I implemented two hooks which are mirroring all published pages in a related-posts-taxonomy, adding a new term for each post that gets published and deleting a term when the related post gets removed. First the code to add a &lt;em&gt;related_posts&lt;/em&gt; taxonomy, by adding this code to our functions.php:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
add_action( &amp;#39;init&amp;#39;, &amp;#39;register_taxonomy_related_posts&amp;#39; );
function register_taxonomy_related_posts() {
    $labels = array( 
        &amp;#39;name&amp;#39; =&amp;gt; _x( &amp;#39;Related posts&amp;#39;, &amp;#39;related_posts&amp;#39; ),
        &amp;#39;singular_name&amp;#39; =&amp;gt; _x( &amp;#39;Related post&amp;#39;, &amp;#39;related_posts&amp;#39; ),
        &amp;#39;search_items&amp;#39; =&amp;gt; _x( &amp;#39;Search Related posts&amp;#39;, &amp;#39;related_posts&amp;#39; ),
        &amp;#39;popular_items&amp;#39; =&amp;gt; _x( &amp;#39;Popular Related posts&amp;#39;, &amp;#39;related_posts&amp;#39; ),
        &amp;#39;all_items&amp;#39; =&amp;gt; _x( &amp;#39;All Related posts&amp;#39;, &amp;#39;related_posts&amp;#39; ),
        &amp;#39;parent_item&amp;#39; =&amp;gt; _x( &amp;#39;Parent Related post&amp;#39;, &amp;#39;related_posts&amp;#39; ),
        &amp;#39;parent_item_colon&amp;#39; =&amp;gt; _x( &amp;#39;Parent Related post:&amp;#39;, &amp;#39;related_posts&amp;#39; ),
        &amp;#39;edit_item&amp;#39; =&amp;gt; _x( &amp;#39;Edit Related post&amp;#39;, &amp;#39;related_posts&amp;#39; ),
        &amp;#39;update_item&amp;#39; =&amp;gt; _x( &amp;#39;Update Related post&amp;#39;, &amp;#39;related_posts&amp;#39; ),
        &amp;#39;add_new_item&amp;#39; =&amp;gt; _x( &amp;#39;Add New Related post&amp;#39;, &amp;#39;related_posts&amp;#39; ),
        &amp;#39;new_item_name&amp;#39; =&amp;gt; _x( &amp;#39;New Related post&amp;#39;, &amp;#39;related_posts&amp;#39; ),
        &amp;#39;separate_items_with_commas&amp;#39; =&amp;gt; _x( &amp;#39;Separate related posts with commas&amp;#39;, &amp;#39;related_posts&amp;#39; ),
        &amp;#39;add_or_remove_items&amp;#39; =&amp;gt; _x( &amp;#39;Add or remove related posts&amp;#39;, &amp;#39;related_posts&amp;#39; ),
        &amp;#39;choose_from_most_used&amp;#39; =&amp;gt; _x( &amp;#39;Choose from the most used related posts&amp;#39;, &amp;#39;related_posts&amp;#39; ),
        &amp;#39;menu_name&amp;#39; =&amp;gt; _x( &amp;#39;Related posts&amp;#39;, &amp;#39;related_posts&amp;#39; ),
    );

    $args = array( 
        &amp;#39;labels&amp;#39; =&amp;gt; $labels,
        &amp;#39;public&amp;#39; =&amp;gt; true,
        &amp;#39;show_in_nav_menus&amp;#39; =&amp;gt; false,
        &amp;#39;show_ui&amp;#39; =&amp;gt; true,
        &amp;#39;show_tagcloud&amp;#39; =&amp;gt; false,
        &amp;#39;hierarchical&amp;#39; =&amp;gt; true,
        &amp;#39;rewrite&amp;#39; =&amp;gt; false,
        &amp;#39;query_var&amp;#39; =&amp;gt; true
    );
    register_taxonomy( &amp;#39;related_posts&amp;#39;, array(&amp;#39;post&amp;#39;), $args );
}
&lt;/pre&gt;
&lt;p&gt;Now we have to hook into the save-post-action to add a term to our taxonomy, when a post gets published, or to update a term when a post’s title gets changed. We use the post’s title as the name for the term, which is visible to the user in the taxonomy widget. But since the post-title might not be unique, the relation has to be established via the post-id. That’s why we save the post-id as the term’s slug. Add the following code to the functions.php.&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
add_action( &amp;#39;save_post&amp;#39;, &amp;#39;add_relatable_post&amp;#39; );
function add_relatable_post( $post_id ) {
	if ( get_post($post_id)-&amp;gt;post_status == &amp;#39;publish&amp;#39; ) {
		if (($term = get_term_by(&amp;#39;slug&amp;#39;, $post_id, &amp;#39;related_posts&amp;#39;))) {
			wp_update_term($term-&amp;gt;term_id, &amp;#39;related_posts&amp;#39;, array(
				&amp;#39;name&amp;#39; =&amp;gt; get_the_title( $post_id ),
				&amp;#39;slug&amp;#39; =&amp;gt; $post_id
			));
		} else {
			wp_insert_term( get_the_title( $post_id ), &amp;#39;related_posts&amp;#39;, array(
				&amp;#39;slug&amp;#39; =&amp;gt; $post_id
			));
		}
	}
}
&lt;/pre&gt;
&lt;p&gt;Finally we have to remove a term if its related post gets deleted. This can be done by hooking into the &lt;em&gt;delete_post &lt;/em&gt;action, which is triggered when a post gets deleted (not moved to trash).&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
add_action(&amp;#39;delete_post&amp;#39;, &amp;#39;remove_relatable_post&amp;#39;, 10 );
function remove_relatable_post( $post_id ) {
	wp_delete_term( get_term_by(&amp;#39;slug&amp;#39;, $post_id, &amp;#39;related_posts&amp;#39;)-&amp;gt;term_id, &amp;#39;related_posts&amp;#39;);
}
&lt;/pre&gt;
&lt;p&gt;The admin interface is now prepared to relate posts to each other. On every post you see a widget, showing the &lt;em&gt;related_posts&lt;/em&gt; taxonomy which should contain a list of all existing posts. Remember, that you have to update existing posts to get them to show up in the taxonomy box. To relate a post to another, you just check the checkbox of the post you want to relate to.&lt;/p&gt;
&lt;p&gt;The last thing to do, is to retrieve the related posts in your theme. That is done by a simple taxonomy query in your template files.&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
if (have_posts()) : while (have_posts()): the_post();
	the_title();
	
	$related_posts = new WP_Query(array(
		&amp;#39;post_type&amp;#39; =&amp;gt; &amp;#39;post&amp;#39;,
		&amp;#39;post_status&amp;#39; =&amp;gt; &amp;#39;publish&amp;#39;,
		&amp;#39;tax_query&amp;#39; =&amp;gt; array(array(
	        &amp;#39;taxonomy&amp;#39; =&amp;gt; &amp;#39;related_posts&amp;#39;,
	        &amp;#39;terms&amp;#39; =&amp;gt; get_the_ID(),
	        &amp;#39;field&amp;#39; =&amp;gt; &amp;#39;slug&amp;#39;		
		))
	));

	if ($related_posts-&amp;gt;have_posts()) : while ($related_posts-&amp;gt;have_posts()): $related_posts-&amp;gt;the_post();
		// print your related posts
	endwhile; endif;

endwhile; endif; 
&lt;/pre&gt;
	</description></item><item><title>Setting up Gravity Forms Analytics Goals </title><link>https://www.danielauener.com/setting-up-gravity-forms-analytics-goals/</link><guid isPermaLink="false">http://www.danielauener.com/?p=300</guid><pubDate>Sun, 16 Dec 2012 14:52:42 GMT</pubDate><description>
		&lt;p&gt;When we deployed our &lt;a title=&quot;Internetavdelningens new site (swedish)&quot; href=&quot;http://www.internetavdelningen.se/ny-hemsida/&quot; target=&quot;_blank&quot;&gt;new site at Internetavdelningen&lt;/a&gt; last week, one of our goals was to get better at measuring conversions. Naturally, one of the main goals of the site is to convince potential clients to get in contact with us. Because our contact form is powered by the (absolutely awesome) Gravity Forms WordPress-plugin, we had to find a way to set up Gravity Forms Analytics Goals.&lt;/p&gt;
&lt;h2&gt;The easy way – a separate confirmation page&lt;/h2&gt;
&lt;p&gt;If that suits your page design and structure, it is easiest to just configure your Gravity form with a confirmation page. See the form settings screenshot below. You just have to create a page, which thanks visitors for their submission or something like that and choose this page in the form settings.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://www.danielauener.com/assets/media/original/542cb272fb3c3fc614e8.png&quot;&gt;&lt;img class=&quot;size-full wp-image-302 aligncenter&quot; title=&quot;confirmation_page&quot; alt=&quot;&quot; src=&quot;https://www.danielauener.com/assets/media/original/542cb272fb3c3fc614e8.png&quot; width=&quot;618&quot; height=&quot;352&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/542cb272fb3c3fc614e8.png 618w, https://www.danielauener.com/assets/media/original/33b5359fa7a375347f74.png 300w&quot; sizes=&quot;(max-width: 618px) 100vw, 618px&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Now it’s only left to add the page as a goal to your Google Analytics profile. Click on the “Admin” item in the top menu on the right side and then on your profile in the Profiles tab, in your profile, choose the “Goals” tab and add a goal in one of the sets. Name and activate the goal, choose “URL Destination” and copy the permalink of your confirmation site into the “Goal URL” field. Now, after a few hours (or max one day) your conversion statistics should appear under “Conversions” in the “Standard Reporting” section.&lt;/p&gt;
&lt;h2&gt;How to do it without a confirmation page&lt;/h2&gt;
&lt;div&gt;As usual the easy way might not be working in your situation. So it was for us, we wanted to use the text confirmation method (see screenshot below) and hadn’t a clue how to implement that with analytics goals.&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;&lt;a href=&quot;https://www.danielauener.com/assets/media/original/d10a11998a3e9565202c.png&quot;&gt;&lt;img class=&quot;alignnone size-full wp-image-303&quot; title=&quot;confirmation_text&quot; alt=&quot;&quot; src=&quot;https://www.danielauener.com/assets/media/original/98fd0b78e69639a8e23a.png&quot; width=&quot;538&quot; height=&quot;388&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/98fd0b78e69639a8e23a.png 538w, https://www.danielauener.com/assets/media/original/9449c89ea16d9c800317.png 300w&quot; sizes=&quot;(max-width: 538px) 100vw, 538px&quot;&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;p&gt;The solution was the somewhat unintuitive goal-type called “Event”. You select it instead of “URL Destination” in the goal settings.&lt;/p&gt;
&lt;p&gt;Fortunately there is a great &lt;a title=&quot;Google Analytics event tracking generator&quot; href=&quot;http://gaconfig.com/google-analytics-event-tracking/&quot; target=&quot;_blank&quot;&gt;generator to do almost all the work&lt;/a&gt; for you. If you follow all the steps, including the described goal settings, the only task left is to add the generated tracking code to the submit button. That’s quite easily done with the &lt;a title=&quot;Filter to alter your Gravity forms submit button&quot; href=&quot;http://www.gravityhelp.com/documentation/page/Gform_submit_button&quot; target=&quot;_blank&quot;&gt;Gform-submit-button-filter&lt;/a&gt;, provided by Gravity Forms.&lt;/p&gt;
&lt;p&gt;Here is the code snippet that adds the tracking code with an onclick-handler to the submit button of the form with id=1. Add it to your theme’s functions.php.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;EDIT: There seems to be a Gravity Forms upgrade that breaks the original code. That is because there is already an &lt;em&gt;onclick&lt;/em&gt;-event on the submit-button in the new version. So we just have to append our tracking code to the &lt;em&gt;onclick&lt;/em&gt;-event. Note that &lt;em&gt;onclick&lt;/em&gt; is written in all non-capital letters, in the original version of my snippet it was &lt;em&gt;onClick&lt;/em&gt;, which confused the HTML-parser. Thanks to &lt;a href=&quot;http://twitter.com/MrPeyler&quot;&gt;@MrPeyler&lt;/a&gt; for sending me a note and helping me test.&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
add_filter(&amp;quot;gform_submit_button_1&amp;quot;, &amp;quot;add_conversion_tracking_code&amp;quot;, 10, 2);
function add_conversion_tracking_code($button, $form) {
    $dom = new DOMDocument();
    $dom-&amp;gt;loadHTML($button);
    $input = $dom-&amp;gt;getElementsByTagName(&amp;#39;input&amp;#39;)-&amp;gt;item(0);
    if ($input-&amp;gt;hasAttribute(&amp;#39;onclick&amp;#39;)) {
        $input-&amp;gt;setAttribute(&amp;quot;onclick&amp;quot;,&amp;quot;_gaq.push([&amp;#39;_trackEvent&amp;#39;, &amp;#39;Contact&amp;#39;, &amp;#39;Information Request&amp;#39;, &amp;#39;Contact Form&amp;#39;,, false]);&amp;quot;.$input-&amp;gt;getAttribute(&amp;quot;onclick&amp;quot;));
    } else {
        $input-&amp;gt;setAttribute(&amp;quot;onclick&amp;quot;,&amp;quot;_gaq.push([&amp;#39;_trackEvent&amp;#39;, &amp;#39;Contact&amp;#39;, &amp;#39;Information Request&amp;#39;, &amp;#39;Contact Form&amp;#39;,, false]);&amp;quot;);
    }
    return $dom-&amp;gt;saveHtml();
}
&lt;/pre&gt;
&lt;p&gt;And here is the original WordPress filter, &lt;strong&gt;which doesn’t work with newer Gravity Forms versions&lt;/strong&gt;:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
add_filter(&amp;quot;gform_submit_button_1&amp;quot;, &amp;quot;add_conversion_tracking_code&amp;quot;, 10, 2);
function add_conversion_tracking_code($button, $form) {
    $dom = new DOMDocument();
    $dom-&amp;gt;loadHTML($button);
    $input = $dom-&amp;gt;getElementsByTagName(&amp;#39;input&amp;#39;)-&amp;gt;item(0);
    $input-&amp;gt;setAttribute(&amp;quot;onClick&amp;quot;,&amp;quot;_gaq.push([&amp;#39;_trackEvent&amp;#39;, &amp;#39;Contact&amp;#39;, &amp;#39;Information Request&amp;#39;, &amp;#39;Contactform&amp;#39;,, false]);&amp;quot;);
    return $dom-&amp;gt;saveHtml();
}
&lt;/pre&gt;
&lt;p&gt;Happy conversion tracking, with your Gravity Forms Analytics Goals!&lt;/p&gt;
	</description></item><item><title>Finally, enabled comments, looking forward to your feedback</title><link>https://www.danielauener.com/finally-enabled-comments-looking-forward-to-your-feedback/</link><guid isPermaLink="false">http://www.danielauener.com/?p=294</guid><pubDate>Wed, 12 Dec 2012 18:46:34 GMT</pubDate><description>
		&lt;p&gt;Happy birthday to me: I enabled comments on all posts and am hoping for a lot of feedback. I will do my very best to approve and respond to all incoming comments as fast as I can.&lt;/p&gt;
&lt;p&gt;Please ask what you want and let me know what you think!&lt;/p&gt;
	</description></item><item><title>Get class hierarchy in PHP</title><link>https://www.danielauener.com/get-class-hierarchy-in-php/</link><guid isPermaLink="false">http://www.danielauener.com/?p=292</guid><pubDate>Tue, 11 Dec 2012 16:59:26 GMT</pubDate><description>
		&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
function walk_up_hierarchy($object,$method) {
    $values = array();
    $class = get_class($object);
    do {
        array_unshift($values,$class::$method());
    } while (($class = get_parent_class($class)) !== false);
    return $values;
}
&lt;/pre&gt;
&lt;h2&gt;Get class hierarchy in PHP: The snippet’s story&lt;/h2&gt;
&lt;p&gt;Yesterday I tried to call a function for every parent class of an object and get the results in an array. I didn’t find the solution instantly, so I thought that’s something for the snippets section.&lt;/p&gt;
&lt;p&gt;The function above takes an instance of a class and a class method’s name. Then it calls the function on the object, storing the result as an array-item. Next it calls the method of the parent class of the object, storing the result in the beginning of the result-array and so on. &lt;/p&gt;
&lt;p&gt;Apparently the method has to be defined in all parent classes, if that is not guaranteed you have to take further precautions.&lt;/p&gt;
	</description></item><item><title>WordPress MVC: Easily add a touch of MVC to plugins</title><link>https://www.danielauener.com/wordpress-mvc-easily-add-a-touch-of-mvc/</link><guid isPermaLink="false">http://www.danielauener.com/?p=281</guid><pubDate>Wed, 05 Dec 2012 21:23:45 GMT</pubDate><description>
		&lt;p&gt;Building web-apps for some years now, I’ve worked a lot with multiple MVC-frameworks. Most recently with CakePHP, which is great. As a WordPress plugin developer I sometimes miss that strictly structured way of coding, a WordPress MVC pattern. While the code of a lot of plugins I see, is organised very well generally, I really don’t like the way many developers mix HTML-output with their plugin functions and classes. Here is an example, from the &lt;em&gt;Hello Dolly&lt;/em&gt; plugin.&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
// This just echoes the chosen line, we&amp;#39;ll position it later
function hello_dolly() {
    $chosen = hello_dolly_get_lyric();
    echo &amp;quot;&amp;lt;p id=&amp;#39;dolly&amp;#39;&amp;gt;$chosen&amp;lt;/p&amp;gt;&amp;quot;;
}
&lt;/pre&gt;
&lt;p&gt;Another one from the &lt;em&gt;akismet&lt;/em&gt; plugin, included in a standard WordPress installation:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
function akismet_stats_display() {
    global $akismet_api_host, $akismet_api_port, $wpcom_api_key;
    $blog = urlencode( get_bloginfo(&amp;#39;url&amp;#39;) );

    $url = &amp;#39;http://&amp;#39;;
    if ( is_ssl() )
        $url = &amp;#39;https://&amp;#39;;

    $url .= &amp;#39;akismet.com/web/1.0/user-stats.php&amp;#39;;
    $url .= &amp;quot;?blog={$blog}&amp;amp;api_key=&amp;quot; . akismet_get_key();
    ?&amp;gt;
    &amp;lt;div class=&amp;quot;wrap&amp;quot;&amp;gt;
    &amp;lt;iframe src=&amp;quot;&amp;lt;?php echo $url; ?&amp;gt;&amp;quot; width=&amp;quot;100%&amp;quot; height=&amp;quot;100%&amp;quot; frameborder=&amp;quot;0&amp;quot; id=&amp;quot;akismet-stats-frame&amp;quot;&amp;gt;&amp;lt;/iframe&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;?php
}
&lt;/pre&gt;
&lt;p&gt;Even if I don’t think that is a big deal, I see at least a readability issue. That’s why I prefer to store my HTML in separate files, just as you would do in every MVC-framework. It just needs a little view-class and this gets really easy. It has three logical parts: The first one is to locate the file, containing the HTML-view, the second one makes it possible to set variables in the view’s context and the last one renders the view.&lt;/p&gt;
&lt;h2&gt;WordPress MVC – The view’s location&lt;/h2&gt;
&lt;p&gt;I like to store my views in a folder called &lt;em&gt;views&lt;/em&gt; in my plugin directory and I even add the fact that it is a view to the filename. Thus, in my plugins a settings view would be located in &lt;code&gt;plugins/my-plugin/views/settings.view.php&lt;/code&gt;. Now, creating an instance of that view in one of my plugin-functions, I don’t want to add the complete path, the relevant part “settings” should do, and the view-class does the rest in the constructor:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
public function __construct($view) {
    $path = $plugin_path.&amp;quot;/views/&amp;quot;.$view.&amp;quot;.view.php&amp;quot;;
    if (file_exists($path&amp;quot;)) {
        $this-&amp;gt;view = $path;
    } else {
        wp_die(__(&amp;quot;View &amp;quot;.$path.&amp;quot; not found&amp;quot;));
    }	
}
&lt;/pre&gt;
&lt;h2&gt;WordPress MVC – Setting variables to use in the view&lt;/h2&gt;
&lt;p&gt;Having the location of the file, we can now add data, that we want to render the view with. Take the &lt;em&gt;Hello Dolly&lt;/em&gt; snippet as an example, the content of our view file would look like:&lt;/p&gt;
&lt;pre class=&quot;brush: xml; title: ; notranslate&quot; title=&quot;&quot;&gt;
&amp;lt;p id=&amp;quot;dolly&amp;quot;&amp;gt;
    &amp;lt;?php echo $chosen; ?&amp;gt;
&amp;lt;/p&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Now we have to set the variable &lt;code&gt;$chosen&lt;/code&gt; in the view’s context. Therefore we use an array called &lt;em&gt;vars&lt;/em&gt; containing all data coming in via the set-function of the view-class.&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
public function set($name,$value) {
    $this-&amp;gt;vars[$name] = $value;
}
&lt;/pre&gt;
&lt;h2&gt;WordPress MVC – Rendering the view&lt;/h2&gt;
&lt;p&gt;Finally we need a function to print out the view. It just registers the variables set in the vars-array and uses the output-buffering-functions of php to include and echo the view:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
public function render() {
    extract($this-&amp;gt;vars,EXTR_SKIP);
    ob_start();
    include $this-&amp;gt;view;
    echo ob_get_clean();
}	
&lt;/pre&gt;
&lt;h2&gt;WordPress MVC – The view class&lt;/h2&gt;
&lt;p&gt;Putting it all together in a view class (for copy and paste use, see github-link below), enables you to cleanly separate your views from your plugin-code. So, in a plugin, we can instantiate the view, set variables and render it, like this:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
include &amp;quot;classes/MyView.class.php&amp;quot;;
$view = new My_view(&amp;quot;dolly-example&amp;quot;);
$view-&amp;gt;set(&amp;quot;chosen&amp;quot;,&amp;quot;Lorem ipsum&amp;quot;);
$view-&amp;gt;render();
&lt;/pre&gt;
	</description></item><item><title>Current wp_nav_menu item in WordPress</title><link>https://www.danielauener.com/current-wp_nav_menu-item-wordpress/</link><guid isPermaLink="false">http://www.danielauener.com/?p=265</guid><pubDate>Fri, 23 Nov 2012 12:26:50 GMT</pubDate><description>
		&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;$menu = wp_get_nav_menu_items($menu_id,array(
   &amp;#39;posts_per_page&amp;#39; =&amp;gt; -1,
   &amp;#39;meta_key&amp;#39; =&amp;gt; &amp;#39;_menu_item_object_id&amp;#39;,
   &amp;#39;meta_value&amp;#39; =&amp;gt; $post-&amp;gt;ID // the currently displayed post
));
var_dump($menu[0]-&amp;gt;ID);
&lt;/pre&gt;
&lt;h2&gt;Current wp_nav_menu item: The snippet’s story&lt;/h2&gt;
&lt;p&gt;I needed to retrieve the current wp_nav_menu item connected to the currently requested page/post in WordPress. I found some solutions going through the whole menu tree, comparing each item’s object ID with the current post-id. But, since menu items are post-types, you are able to use all the WP-Query-params with &lt;a href=&quot;http://codex.wordpress.org/Function_Reference/wp_get_nav_menu_items&quot; title=&quot;Wordpress codex: wp_get_nav_menu_items&quot; target=&quot;_blank&quot;&gt;wp_get_nav_menu_items&lt;/a&gt;, even a meta-query. The code above selects all menu_items which are connected to the current post, from the menu you specify via $menu_id. &lt;/p&gt;
&lt;p&gt;The only drawback is that two menu-items, linked to the same post, would both be returned without you knowing which was actually clicked. However, that’s the same with all the other solutions I found.&lt;/p&gt;
	</description></item><item><title>WordPress post to post relationships, without altering the Database</title><link>https://www.danielauener.com/wordpress-post-to-post-relationships-without-altering-the-database/</link><guid isPermaLink="false">http://websites.local/daniel.auener.com/?p=120</guid><pubDate>Sat, 10 Nov 2012 12:26:28 GMT</pubDate><description>
		&lt;p&gt;Using WordPress as a framework for a web app, often requires some creativity when applying your desired data model to the &lt;a title=&quot;Wordpress database model&quot; href=&quot;http://codex.wordpress.org/Database_Description&quot; target=&quot;_blank&quot;&gt;standard WordPress database setup&lt;/a&gt;. This article wants to explore possible ways of creating WordPress Post-to-Post relationships. But, be warned, it is not about best practices, performance or perfect database modelling. It’s more of an attempt to list some options to consider before adding custom tables and queries and working around all the secure and tested WordPress API functions.&lt;/p&gt;
&lt;p&gt;Consider the enhanced entity relationship (ERR) diagram below. It shows some simple relationships of an exemplary author database. There is a many-to-many (n:m) relation of authors and books and in addition a one-to-many relation of publishers and authors.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.danielauener.com/assets/media/original/4ede61e97d5830e4ce38.png&quot;&gt;&lt;img class=&quot;size-full wp-image-191 aligncenter&quot; title=&quot;erauthors&quot; src=&quot;https://www.danielauener.com/assets/media/original/4ede61e97d5830e4ce38.png&quot; alt=&quot;&quot; width=&quot;544&quot; height=&quot;291&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/4ede61e97d5830e4ce38.png 544w, https://www.danielauener.com/assets/media/original/387bcd02b52b1b03ee2d.png 300w&quot; sizes=&quot;(max-width: 544px) 100vw, 544px&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;
&lt;p&gt;There are several ways to implement such a data-model without adding any custom tables to the WordPress database. The one thing you have to do in any case is to add appropriate custom post types, extended with suitable meta data.&lt;/p&gt;
&lt;h2&gt;Implementing custom post types and fields&lt;/h2&gt;
&lt;p&gt;WordPress gives us custom post types and fields to build our own data-structures into the database. In our example, custom post types correspond to the three main tables (authors, books and publishers). Following our model, we would define three post types, named author, book and publisher, like the one in this, somewhat generic, code example:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;register_post_type(&amp;#39;author&amp;#39;,
	array(
		&amp;#39;labels&amp;#39; =&amp;gt; array(
			&amp;#39;name&amp;#39; =&amp;gt; &amp;#39;Author&amp;#39;,
		),
		&amp;#39;public&amp;#39; =&amp;gt; true,
		&amp;#39;has_archive&amp;#39; =&amp;gt; true,
		&amp;#39;supports&amp;#39; =&amp;gt; array(&amp;#39;title&amp;#39;,&amp;#39;editor&amp;#39;,&amp;#39;custom-fields&amp;#39;)
	)
);&lt;/pre&gt;
&lt;p&gt;That would provide us with the extra post types in the admin main menu. Posts of these new types have a title field and an editor field by default and you are able to add whichever meta-data you like, through custom fields.&lt;/p&gt;
&lt;h2&gt;Relating Posts&lt;/h2&gt;
&lt;p&gt;That was the easy part, but now it gets more tricky. How do we relate posts of the custom post types, just by using the WordPress API and no custom tables? There are some candidates among all the WordPress components that might work.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;hierarchical posts&lt;/dt&gt;
&lt;dd&gt;WordPress posts, and so posts of custom post types, are already designed to have a relation, if you want them to. It is a simple parent-child relationship that you might know from WordPress pages. Thus, all of our custom posts can have one parent and, luckily, it doesn’t have to be the same post type.&lt;/dd&gt;
&lt;dt&gt;meta data&lt;/dt&gt;
&lt;dd&gt;As you read above, we can use post meta data to add any kind of information to a post. It could be an ISBN number to a book, but it could as well be information about relations between one post and another. As you will see we can realize all significant relation-types with metadata.&lt;/dd&gt;
&lt;dt&gt;custom taxonomies&lt;/dt&gt;
&lt;dd&gt;In contrast to posts, which are holding content, taxonomies are &lt;em&gt;organizing&lt;/em&gt; it. You already know the two default taxonomies WordPress provides: categories and tags. Even taxonomies can be used to establish relations, but as I think meta-data is the cleaner way, there will be no example in this article.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Let’s have a look at a simplified WordPress data model and see how these components are built. Hierarchical posts are realized by a &lt;em&gt;post_parent&lt;/em&gt; column in the &lt;em&gt;wp_posts&lt;/em&gt; table, which can be set to the ID of any post. Post-metadata is implemented through the &lt;em&gt;wp_postmeta&lt;/em&gt; table, which is able to hold multiple metadata rows for each post.&lt;/p&gt;
&lt;p&gt;&lt;img class=&quot;size-full wp-image-193 aligncenter&quot; title=&quot;wp_simple_db&quot; src=&quot;https://www.danielauener.com/assets/media/original/784d1d3853774e7c3e83.png&quot; alt=&quot;&quot; width=&quot;641&quot; height=&quot;460&quot; srcset=&quot;https://www.danielauener.com/assets/media/original/784d1d3853774e7c3e83.png 641w, https://www.danielauener.com/assets/media/original/68e40f8377b52b86ccfd.png 300w&quot; sizes=&quot;(max-width: 641px) 100vw, 641px&quot;&gt;&lt;/p&gt;
&lt;p&gt;Now, what we want to do, is to utilize the existing database schema, to get the relations between posts of varied types to work. But, our goal is to do this only by using the API, so we can’t just start to hack SQL-queries. Let’s go through the types of relations we want to build one by one and take a look at how it can be done.&lt;/p&gt;
&lt;h2&gt;Implementing a one-to-many Relation, using the &lt;em&gt;post_parent-&lt;/em&gt;column&lt;/h2&gt;
&lt;p&gt;Now, how to implement a one-to-many relation, like the one between publishers and authors in our example model? The section on hierarchical posts might have given you the idea. A 1:n relation is nothing more than a parent-child relationship. One parent post can have multiple children, but one child post can only have one parent. So, let’s say, we are inserting an author-post, the only thing we have to do is to set the &lt;em&gt;post_parent&lt;/em&gt; property and we are done.&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;$publishers_id = 22; // insert the real id of a publisher-post here
$author = array(
   &amp;#39;post_parent&amp;#39;    =&amp;gt; $publishers_id,
   &amp;#39;post_status&amp;#39;    =&amp;gt; &amp;#39;publish&amp;#39;,
   &amp;#39;post_title&amp;#39;     =&amp;gt; &amp;#39;This is an example author&amp;#39;,
   &amp;#39;post_type&amp;#39;      =&amp;gt; &amp;#39;author&amp;#39;
);
wp_insert_post( $author );&lt;/pre&gt;
&lt;p&gt;Retrieving parent posts is equally simple. Just use a custom &lt;em&gt;WP_Query&lt;/em&gt; object for getting all the authors related to a publisher:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
   $args = array(
      &amp;#39;post_type&amp;#39; =&amp;gt; &amp;#39;author&amp;#39;,
      &amp;#39;post_parent&amp;#39; =&amp;gt; $publishers_id
   );
   $authors = new WP_Query($args);
&lt;/pre&gt;
&lt;p&gt;The drawback of this method is that you aren’t able to relate a post to more than one parent, because all the posts are in one table. Thus you can only build a parent-child relation between one post type and another and not one post type and multiple others. If you have a more complex model than ours, chances are high that you have more than one 1:n relation on some post types. For example, if we wanted to add labor unions to the model. That would mean that you had to set both a publisher and an authors union as parent, which isn’t possible.&lt;/p&gt;
&lt;h2&gt;Multiple one-to-many Relations, using post-metadata&lt;/h2&gt;
&lt;p&gt;If you look at the WordPress database schema above, you can see that one post can be related to multiple &lt;em&gt;wp_postmeta&lt;/em&gt; rows. The idea is now, to use this existing relation in the database for our relation of multiple post types – we want, in our concrete case, to relate some authors to both a publisher and a union. Our implementation is basically a variation of the &lt;em&gt;post_parent&lt;/em&gt; method, as we will just create additional &lt;em&gt;post_parent&lt;/em&gt;-meta-data for every post type we are relating. &lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
// insert the real post ids here
$publishers_id = 1;
$unions_id = 2;
$author_1_id = 3;
$author_2_id = 4;

// add relations, author 1 has only a publisher, author 2 has both publisher and union
add_post_meta($author_1_id, &amp;#39;publisher_id&amp;#39;, $publishers_id);
add_post_meta($author_2_id, &amp;#39;publisher_id&amp;#39;, $publishers_id);
add_post_meta($author_2_id, &amp;#39;unions_id&amp;#39;, $unions_id);
&lt;/pre&gt;
&lt;p&gt;Even retrieving the posts again is only slightly different from the &lt;em&gt;post_parent&lt;/em&gt;-method we used above. Instead of querying the posts by &lt;em&gt;post_parent&lt;/em&gt; we have to query them by &lt;em&gt;meta_key&lt;/em&gt;.&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
   // getting a publishers authors
   $args = array(
      &amp;#39;post_type&amp;#39; =&amp;gt; &amp;#39;author&amp;#39;,
      &amp;#39;meta_key&amp;#39; =&amp;gt; &amp;#39;publisher_id&amp;#39;
      &amp;#39;meta_value&amp;#39; =&amp;gt; $publishers_id
   );
   $authors = new WP_Query($args);

   // getting a unions authors
   $args = array(
      &amp;#39;post_type&amp;#39; =&amp;gt; &amp;#39;author&amp;#39;,
      &amp;#39;meta_key&amp;#39; =&amp;gt; &amp;#39;union_id&amp;#39;
      &amp;#39;meta_value&amp;#39; =&amp;gt; $unions_id
   );
   $authors = new WP_Query($args);
&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;A note on 1:1 relations: Implementing one to one relations is basically the same as implementing one-to-many relations. The only difference is that you manually have to set a constraint, limiting the application to relate not more than one post to another, so that a post can’t be set as a parent if it already is the parent of  another post.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Many-to-many relations, using post-metadata&lt;/h2&gt;
&lt;p&gt;Many-to-many relations can’t be created with the &lt;em&gt;parent_post&lt;/em&gt;-method. They are usually created by using a &lt;a href=&quot;http://en.wikipedia.org/wiki/Junction_table&quot;&gt;junction table&lt;/a&gt;, which holds the keys of two related posts in each row. In the author database model at the beginning of this article, you can see a junction table between authors and books, which physically enables a n:m-relation via two 1:n relations to the junction table. Now, take a look at the simplified WordPress database schema and the &lt;em&gt;wp_posts&lt;/em&gt;/&lt;em&gt;wp_postmeta&lt;/em&gt; relation. There is a one-to-many relationship between them, but, since we are relating author-posts to book-posts, stored in the same table, there actually are two one-to-many relations and the &lt;em&gt;wp_postmeta&lt;/em&gt; table is working precisely as a junction table. The only thing we have to do, is to adjust the meta-data example above, to save multiple related post ids, instead of one. Luckily, the WordPress API enables us to do that.&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
// insert the real post ids here
$book_1_id = 1;
$book_2_id = 2;
$author_1_id = 3;
$author_2_id = 4;

// add relations, author 1 has only a publisher, author 2 has both publisher and union
add_post_meta($author_1_id, &amp;#39;authors_books&amp;#39;, $book_1_id);
add_post_meta($author_2_id, &amp;#39;authors_books&amp;#39;, $book_1_id);
add_post_meta($author_2_id, &amp;#39;authors_books&amp;#39;, $book_2_id);
&lt;/pre&gt;
&lt;p&gt;That was all. Retrieving the ids of the books of an author is as simple as reading the &lt;em&gt;authors_books&lt;/em&gt;-meta-data of an author post. If the author is related to multiple books, you will get an array of ids, which you can use to read the book-posts. Getting all the authors of a book requires a custom &lt;em&gt;WP_Query&lt;/em&gt; with &lt;em&gt;meta_key&lt;/em&gt;-option, just as the one we used on 1:n relations.&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
   // getting a books authors
   $args = array(
      &amp;#39;post_type&amp;#39; =&amp;gt; &amp;#39;author&amp;#39;,
      &amp;#39;meta_key&amp;#39; =&amp;gt; &amp;#39;authors_books&amp;#39;
      &amp;#39;meta_value&amp;#39; =&amp;gt; $book_id
   );
   $authors = new WP_Query($args);
&lt;/pre&gt;
&lt;h2&gt;Many-to-many relations with additional relationship information&lt;/h2&gt;
&lt;p&gt;Sometimes you need to add a piece of information to the relationship itself. How many chapters of the book are written by each of its authors, would be an (uninspired) example. Usually you just add columns to the junction table, but that’s not possible in our case, because we don’t want to change the database setup. &lt;/p&gt;
&lt;p&gt;Since the only way to dynamically add custom data is through custom post types, we have to create one, just to store the relation-data. Let’s call it &lt;em&gt;author_book&lt;/em&gt;. Now, when we create a relation between an author-post and a book-post, we even have to create an &lt;em&gt;author_book&lt;/em&gt;-post, store some data in it and connect it to the relation itself. We are doing this, again, with post-metadata.&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
// post ids, of authors and books
$author = 1;
$book = 2;

// insert relationship post
$author_book = array(
   &amp;#39;post_status&amp;#39;    =&amp;gt; &amp;#39;publish&amp;#39;,
   &amp;#39;post_title&amp;#39;     =&amp;gt; &amp;#39;Information about the relation between author and book&amp;#39;,
   &amp;#39;post_type&amp;#39;      =&amp;gt; &amp;#39;author_book&amp;#39;
);
author_book_id = wp_insert_post( $author_book );

// relate posts
add_post_meta($author_book_id,&amp;#39;author&amp;#39;,$author);
add_post_meta($author_book_id,&amp;#39;book&amp;#39;,$book);
&lt;/pre&gt;
&lt;p&gt;The &lt;em&gt;author_book&lt;/em&gt;-post is now related to both, the &lt;em&gt;author&lt;/em&gt;– and the &lt;em&gt;book&lt;/em&gt;-post. Retrieving the data, has to be done in several steps now, which might be ineffective – but, as I said before, this article is not about finding the most performant solution.&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
// retrieve authors of a book, plus information post
$book_id = 1;

$args = array(
   &amp;#39;post_type&amp;#39; =&amp;gt; &amp;#39;author_book&amp;#39;,
   &amp;#39;meta_key&amp;#39; =&amp;gt; &amp;#39;book&amp;#39;
   &amp;#39;meta_value&amp;#39; =&amp;gt; $book_id
);
$author_books = get_posts($args);

foreach ($author_books as $author_book) {
   $author = get_post(get_post_meta($author_book-&amp;gt;ID));
   // do sth with the author
}
&lt;/pre&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Relating posts of different posts types is one of the key features for using WordPress as a web-application framework. Using post-metadata and some API functions, it is possible to implement 1:n, 1:1, n:m and even data-holding n:m relations. The pros are, that you can rely on the reliable, tested and continuously bug-fixed WordPress API. The cons are that you might run into performance problems, not using an optimized database. However, I think the discussed solutions for one-to-many, one-to-one and many-to-many relations are at least considerable and could be used in production. While the last case of simulating a junction-table with content columns was more of a showcase of what’s possible. &lt;/p&gt;
	</description></item><item><title>How to use array_map on associative arrays to change values and keys</title><link>https://www.danielauener.com/howto-use-array_map-on-associative-arrays-to-change-values-and-keys/</link><guid isPermaLink="false">http://www.danielauener.com/?p=135</guid><pubDate>Fri, 09 Nov 2012 19:52:26 GMT</pubDate><description>
		&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
$assoc_arr = array_reduce($arr, function ($result, $item) {
    $result[$item[&amp;#39;text&amp;#39;]] = $item[&amp;#39;id&amp;#39;];
    return $result;
}, array());
&lt;/pre&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Recommendation: &lt;/strong&gt;If you are interested in fast PHP for your WordPress site, check out this great &lt;a href=&quot;https://kinsta.com/blog/php-benchmarks/?kaid=LJTEEDVAIWBS&quot; rel=&quot;nofollow&quot;&gt;PHP/WP benchmark-post&lt;/a&gt; from Kinsta, where you can get great &lt;a href=&quot;https://kinsta.com/?kaid=LJTEEDVAIWBS&quot; rel=&quot;nofollow&quot;&gt;managed WordPress hosting&lt;/a&gt; with the best support and performance-optimizing technical add-ons like Redis and Elasticsearch.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;The snippet’s story&lt;/h2&gt;
&lt;p&gt;I just ran into a problem using array_map on associative arrays, like the following one:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
$arr = array(
   array(
      &amp;#39;id&amp;#39; =&amp;gt; 22,
      &amp;#39;text&amp;#39; =&amp;gt; &amp;#39;Lorem&amp;#39;
   ),
   array(
      &amp;#39;id&amp;#39; =&amp;gt; 25,
      &amp;#39;text&amp;#39; =&amp;gt; &amp;#39;ipsum&amp;#39;
   ),
);
&lt;/pre&gt;
&lt;p&gt;From this array, I wanted to create another, associative array, with the following structure:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;
$assoc_arr = array(
   &amp;#39;Lorem&amp;#39; =&amp;gt; 22,
   &amp;#39;ipsum&amp;#39; =&amp;gt; 25
);
&lt;/pre&gt;
&lt;p&gt;My first guess was the &lt;a title=&quot;array map function&quot; href=&quot;http://php.net/manual/en/function.array-map.php&quot;&gt;array_map&lt;/a&gt; function, but I had to realize that there is no way to manipulate the keys of the resulting array. After some googling, I discovered that it is &lt;a title=&quot;array reduce function&quot; href=&quot;http://php.net/manual/en/function.array-reduce.php&quot;&gt;array_reduce&lt;/a&gt; you have to use to simulate array_map on associative arrays.&lt;/p&gt;
&lt;p&gt;P.S. I know, a simple foreach would have done the trick, but once on the path of functional programming, I didn’t want to leave it so quickly 🙂&lt;/p&gt;
	</description></item><item><title>WordPress as a Framework for Web Apps - Building a simple Recipe Database</title><link>https://www.danielauener.com/wordpress-as-framework-for-webapps/</link><guid isPermaLink="false">http://websites.local/daniel.auener.com/?p=51</guid><pubDate>Sun, 04 Nov 2012 20:06:18 GMT</pubDate><description>
		&lt;p&gt;In the past WordPress has grown from a powerful blog-system to a powerful CMS and, more recently, to a powerful framework for web applications. In fact, using WordPress customization features and the WordPress API, there are not many applications I can think of, you couldn’t build with WordPress as a framework. However, there are a lot of applications you shouldn’t build with WordPress. Choosing which framework to use (or choosing not to use one) is balancing between many pros and cons affecting architecture, performance, security, scalability and so on.&lt;/p&gt;
&lt;p&gt;I found WordPress extremely useful as a base for medium-sized web apps, without too much traffic. Building a small application, for example a restaurant table booking system, from scratch or even with a framework like Rails or CakePHP, would involve thinking about database schema, controller structure, authentication, user interfaces etc. WordPress already does much of this: you already have rough user management, a working admin interface and you only have to think about how to map your data-model to the already existing WordPress database structure.&lt;/p&gt;
&lt;h2&gt;Our use case: A recipe database&lt;/h2&gt;
&lt;p&gt;Now, I want to show you how to implement a simple recipe database with WordPress as a framework. Requirements are really basic:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Allows adding recipes and editing them just like ordinary posts or pages&lt;/li&gt;
&lt;li&gt;Allows categorizing recipes in hierarchical categories like Healthy -&amp;gt; Chicken -&amp;gt; Marinated Chicken Breasts&lt;/li&gt;
&lt;li&gt;Allows adding ingredients to a recipe and finding recipes by ingredients&lt;/li&gt;
&lt;li&gt;Allows adding quantities to ingredients of a recipe, e.g. 500ml milk, 20g sugar, 3 tablespoons olive oil&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;I will focus on how to customize WordPress to adjust it to your data model, mainly by showing you how to use the essentials to build every WordPress powered web app:&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;Custom post types&lt;/li&gt;
&lt;li&gt;Custom taxonomies&lt;/li&gt;
&lt;li&gt;Custom fields&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2&gt;Set up custom post type for recipes&lt;/h2&gt;
&lt;p&gt;In WordPress the base of every content holding entity is a post. The two post types you surely are familiar with are posts and pages. For our recipe database we will create a new type: recipes.&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;register_post_type(&amp;#39;recdb_recipe&amp;#39;,
	array(
		&amp;#39;labels&amp;#39; =&amp;gt; array(
			&amp;#39;name&amp;#39; =&amp;gt; &amp;#39;Recipes&amp;#39;,
		),
		&amp;#39;public&amp;#39; =&amp;gt; true,
		&amp;#39;has_archive&amp;#39; =&amp;gt; true,
		&amp;#39;supports&amp;#39; =&amp;gt; array(&amp;#39;title&amp;#39;,&amp;#39;editor&amp;#39;,&amp;#39;custom-fields&amp;#39;)
	)
);&lt;/pre&gt;
&lt;p&gt;The new post type will show up in the admin interface along with posts and pages. It supplies a field for the recipe title and an editor field which is meant for the recipe’s description part. We even added support for custom fields, which will be necessary later on.&lt;/p&gt;
&lt;h2&gt;Set up custom taxonomies for recipe categories and ingredients&lt;/h2&gt;
&lt;p&gt;In WordPress, taxonomies are not for holding content, like posts, they are for organizing it. You should be used to the two default taxonomies: categories (hierarchical) and tags (not hierarchical). However, like with post types, you can add your own kinds of taxonomies. For our recipes database you could use categories and tags, but they are meant to be used for posts really, so we create our own recipe categories and link them to the recipe post type:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;register_taxonomy(
	&amp;#39;recdb_categories&amp;#39;,
	array(&amp;#39;recdb_recipe&amp;#39;),
	array(
		&amp;#39;label&amp;#39; =&amp;gt; &amp;#39;Recipe categories&amp;#39;,
		&amp;#39;sort&amp;#39; =&amp;gt; true,
		&amp;#39;rewrite&amp;#39; =&amp;gt; array(&amp;#39;slug&amp;#39; =&amp;gt; &amp;#39;recipe-categories&amp;#39;),
		&amp;#39;hierarchical&amp;#39; =&amp;gt; true,
		&amp;#39;show_in_nav_menus&amp;#39; =&amp;gt; true
	)
);&lt;/pre&gt;
&lt;p&gt;In the admin interface they will show up under the recipes-menu and furthermore there will be a checkbox-list on every recipe to sort it into categories. The same way we want it with ingredients, but with a slight difference: they don’t have to be hierarchical, because every recipe will have just a plain list of ingredients. Here is how to create an ingredients-taxonomy, that will work just like ordinary tags. You can manage it from your admin interface and add it to any recipe:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;register_taxonomy(
	&amp;#39;recdb_categories&amp;#39;,
	array(&amp;#39;recdb_recipe&amp;#39;),
	array(
		&amp;#39;label&amp;#39; =&amp;gt; &amp;#39;Recipe categories&amp;#39;,
		&amp;#39;sort&amp;#39; =&amp;gt; true,
		&amp;#39;rewrite&amp;#39; =&amp;gt; array(&amp;#39;slug&amp;#39; =&amp;gt; &amp;#39;recipe-categories&amp;#39;),
		&amp;#39;hierarchical&amp;#39; =&amp;gt; true,
		&amp;#39;show_in_nav_menus&amp;#39; =&amp;gt; true
	)
);&lt;/pre&gt;
&lt;h2&gt;Set up custom fields for ingredient units&lt;/h2&gt;
&lt;p&gt;For now we can create new recipes, categorize them and add ingredients. The last missing feature is to add some sort of quantities to the ingredients, because the information that you will need milk, while cooking your dinner, is useless if you don’t know how much. Here is where custom fields come into the picture. For all ingredient-tags you are adding to a recipe, you have to add a custom filed as well. The name of the field is always &lt;em&gt;quantities&lt;/em&gt;, that will allow us to read them as an array later on. The value has to be formatted like this: &lt;em&gt;taxonomy-term-slug:string&lt;/em&gt;. Here are some concrete examples for the custom fields on our recipes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;quantities -&amp;gt; water:100ml&lt;/li&gt;
&lt;li&gt;quantities -&amp;gt; milk:200ml&lt;/li&gt;
&lt;li&gt;quantities -&amp;gt; sugar:20g&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Embedding recipes in your theme&lt;/h2&gt;
&lt;p&gt;I am assuming you have a working theme and now want to add special templates for recipes. Begin with adding recipe-categories to your menus. If you are using custom menus, they will show up in the menu editor just like ordinary categories (you might have to activate them in your screen options panel). Now you should be able to navigate to the added recipe categories on your website. The recipes in those categories are displayed with your &lt;em&gt;index.php&lt;/em&gt; or another matching template.&lt;/p&gt;
&lt;p&gt;The next step is to build a custom loop for recipes. We will generally build quite an ordinary loop, including &lt;code&gt;the_title&lt;/code&gt; and &lt;code&gt;the_content&lt;/code&gt; template tags. Building the ingredients list is a bit special, though. For this, we first have to get the quantities meta-value, using &lt;code&gt;get_post_meta&lt;/code&gt;. Then we are looping through the quantities, reading both the quantity and the ingredient and finally we provide an ingredient link, which leads to a site listing recipes with the same ingredient. Create a file called &lt;em&gt;loop-recipes.php&lt;/em&gt; in your template directory and add the following loop:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;&amp;lt;?php if (have_posts()): while (have_posts()): the_post(); ?&amp;gt;
	&amp;lt;div class=&amp;quot;recipe&amp;quot;&amp;gt;
		&amp;lt;h2&amp;gt;&amp;lt;?php the_title(); ?&amp;gt;&amp;lt;/h2&amp;gt;
		&amp;lt;ul class=&amp;#39;ingredients&amp;#39;&amp;gt;
			&amp;lt;?php
				if (is_single()):
					$quantities = get_post_meta(get_the_ID(),&amp;#39;quantities&amp;#39;);
					foreach ($quantities as $quantity):
						$quantity = explode(&amp;#39;:&amp;#39;,$quantity); ?&amp;gt;
						&amp;lt;li&amp;gt;
							&amp;lt;?php echo $quantity[1]; ?&amp;gt; &amp;lt;a href=&amp;#39;&amp;lt;?php echo get_term_link($quantity[0],&amp;#39;recdb_ingredients&amp;#39;); ?&amp;gt;&amp;#39;&amp;gt;
								&amp;lt;?php echo $quantity[0]; ?&amp;gt;
							&amp;lt;/a&amp;gt;
						&amp;lt;/li&amp;gt;&amp;lt;?php
					endforeach;
				endif;
			?&amp;gt;
		&amp;lt;/ul&amp;gt;
		&amp;lt;?php
			if (is_single()):
				the_content();
			else:
				the_excerpt();
				?&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;?php the_permalink(); ?&amp;gt;&amp;quot;&amp;gt;Read recipe&amp;lt;/a&amp;gt;&amp;lt;?php
			endif; ?&amp;gt;
	&amp;lt;/div&amp;gt;
&amp;lt;?php endwhile; endif; ?&amp;gt;&lt;/pre&gt;
&lt;p&gt;Now it is only left to embed the loop in the template files for recdb_categories and recdb_ingredients and adding a template to show a full recipe. Create three files called &lt;code&gt;taxonomy-recdb_categories.php&lt;/code&gt;, &lt;code&gt;taxonomy-recdb_ingredients.php&lt;/code&gt; and &lt;code&gt;single-recdb_recipe.php&lt;/code&gt; in your template directory. The following code goes into the category-template:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;&amp;lt;?php get_header(); ?&amp;gt;
&amp;lt;h1&amp;gt;Category: &amp;lt;?php single_cat_title(); ?&amp;gt;&amp;lt;/h1&amp;gt;
&amp;lt;p&amp;gt;List of recipes in category &amp;lt;?php single_cat_title(); ?&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;?php get_template_part(&amp;#39;loop&amp;#39;,&amp;#39;recipes&amp;#39;); ?&amp;gt;
&amp;lt;?php get_footer(); ?&amp;gt;&lt;/pre&gt;
&lt;p&gt;Here is the code for the ingredients-template:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;&amp;lt;?php get_header(); ?&amp;gt;
&amp;lt;h1&amp;gt;&amp;lt;?php single_cat_title(); ?&amp;gt;&amp;lt;/h1&amp;gt;
&amp;lt;p&amp;gt;List of recipes, which use &amp;lt;?php single_cat_title(); ?&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;?php get_template_part(&amp;#39;loop&amp;#39;,&amp;#39;recipes&amp;#39;); ?&amp;gt;
&amp;lt;?php get_footer(); ?&amp;gt;&lt;/pre&gt;
&lt;p&gt;And finally the single recipe template:&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;&amp;lt;?php get_header(); ?&amp;gt;
&amp;lt;?php get_template_part(&amp;#39;loop&amp;#39;,&amp;#39;recipes&amp;#39;); ?&amp;gt;
&amp;lt;?php get_footer(); ?&amp;gt;&lt;/pre&gt;
&lt;h2&gt;WordPress as a framework for web-apps: Conclusion&lt;/h2&gt;
&lt;p&gt;If you followed all the steps, you should have a really basic, but working recipe database running. Of course, the way to add ingredients is really horrifying, from a user’s point of view, but this tutorial isn’t about usability. It is a starting point for one who wants to take WordPress as a framework for web apps that aren’t blogs or ordinary websites. The vital point, I think, is to really understand the WordPress customization abilities and learn to map them to your own use-case.&lt;/p&gt;
&lt;p&gt;Surely there are quite some drawbacks using WordPress for your web-app and you shouldn’t ignore them. However, once you have decided to go the WordPress way, you get a lot of cool features to defeat the disadvantages.&lt;/p&gt;
	</description></item><item><title>Strip scripts and styles from WP-ecommerce themes</title><link>https://www.danielauener.com/strip-wp-ecommerce-themes-scripts-styles/</link><guid isPermaLink="false">http://websites.local/daniel.auener.com/?p=26</guid><pubDate>Sat, 03 Nov 2012 07:46:18 GMT</pubDate><description>
		&lt;p&gt;I had to implement some WP-ecommerce themes (&lt;a href=&quot;http://getshopped.org/&quot; title=&quot;Wp-ecommerce download&quot; target=&quot;_blank&quot;&gt;download WP-ecommerce&lt;/a&gt;), a couple of weeks ago. The admin interface happens to be quite good and simple, but I wanted to build my theme from scratch, controlling 100% of the code. So all the JavaScript and css stuff, that automatically gets included, was just a lot of overhead for me.&lt;/p&gt;
&lt;p&gt;It took a while to find all the scripts and styles, so I thought sharing them here could help someone with the same problem. Just add the following lines to your &lt;em&gt;functions.php&lt;/em&gt;.&lt;/p&gt;
&lt;pre class=&quot;brush: php; title: ; notranslate&quot; title=&quot;&quot;&gt;add_action(&amp;#39;wp_print_styles&amp;#39;,&amp;#39;deregister_styles&amp;#39;,100);
function deregister_styles() {
	if (!is_admin()) {
		wp_deregister_style(&amp;#39;wpsc-thickbox&amp;#39;);
		wp_deregister_style(&amp;#39;wpsc-theme-css&amp;#39;);
		wp_deregister_style(&amp;#39;wpsc-theme-css-compatibility&amp;#39;);
		wp_deregister_style(&amp;#39;wp-e-commerce-dynamic&amp;#39;);
	}
}

add_action(&amp;#39;wp_print_scripts&amp;#39;,&amp;#39;deregister_script&amp;#39;,100);
function deregister_script() {
	if (!is_admin()) {
		wp_deregister_script(&amp;#39;jQuery&amp;#39;);
		wp_deregister_script(&amp;#39;wp-e-commerce&amp;#39;);
		wp_deregister_script(&amp;#39;infieldlabel&amp;#39;);
		wp_deregister_script(&amp;#39;wp-e-commerce-ajax-legacy&amp;#39;);
		wp_deregister_script(&amp;#39;wp-e-commerce-legacy&amp;#39;);
		wp_deregister_script(&amp;#39;wp-e-commerce-dynamic&amp;#39;);
		wp_deregister_script(&amp;#39;livequery&amp;#39;);
		wp_deregister_script(&amp;#39;wpsc-thickbox&amp;#39;);
	}
}&lt;/pre&gt;
&lt;p&gt;All done. Now we just have to load our own styles and can begin to work on our cleaned up WP-ecommerce themes.&lt;/p&gt;
	</description></item></channel></rss>