Tag: WordPress

  • Code as Context for l10n

    Why WordPress Demands “مخطّط المستند” Over Legacy Translations

    In software localization, a string in isolation is a trap. When translating a massive platform like WordPress, looking at a spreadsheet of isolated English phrases often leads to “safe” but clunky translations. The ultimate source of truth is never the glossary—it is the source code.

    For years, the Arabic localization for “Document Outline” has been ملخص عناوين المستند (literally: Summary of document headings). Born from an era where translators felt the need to heavily explain UI features to users (a process called explicitation), this string is wordy, descriptive, and ultimately outdated.

    As we look toward modern WordPress UI paradigms, it is time to standardize this string to مخطّط المستند. To understand exactly why this update is necessary, we don’t need to debate linguistics—we just need to look at the code.

    The Reference Code: A Window into the UI

    Let’s examine the exact file where this string lives in the Gutenberg block editor: wp-includes/js/dist/editor.js, specifically within the TableOfContentsPanel component.

    Here is the structural blueprint of that panel:

    JavaScript

    // ... [Lines 49560 - 49617 omitted for brevity] ...
    <div className="table-of-contents__wrapper" role="note" aria-label={__("Document Statistics")}>
        {/* Renders Counts: Words, Characters, Time to read, Headings, Paragraphs, Blocks */}
    </div>
    
    { headingCount > 0 && (
        <>
            <hr />
            <h2 className="table-of-contents__title">{__("Document Outline")}</h2>
            <DocumentOutline
                onSelect={onRequestClose}
                hasOutlineItemsDisabled={hasOutlineItemsDisabled}
            />
        </>
    )}
    // ... [Line 49630] ...
    

    By reading this snippet, the context transforms the way we must approach the translation. Here is how the reference code guides us to a vastly superior Arabic localization.

    1. The Code Proves It’s a Structure, Not a “Summary”

    Look at the logic in the code. The panel is divided into two distinct sections. The top half is strictly for Document Statistics (Words, Characters, reading time). This top section acts as the actual summary of the document’s contents.

    Below the <hr /> (horizontal rule), we see the Document Outline. If we keep the legacy translation ملخص عناوين المستند (Summary of headings), we create a semantic clash. We are placing a “summary” directly underneath actual statistical summaries.

    The <DocumentOutline/> component rendered here is a navigational tree—a structural skeleton that lets users jump between header blocks. مخطّط means “plan,” “map,” or “outline.” By using مخطّط المستند, we accurately tell the user they are looking at a structural map, differentiating it cleanly from the statistics above it.

    2. The Original File Path Reveals Architectural Intent While the bundled distribution code lives in editor.js, line 49560 provides a crucial breadcrumb to the original, uncompiled source code: // packages/editor/build-module/components/table-of-contents/panel.mjs.

    This file path is a L10n goldmine. It explicitly identifies that this UI element belongs to the table-of-contents component. A Table of Contents is inherently a navigational map of a document’s hierarchy; it is never a summary of the text itself. By organizing the code under table-of-contents, the core engineering team is signaling clear structural intent.

    Translating this feature as a ملخص (summary) directly contradicts the architectural blueprint of the software. Conversely, مخطّط (outline/map) perfectly echoes the navigational purpose of a Table of Contents, ensuring the Arabic string aligns with the foundational logic of the Gutenberg editor.

    3. The <h2> Tag Demands Brevity

    Notice the HTML element wrapping our string:

    <h2 className="table-of-contents__title">{__("Document Outline")}</h2>

    This string is not explanatory text; it is a section heading (<h2>). In UI design, headings must be punchy, scannable, and instantly recognizable.

    • Legacy: ملخص عناوين المستند (3 words, visually heavy)
    • Proposed: مخطّط المستند (2 words, crisp and standard)

    Users do not read software interfaces; they scan them. A three-word, overly descriptive heading slows down the user’s cognitive parsing. مخطّط المستند functions perfectly as a quick, scannable title.

    4. Spatial Constraints of the Sidebar Panel

    The component name is TableOfContentsPanel. In the WordPress editor, this panel is a narrow sidebar or a popover menu. UI real estate is highly restricted.

    When a multi-word string like ملخص عناوين المستند is crammed into a narrow sidebar, it risks truncation (e.g., ملخص عناوين ا...) or awkward line breaks, especially on mobile views. The source code reveals the physical constraints of the UI, proving that the shorter, more compact مخطّط المستند is a functional necessity to preserve the design layout.

    5. Aligning with Industry Standards

    As localization specialists, consistency across the digital ecosystem is one of our primary goals. When users switch between Microsoft Word, Google Docs, Apple Pages, and various web-based CMS platforms, they shouldn’t have to learn a new vocabulary for the exact same tool.

    Major tech giants have already recognized the need for concise, structural terminology:

    • Google Docs currently utilizes مخطّط المستند for its outline feature.
    • Microsoft Word uses similar structural terminology, like جزء التنقل (Navigation Pane) or مخطط المستند (Document Map in older versions).

    By updating to مخطّط المستند, we align our product with the established mental models of millions of Arab users. We stop forcing them to translate our unique legacy jargon and instead speak the language they already know.

    Conclusion: Translating for the Future

    WordPress is a constantly evolving ecosystem. With modern iterations of the block editor, the UI is becoming cleaner, faster, and more minimalist. Our Arabic localization must evolve with it.

    Relying on the source code changes a translator from a mere linguist into a UI/UX advocate. The code at editor.js:49618 explicitly tells us that “Document Outline” is a compact, structural heading housed within a narrow panel. By dropping the outdated, hand-holding explicitation, observing UI boundaries, and adopting the industry standard مخطّط المستند, we respect the developer’s design and ultimately provide a more native, professional experience for the Arab WordPress user.

  • Why Your WordPress Theme Needs wp_get_theme()->get(‘Version’) for Cache Busting

    Decoding wp_get_theme()->get( 'Version' ): A Beginner’s Guide to Constants and the Arrow (->)

    If you are just starting your journey as a WordPress theme developer, opening the functions.php file of a reputable theme can feel like staring at a foreign language. You will likely come across a line that looks something like this:

    define( 'ARFSE_VERSION', wp_get_theme()->get( 'Version' ) );

    At first glance, it’s just a bunch of symbols, parentheses, and an arrow. What does it do? Why is it there? And what on earth is that -> symbol trying to tell you?

    Let’s break down this single line of code piece by piece. By the end of this post, you won’t just understand it—you will want to use it in your own themes.


    Part 1: Unpacking the Basics – define() and Constants

    Let’s start from the outside and work our way in.

    The define() function is a standard PHP function. Its job is to create a global constant. Think of a constant as a labeled box that holds one specific piece of information. Once you put something inside it, you can never change it while the page is loading—it is “set in stone.”

    • Constant Name: ARFSE_VERSION
    • Constant Value: Whatever is returned by wp_get_theme()->get( 'Version' )

    Once this line runs, you can type ARFSE_VERSION anywhere else in your theme (or even in plugins) and it will magically output your theme’s version number.


    Part 2: Where does the version come from? wp_get_theme()

    Now, let’s look at the right side of the equation: wp_get_theme()->get( 'Version' ).

    wp_get_theme() is a built-in WordPress function. When you call it without passing any arguments, it automatically figures out which theme is currently active and returns a special “object” representing that theme.

    But how does WordPress know the version number? It reads the metadata from your theme’s style.css file. If you open your style.css, you will see a header like this at the top:

    /*
     Theme Name: My Awesome Theme
     Version: 1.2.3
     */

    The wp_get_theme() function parses this file header and loads all this data into memory.


    Part 3: The Magical ->get( 'Version' ) Method

    This is where the arrow (->) comes into play.
    Since wp_get_theme() returned a “Theme Object,” we can access its internal functions using the -> symbol. The get() method is specifically designed to retrieve any value from that style.css header.

    By passing the string 'Version' to this method, we are telling WordPress: “Out of all the data you read from the style.css file, please hand me back only the Version number.”

    It returns the string "1.2.3".


    Part 4: Why do developers use this pattern? (The Real Benefits)

    You might be thinking: “Why not just type ‘1.2.3’ directly into my code?”

    Here are the three biggest reasons this pattern is a game-changer:

    1. Cache Busting (The #1 Reason)

    This is the most important benefit. When you enqueue CSS or JavaScript files in WordPress, browsers aggressively cache them to speed up page loading.

    If you hardcode the version as 1.0 and update your theme’s styles, your users will keep seeing the old, cached CSS files.

    By using the constant, you can write your enqueue function like this:

    wp_enqueue_style( 'my-theme-style', get_template_directory_uri() . '/style.css', [], ARFSE_VERSION );

    Now, whenever you bump the version number in your style.css header, the URL automatically changes to style.css?ver=1.2.3. Browsers see this as a “new” file and instantly download the fresh assets. No more clearing caches manually!

    2. Single Source of Truth

    You only maintain the version number in one place—the style.css header, which WordPress requires anyway. Instead of updating the version in five different files, you define the constant once, and the entire theme inherits it automatically.

    3. Conditional Logic for Updates

    You can use the constant to run database migrations or update routines:

    if ( get_option( 'my_theme_db_version' ) !== ARFSE_VERSION ) {
        // Run database upgrade scripts...
        update_option( 'my_theme_db_version', ARFSE_VERSION );
    }

    Part 5: Zooming in on the Arrow (->)

    Now, let’s tackle the part that scares most beginners: the Object Operator, or as it is officially known, the arrow (->).

    The arrow’s entire job is to access a property or method that belongs to a specific object.

    Here is the exact execution order when PHP runs wp_get_theme()->get( 'Version' ):

    1. Step 1: PHP calls wp_get_theme(). This builds a WP_Theme object in memory.
    2. Step 2: PHP looks at the arrow (->) and sees the method get() on the right side.
    3. Step 3: It searches inside that specific WP_Theme object, finds the get method, and runs it.
    4. Step 4: It passes the argument 'Version' into that method and returns the result.

    Method Chaining (A Cool Trick)
    Without the arrow, you would have to write this in two separate lines:

    $theme_object = wp_get_theme();       // Step 1: Get the object
    $version = $theme_object->get( 'Version' ); // Step 2: Access the method

    By using -> right after the function call, PHP allows you to chain them together into one smooth, elegant line.


    Part 6: What is happening inside the get method?

    To truly understand the arrow, you need to know what happens when the method runs. Inside the WP_Theme class, the get() method uses a special PHP variable called $this.

    $this is a pointer that represents the exact object that the arrow was used on.

    A simplified version of the code inside the class looks like this:

    class WP_Theme {
        private $headers = []; // Stores the style.css data
    
        public function get( $header_key ) {
            // $this refers to the object we just grabbed via wp_get_theme()
            if ( isset( $this->headers[ $header_key ] ) ) {
                return $this->headers[ $header_key ];
            }
            return '';
        }
    }

    So when you write $theme_obj->get('Version'), the $this inside the method points right back to $theme_obj, allowing it to read its own internal data.


    Part 7: The Showdown – Arrow (->) vs. Double Colon (::)

    New PHP developers often confuse the arrow (->) with the double colon (::). They are not interchangeable.

    To understand why, you need to know the difference between a Blueprint (Class) and a Physical Building (Instance):

    FeatureInstance (Object) – uses ->Static (Class) – uses ::
    How to createMust use new keyword (e.g., $house = new House();).No new needed. Exists automatically (e.g., House::getBlueprint();).
    MemoryEach object gets its own copy of properties. (House A has a red door, House B has a blue door).Only one copy exists in memory, shared by everything.
    The $this variableAvailable. $this refers to this specific object.Not available. There is no specific object to refer to.
    When to useWhen you have specific data that belongs to one thing (like multiple WP_Query loops).For stateless utilities (like formatting text) or when you don’t need to store unique data.

    Why this matters in our code: wp_get_theme() returns an Instance (an actual object). Therefore, you must use ->. If you tried wp_get_theme()::get('Version'), PHP would throw a fatal error!


    The Curious Bonus: The Fundamental Difference – Instance (Object) vs. Static (Class) Context in PHP

    To fully grasp the arrow (->), you must contrast it with the double colon (::). They are not interchangeable, and the difference comes down to context.

    Think of a Class as a blueprint for a house, and an Instance (Object) as an actual physical house built from that blueprint.

    FeatureInstance (Object) – uses ->Static (Class) – uses ::
    CreationMust use new (e.g., $house = new House();).No new needed. Exists automatically (e.g., House::getBlueprint();).
    MemoryEach object has its own copy of properties. House A has a red door; House B has a blue door.Only one copy exists in memory, shared globally across your entire script.
    The $this variableAvailable. $this refers to this specific object’s unique data.Not available. There is no specific object to point to.
    State managementMaintains state—changes to one object do not affect others.Stateless—changing a static property changes it for everyone using that class.
    Use caseWhen you need to store unique data (e.g., multiple WP_Query objects).For pure utility functions that don’t rely on specific data (e.g., formatting strings).

    Why this matters here: wp_get_theme() returns an Instance (an actual object). Therefore, you must use ->. If you mistakenly tried wp_get_theme()::get('Version'), PHP would throw a fatal error because the :: operator is for static class members, not for objects.


    Final Thoughts: Don’t Fear the Symbols

    When you see wp_get_theme()->get( 'Version' ), don’t see gibberish. See it as:

    • A Powerful Constant that makes your code easier to maintain.
    • A Dynamic Version that busts browser caches automatically.
    • A friendly Arrow (->) acting as a bridge between a function and the specific object it returned.

    The arrow is your best friend in Object-Oriented PHP. It tells the interpreter: “Take the object I just got, look inside it, and run this specific function on it.”

    Keep practicing, keep reading core WordPress code, and soon these patterns will feel like second nature. Happy coding! 🚀

  • Beyond the Glossary: Context-Driven Arabic Translations for ‘Author’ and ‘Parent’ in WordPress

    Beyond the Glossary: Context-Driven Arabic Translations for ‘Author’ and ‘Parent’ in WordPress



    In WordPress Arabic localization, the choice between كاتب and مُطوِّر for translating "author" is strictly context-driven. The official WordPress Arabic glossary provides a clear baseline, but real-world usage requires nuance.


    Official Rule (WordPress Glossary)

    Authorكاتب
    في سياق المحتوى الكتابي مثل مقال، صفحة، تعليق..الخ

    كاتب is the default, approved translation for “author” when referring to the person who wrote content within WordPress (posts, pages, comments).


    When to Use Each Term

    TermUse When…Example ContextsWhy
    كاتبReferring to the writer of content (posts, pages, comments, custom post types)كاتب المقالة، عرض جميع مقالات الكاتب، كاتب التعليقMatches the glossary; aligns with Arabic UX expectations for content attribution.
    مُطوِّرReferring to the creator of a plugin or themeمُطوِّر الإضافة، مُطوِّر القالبمُطوِّر implies “originator/creator of a substantial work” – used outside content authorship. Is also synonym with developer.

    Critical Distinction in WordPress Core

    WordPress uses contextual strings (_x()) to disambiguate. Always check the msgctxt:

    // Content authorship → كاتب
    _x( 'Author', 'post author' );           // → كاتب
    
    // Plugin/theme creator → مُطوِّر
    /* translators: %s: plugin author name */
    __( 'By %s', 'my-plugin' );              // Context: plugin header → مُطوِّر
    
    // Theme author (official glossary)
    'Theme Author' → 'مُطور القالب'          // Note: glossary uses مُطوِّر, not مؤلف

    🚫 Common Pitfalls to Avoid

    MistakeWhy It’s WrongCorrection
    Using مؤلف for post authorsSounds overly formal; breaks consistency with WP admin UIUse كاتب
    Using كاتب for plugin authorsUnderstates the technical/creative roleUse مُطوِّر (preferred) or مؤلِّف
    Ignoring msgctxtLeads to inconsistent translations across contextsAlways check context in .pot files
    Translating “Author” without contextAmbiguous; may be post author, plugin author, or book authorRequest context from developers or use glossary defaults

    ✅ Quick Reference Decision Tree

    Is "author" referring to…?
    │
    ├─► A person who wrote a post/page/comment? → كاتب
    │
    ├─► The creator of a plugin/theme? → مُطوِّر (glossary-preferred) 
    ││
    └─► Uncertain? → Default to كاتب + flag for review

    In WordPress Arabic localization, the choice between أب and الأصل for translating "parent" is strictly context-driven. The WordPress Arabic translation team maintains a consistent convention to avoid ambiguity in UI, code, and documentation.

    Note: we use أم instead of الأب, that is “mother” instead of “father” when translating “parent page” as “page is feminine” in Arabic.

    Here’s the practical breakdown:

    ✅ Use أب when:

    ContextExample TranslationWhy
    Parent/Child Themesالقالب الأبMirrors the technical parent/child metaphor used in WP theme inheritance. Pairs naturally with القالب الابن.
    Code/Developer Contextsملف القالب الأب, دوال القالب الأبUsed in dev docs, hooks, or CLI output where the familial metaphor is preserved for clarity.
    Term/Theme/Plugin Inheritance UIتحديث القالب الأب Matches how WP core handles theme relationships.
    Pageصفحة أمWe use أم (mother) as page is feminine

    ✅ Use الأصل when:

    ContextExample TranslationWhy
    Hierarchical Content (Categories, Custom Post Types)الصفحة الأصل, التصنيف الأصل, الأصل (dropdown label)الأصل implies “root/source/base” in Arabic UX. It’s the standard for content trees.
    Menu Structureالعنصر الأصل, الأصلMenus use الأصل to denote top-level items in nested lists.
    Taxonomy/Relationship UIاختيار الأصل, بدون أصلAvoids biological connotations; focuses on hierarchy origin.

    🔍 How WordPress Enforces This

    WordPress uses contextual translation functions to distinguish these cases. In the source code, you’ll find:

    _x( 'Parent', 'child theme' );        // → الأب
    _x( 'Parent', 'theme parent' );      // → القالب الأب
    _x( 'Parent', 'menu parent' );       // → الأصل

    Always check the msgctxt (message context) in .pot files. It’s the single source of truth.

    Conclusion

    Navigating these subtleties in WordPress Arabic localization demands more than a quick glossary lookup—it calls for deliberate, context-aware investigation. When doubt arises, always check the message context (msgctxt) in source files, cross-reference previously approved translations, and inspect the surrounding code to confirm meaning. Filtering a term across the entire project helps you maintain a consistent, precise translation that respects both the official glossary and real-world user expectations.

  • Beyond WordPress: Embracing Flutter’s Versatility in Coding Realm

    Beyond WordPress: Embracing Flutter’s Versatility in Coding Realm

    In my journey of advancing my coding and computer skills, I’ve begun exploring other technologies alongside my WordPress experience—most recently, Flutter and Dart.

    My Experience with WordPress Contributions

    For about three years, I’ve contributed to various open-source projects within the WordPress community, including translation, documentation, accessibility, and support.

    Though my WordPress.org profile currently boasts two badges, I’ve appreciated the journey, which has allowed me to make a positive impact in WordPress open-source.

    One takeaway is that I didn’t find as much guidance from the WordPress contributor community as expected, particularly when it came to hands-on mentorship for leveling up my skills.

    While support forums are strong, I believe WordPress could further benefit from offering more targeted support for budding contributors.

    WordPress Developer Experience

    Years ago, when I ceased coding WordPress themes, there was a dearth of resources and tutorials available for aspiring WordPress developers. However, a quick search on YouTube today reveals an abundance of free tutorials on WordPress development.

    Furthermore, there’s no denying the plethora of engaging blogs and websites dedicated to WordPress, catering to developers and enthusiasts alike. These resources, such as codeinwp.com (now https://wpshout.com/), WP Tavern, WPBeginner, the Codex, and numerous expert WordPress developers’ blogs, offer invaluable insights and knowledge.

    Why I’m Expanding My Skills with Flutter

    Comparing the Flutter and Dart ecosystem to WordPress:

    The Flutter community is notably more active, offering extensive support and tutorials compared to WordPress.
    Backed by Google, Flutter provides a more robust and modern development environment.
    Flutter’s cross-platform capabilities, including compatibility with embedded systems, make it a versatile choice for app development.

    Flutter leverages modern tooling and programming language, which was a refreshing and exciting experience when I started to write code using Dart & Flutter on VScode

    Packages and Libraries

    Feature WordPress Dart/Flutter
    Library Source Built-in, external sources Built-in (widgets), Pub package manager
    Package Management No built-in manager, alternatives used Pub package manager
    Library Management Manual downloads, SVN (workaround) Automated installation, dependency management
    Packages & library Flutter/Dart VS WordPress

    WordPress often relies on manual library downloads or workarounds for dependency management, whereas Dart/Flutter offers a streamlined approach through Pub package manager.

    Static Analysis

    Feature Flutter WordPress
    Integration Built-in with dart analyze External tools for PHP
    Scope Analyzes Dart code (entire codebase) Analyzes PHP code (themes/plugins only)
    Focus General code quality, Flutter-specific issues Security vulnerabilities, coding best practices
    False Positives Less common More potential for false positives
    Client-Side Analysis No May not analyze client-side code (JavaScript)
    Static analysis comparison Dart/Flutter VS WordPress

    In essence, Flutter offers a more robust and integrated static analysis experience, while WordPress relies on external tools and has certain limitations.

    We could delve into comparing other aspects of both the most popular CMS and the Dart/Flutter ecosystem. However, that’s beyond the scope of this post.

    Moneywise

    WordPress remains a solid platform for web development, especially given its extensive user base. Flutter, meanwhile, opens up opportunities in cross-platform app development, potentially expanding revenue streams by reaching mobile and embedded systems in addition to web.

    Conclusion

    My contributions to WordPress have laid an essential foundation in computer science, and I still cherish and utilize WordPress frequently.

    While I still cherish and utilize WordPress, my focus on Flutter and its cross-platform capabilities offers a more modern and efficient developer experience.

    Looking forward, I may consider specializing in both Flutter and WordPress. With Flutter’s innovative toolkit and the immense market share WordPress commands, both hold promising, versatile paths in my ongoing journey of growth.