{"id":642,"date":"2025-04-02T11:40:07","date_gmt":"2025-04-02T11:40:07","guid":{"rendered":"https:\/\/adhdux.com\/?p=642"},"modified":"2025-03-25T12:25:05","modified_gmt":"2025-03-25T12:25:05","slug":"designing-for-ux-in-wordpress-a-non-developers-take","status":"publish","type":"post","link":"https:\/\/adhdux.com\/?p=642","title":{"rendered":"Designing for UX in WordPress \u2013 A Non-Developer&#8217;s Take"},"content":{"rendered":"\n<p>As someone deeply involved in user experience but not a traditional developer, I recently took over our company&#8217;s WordPress site. I inherited a site that <em>technically worked<\/em>, but from design systems and UX point of view, it felt rigid, inflexible, and hard to scale.<\/p>\n\n\n\n<p>Don&#8217;t get me wrong \u2014 WordPress powers over 40% of the web, and for good reason. It&#8217;s versatile, backed by a massive community, and has more plugins than I can count. But when you approach WordPress with the UX mindset of crafting tailored experiences, reusing elegant components, and designing for consistent storytelling across pages\u2026 it can feel like trying to paint a mural with crayons.<\/p>\n\n\n\n<p>One of the things I&#8217;ve really wanted is componentized design\u2014reusable testimonial blocks, callouts, and CTAs\u2014things I could plug in and reuse across different campaigns or product pages without reinventing the wheel. That&#8217;s how I&#8217;d think in Figma or a design system. But out of the box, WordPress&#8217;s Gutenberg blocks don&#8217;t always get me there, especially with the limited customization some themes lock you into.<\/p>\n\n\n\n<p>So I started wondering\u2026 can AI actually help design for UX in WordPress?<\/p>\n\n\n\n<p>Turns out: yes. Below is a custom WordPress block inspired by a testimonial I wanted to reuse across our site. I fed ChatGPT an image of the layout, which helped turn it into a flexible, reusable Gutenberg block. This is the kind of creative partnership between UX and AI that I get excited about.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">WordPress Custom Block: Testimonial with Image and Quote<\/h2>\n\n\n\n<p>Here&#8217;s a fully functioning Gutenberg block written in JSX using React (compatible with @wordpress\/scripts). You can drop this into a custom plugin or your theme&#8217;s blocks folder.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">testimonial-block.js<\/h3>\n\n\n\n<p>jsx<\/p>\n\n\n\n<p>CopyEdit<\/p>\n\n\n\n<p>import { registerBlockType } from &#8216;@wordpress\/blocks&#8217;;<\/p>\n\n\n\n<p>import { RichText, MediaUpload, InspectorControls } from &#8216;@wordpress\/block-editor&#8217;;<\/p>\n\n\n\n<p>import { Button, PanelBody } from &#8216;@wordpress\/components&#8217;;<\/p>\n\n\n\n<p>import &#8216;.\/style.css&#8217;;<\/p>\n\n\n\n<p>registerBlockType(&#8216;custom\/testimonial-block&#8217;, {<\/p>\n\n\n\n<p>&nbsp;&nbsp;title: &#8216;Testimonial with Image and Quote&#8217;,<\/p>\n\n\n\n<p>&nbsp;&nbsp;icon: &#8216;format-quote&#8217;,<\/p>\n\n\n\n<p>&nbsp;&nbsp;category: &#8216;widgets&#8217;,<\/p>\n\n\n\n<p>&nbsp;&nbsp;attributes: {<\/p>\n\n\n\n<p>&nbsp; &nbsp;&nbsp;imageUrl: { type: &#8216;string&#8217; },<\/p>\n\n\n\n<p>&nbsp; &nbsp;&nbsp;imageAlt: { type: &#8216;string&#8217;},<\/p>\n\n\n\n<p>&nbsp; &nbsp;&nbsp;callout: { type: &#8216;string&#8217;, source: &#8216;html&#8217;, selector: &#8216;.callout-text&#8217;},<\/p>\n\n\n\n<p>&nbsp; &nbsp;&nbsp;quote: { type: &#8216;string&#8217;, source: &#8216;html&#8217;, selector: &#8216;.quote-text&#8217;},<\/p>\n\n\n\n<p>&nbsp; &nbsp;&nbsp;author: { type: &#8216;string&#8217;, source: &#8216;html&#8217;, selector: &#8216;.author&#8217;},<\/p>\n\n\n\n<p>&nbsp;&nbsp;},<\/p>\n\n\n\n<p>&nbsp;&nbsp;edit: ({ attributes, setAttributes }) =&gt; {<\/p>\n\n\n\n<p>&nbsp; &nbsp;&nbsp;const { imageUrl, imageAlt, callout, quote, author } = attributes;<\/p>\n\n\n\n<p>&nbsp; &nbsp;&nbsp;return (<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp;&nbsp;&lt;&gt;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;InspectorControls&gt;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;PanelBody title= &#8220;Image Settings&#8221;&gt;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;MediaUpload<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;onSelect={(media) =&gt; setAttributes({ imageUrl: media.url, imageAlt: media.alt })}<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;allowedTypes={[&#8216;image&#8217;]}<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;render={({ open }) =&gt; (<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;Button onClick={open} isSecondary&gt;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;{imageUrl ? &#8216;Change Image&#8217;: &#8216;Choose Image&#8217;}<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;\/Button&gt;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;)}<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\/&gt;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;\/PanelBody&gt;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;\/InspectorControls&gt;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;div className=&#8221;testimonial-block&#8221;&gt;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;{imageUrl &amp;&amp; &lt;img src={imageUrl} alt={imageAlt} className=&#8221;testimonial-image&#8221; \/&gt;}<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;div className=&#8221;testimonial-content&#8221;&gt;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;RichText<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;tagName= &#8220;p&#8221;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;className=&#8221;callout-text&#8221;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;value={callout}<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;onChange={(val) =&gt; setAttributes({ callout: val })}<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;placeholder= &#8220;Callout text (e.g. delivery for over 110,000 EOPs&#8230;)&#8221;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\/&gt;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;RichText<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;tagName= &#8220;blockquote&#8221;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;className=&#8221;quote-text&#8221;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;value={quote}<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;onChange={(val) =&gt; setAttributes({ quote: val })}<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;placeholder= &#8220;Testimonial quote&#8230;&#8221;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\/&gt;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;RichText<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;tagName= &#8220;p&#8221;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;className= &#8220;author&#8221;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;value={author}<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;onChange={(val) =&gt; setAttributes({ author: val })}<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;placeholder= &#8220;Author name and organization&#8221;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;\/&gt;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;\/div&gt;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;\/div&gt;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp;&nbsp;&lt;\/&gt;<\/p>\n\n\n\n<p>&nbsp; &nbsp;&nbsp;);<\/p>\n\n\n\n<p>&nbsp;&nbsp;},<\/p>\n\n\n\n<p>&nbsp;&nbsp;save: ({ attributes }) =&gt; {<\/p>\n\n\n\n<p>&nbsp; &nbsp;&nbsp;const { imageUrl, imageAlt, callout, quote, author } = attributes;<\/p>\n\n\n\n<p>&nbsp; &nbsp;&nbsp;return (<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp;&nbsp;&lt;div className=&#8221;testimonial-block&#8221;&gt;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;{imageUrl &amp;&amp; &lt;img src={imageUrl} alt={imageAlt} className=&#8221;testimonial-image&#8221; \/&gt;}<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;div className=&#8221;testimonial-content&#8221;&gt;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;p className=&#8221;callout-text&#8221;&gt;{callout}&lt;\/p&gt;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;blockquote className=&#8221;quote-text&#8221;&gt;{quote}&lt;\/blockquote&gt;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;p className=&#8221;author&#8221;&gt;{author}&lt;\/p&gt;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&lt;\/div&gt;<\/p>\n\n\n\n<p>&nbsp; &nbsp; &nbsp;&nbsp;&lt;\/div&gt;<\/p>\n\n\n\n<p>&nbsp; &nbsp;&nbsp;);<\/p>\n\n\n\n<p>&nbsp;&nbsp;},<\/p>\n\n\n\n<p>});<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">CSS: style.css<\/h3>\n\n\n\n<p>css<\/p>\n\n\n\n<p>CopyEdit<\/p>\n\n\n\n<p>.testimonial-block {<\/p>\n\n\n\n<p>&nbsp;&nbsp;display: flex;<\/p>\n\n\n\n<p>&nbsp;&nbsp;flex-wrap: wrap;<\/p>\n\n\n\n<p>&nbsp;&nbsp;gap: 2rem;<\/p>\n\n\n\n<p>&nbsp;&nbsp;background: #f9f9fc;<\/p>\n\n\n\n<p>&nbsp;&nbsp;border-radius: 12px;<\/p>\n\n\n\n<p>&nbsp;&nbsp;padding: 2rem;<\/p>\n\n\n\n<p>&nbsp;&nbsp;align-items: center;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>.testimonial-image {<\/p>\n\n\n\n<p>&nbsp;&nbsp;max-width: 300px;<\/p>\n\n\n\n<p>&nbsp;&nbsp;border-radius: 12px;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>.testimonial-content {<\/p>\n\n\n\n<p>&nbsp;&nbsp;flex: 1;<\/p>\n\n\n\n<p>&nbsp;&nbsp;min-width: 300px;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>.callout-text {<\/p>\n\n\n\n<p>&nbsp;&nbsp;background: #4d3489;<\/p>\n\n\n\n<p>&nbsp;&nbsp;color: #fff;<\/p>\n\n\n\n<p>&nbsp;&nbsp;padding: 1rem;<\/p>\n\n\n\n<p>&nbsp;&nbsp;border-radius: 8px;<\/p>\n\n\n\n<p>&nbsp;&nbsp;font-weight: bold;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>.quote-text {<\/p>\n\n\n\n<p>&nbsp;&nbsp;font-style: italic;<\/p>\n\n\n\n<p>&nbsp;&nbsp;color: #3f3f78;<\/p>\n\n\n\n<p>&nbsp;&nbsp;margin: 1rem 0;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<p>.author {<\/p>\n\n\n\n<p>&nbsp;&nbsp;font-weight: 500;<\/p>\n\n\n\n<p>&nbsp;&nbsp;color: #555;<\/p>\n\n\n\n<p>}<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">To Use This Block:<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Create a folder in your theme or plugin called \/blocks\/testimonial-block\/<\/li>\n\n\n\n<li>Save the JS file as testimonial-block.js and the CSS as style.css<\/li>\n\n\n\n<li>Register the block using @wordpress\/scripts or enqueue it via functions.php<\/li>\n\n\n\n<li>Use it inside any page\/post with Gutenberg<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Final Thoughts<\/h2>\n\n\n\n<p>WordPress doesn&#8217;t have to limit your creativity as a UX pro. With just a bit of help \u2014 even from AI \u2014 you can turn static ideas into dynamic, reusable, user-centered components. And if you&#8217;re not a developer? Doesn&#8217;t matter. You&#8217;ve got vision \u2014 and now you&#8217;ve got tools to turn that vision into reality.<\/p>\n\n\n\n<p>Want to turn more of your ideas into WordPress blocks? I&#8217;m happy to help.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As someone deeply involved in user experience but not a traditional developer, I recently took over our company&#8217;s WordPress site. I inherited a site that technically worked, but from design systems and UX point of view, it felt rigid, inflexible, and hard to scale. Don&#8217;t get me wrong \u2014 WordPress powers over 40% of the<\/p>\n<p><span class=\"more-wrapper\"><a class=\"more-link button\" href=\"https:\/\/adhdux.com\/?p=642\">Continue reading<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[10,6,7,4,165],"class_list":["post-642","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-uxdesign","tag-uxresearch","tag-uxstrategy","tag-uxui","tag-wordpress"],"_links":{"self":[{"href":"https:\/\/adhdux.com\/index.php?rest_route=\/wp\/v2\/posts\/642","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/adhdux.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/adhdux.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/adhdux.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/adhdux.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=642"}],"version-history":[{"count":1,"href":"https:\/\/adhdux.com\/index.php?rest_route=\/wp\/v2\/posts\/642\/revisions"}],"predecessor-version":[{"id":643,"href":"https:\/\/adhdux.com\/index.php?rest_route=\/wp\/v2\/posts\/642\/revisions\/643"}],"wp:attachment":[{"href":"https:\/\/adhdux.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=642"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/adhdux.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=642"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/adhdux.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=642"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}