Tag: Best Practices

  • Customizing the Drupal Admin UI with Admin Toolbar and Beyond

    Customizing the Drupal Admin UI with Admin Toolbar and Beyond

    As a Drupal developer, one of my favorite tricks to improve both my workflow and my clients’ satisfaction is refining the Drupal admin interface. While Drupal’s default admin backend is powerful, it can be overwhelming—or a bit inefficient—out of the box. Today, I’ll walk you through practical enhancements you can make to the admin UI, focusing on the must-install Admin Toolbar module and a few other helpful tweaks.

    1. Install and Configure the Admin Toolbar Module

    The Admin Toolbar is an almost mandatory module for any serious Drupal site. It builds upon the standard Toolbar module, transforming the top navigation into a hierarchical drop-down menu that dramatically reduces clicks to access deep configuration pages.

    How to Install:

    1. Use Drush: drush en admin_toolbar admin_toolbar_tools -y
    2. Or, use Extend in the UI to enable both Admin Toolbar and Admin Toolbar Tools.

    Bonus: When working in a development or staging environment, enable admin_toolbar_search for quick admin page access. (Don’t forget to disable it in production for performance reasons.)

    2. Streamline Navigation with Shortcuts

    Customizing your shortcut bar to include most-used items (like Content, Structure, and Configuration pages) can save minutes every day. Go to Manage > Shortcuts to add or reorder relevant links. Encourage your clients to curate their shortcut sets as well!

    3. Clean Up the Dashboard

    The dashboard can be made less overwhelming by hiding or rearranging blocks. Use the Block Layout configuration in the UI or the contributed module Adminimal Admin Toolbar for a cleaner look.

    4. Use the "Coffee" Module for Power Users

    For keyboard-centric navigation, the Coffee module is a revelation: hit Alt+D+F (or Alt+Shift+D depending on your OS), start typing the name of any admin page, and jump directly there. Your admins will thank you for introducing this time-saving power tool.

    5. Simplify and Personalize the Interface

    Help editors by hiding unnecessary menu items and permissions. The Admin Menu Per Role module or careful user permissions configuration ensures each user only sees what they really need.

    In Summary:
    By taking a few minutes to install and configure key UI modules—and tailoring the admin interface to your (and your clients’) needs—you’ll make Drupal both more powerful and more pleasant to use. For me, Admin Toolbar is always the first step, but there’s so much more you can do. Happy site building!

    — Drew

  • Building Custom Gutenberg Blocks: Elevate Your WordPress Editing Experience

    Building Custom Gutenberg Blocks: Elevate Your WordPress Editing Experience

    Gutenberg, the block editor introduced to WordPress in version 5.0, fundamentally transformed how users create and manage content. While the default set of blocks covers most needs, there comes a point in every developer’s journey where custom blocks are essential for delivering unique functionality and on-brand designs. In this article, I’ll walk you through the basics of building your own custom Gutenberg block and explain best practices to ensure maintainability and performance.

    Why Create Custom Blocks?

    Custom blocks empower you to:

    • Tailor editing experiences to content creators
    • Provide reusable design components
    • Encourage brand consistency
    • Extend functionality without shortcodes

    Setting Up Your Plugin

    To get started, you’ll want to create a new plugin. Begin by setting up your plugin directory (e.g., /wp-content/plugins/my-custom-blocks/) and placing a main PHP file inside:

    <?php
    /*
    Plugin Name: My Custom Blocks
    Description: Adds custom Gutenberg blocks.
    Version: 1.0
    Author: Presley
    */
    

    Next, use register_block_type to register your block. You will need two main files:

    • block.js (for block definition and React code)
    • style.css (for block styling)

    Example: A Simple Alert Box Block

    1. Enqueue Scripts in PHP:
    function mcb_register_block() {
        wp_register_script(
            'mcb-alert-block',
            plugins_url('block.js', __FILE__),
            array('wp-blocks', 'wp-element', 'wp-editor')
        );
        wp_register_style(
            'mcb-style',
            plugins_url('style.css', __FILE__)
        );
        register_block_type('mcb/alert-box', array(
            'editor_script' => 'mcb-alert-block',
            'style' => 'mcb-style',
        ));
    }
    add_action('init', 'mcb_register_block');
    
    1. Block JavaScript (block.js):
    const { registerBlockType } = wp.blocks;
    const { RichText } = wp.blockEditor;
    
    registerBlockType('mcb/alert-box', {
        title: 'Alert Box',
        icon: 'warning',
        category: 'widgets',
        attributes: {
            message: { type: 'string', source: 'html', selector: 'div' }
        },
        edit({ attributes, setAttributes }) {
            return (
                <RichText
                    tagName="div"
                    className="mcb-alert-box"
                    value={attributes.message}
                    onChange={(message) => setAttributes({ message })}
                    placeholder="Type your message..."
                />
            );
        },
        save({ attributes }) {
            return <div className="mcb-alert-box">{attributes.message}</div>;
        }
    });
    
    1. Styling (style.css):
    .mcb-alert-box {
      background: #fff3cd;
      border: 1px solid #ffeeba;
      padding: 16px;
      border-radius: 4px;
      color: #856404;
    }
    

    Best Practices for Custom Blocks

    • Namespace your block names and CSS classes to avoid conflicts.
    • Follow WordPress coding standards in PHP and JavaScript.
    • Document your code for the benefit of other developers.
    • Test across different themes and environments to ensure compatibility.
    • Consider localization/internationalization via wp.i18n functions.

    Final Thoughts

    Custom Gutenberg blocks are a powerful way to enhance the WordPress editing experience for developers, designers, and content creators alike. Once you have the basics down, experiment with Inspector Controls, custom attributes, and server-side rendering to create sophisticated, flexible blocks.

    Have you built any unique blocks? Share your experiences and questions in the comments below!

    — Presley

  • Securing Your WordPress Site: Essential Practices for Modern Sites

    Securing Your WordPress Site: Essential Practices for Modern Sites

    As a web developer who has seen countless WordPress installs over the past decade, I can tell you that site security remains one of the most crucial and yet sometimes overlooked aspects of WordPress management. Whether you’re building a personal blog, an e-commerce platform, or a network of sites, a proactive approach to security goes hand-in-hand with performance, reliability, and user trust.

    In this article, I’ll walk you through actionable strategies to lock down your WordPress sites and help you avoid common pitfalls that could leave your site vulnerable.

    1. Keep WordPress Core, Themes, and Plugins Updated

    This is your first line of defense. Outdated core files, themes, and plugins are the most commonly exploited vulnerabilities. Enable auto-updates when possible, but always test updates in a staging environment if you’re running mission-critical or custom sites. Remove unused plugins and themes entirely—deactivated code can still be a threat.

    2. Enforce Strong Authentication

    Default usernames like “admin” and weak passwords are invitations for brute-force attacks. Choose complex passwords and enable two-factor authentication (2FA) for all user accounts. Popular plugins such as Wordfence and iThemes Security make enabling 2FA straightforward.

    3. Restrict Access and Permissions

    Apply the Principle of Least Privilege: only give users the permissions they need. For multisite networks, be especially careful with Super Admin access. Use dedicated admin accounts for site management, and encourage content creators to use Contributor or Author roles.

    4. Secure wp-config.php and Sensitive Files

    Move wp-config.php one directory above the root, and add rules to your .htaccess file to prevent direct access to sensitive files such as wp-config.php and .htaccess itself. For example:

    <files wp-config.php>
      order allow,deny
      deny from all
    </files>
    

    5. Install a Web Application Firewall (WAF)

    A WAF can block common threats like SQL injection, XSS, and unauthorized access attempts. Many reputable security plugins offer WAF features, or you can use a cloud-based proxy WAF for enhanced protection.

    6. Regular Backups and Monitoring

    No security setup is perfect. Schedule automatic backups and ensure you can restore your site quickly in case of compromise. Monitor your site’s logs for suspicious activity—plugins like WP Activity Log provide granular insights.

    7. Disable XML-RPC If Not Needed

    XML-RPC is an old protocol that can be exploited for DDoS or brute-force attacks. If you’re not using it for remote publishing or third-party apps, disable it:

    add_filter('xmlrpc_enabled', '__return_false');
    

    Final Thoughts

    Security is an ongoing process—not a set-and-forget task. By implementing these foundational practices, you’ll significantly reduce your attack surface and gain peace of mind knowing your WordPress sites are better protected.

    Have more questions about hardening your WordPress setup? Drop them in the comments below or reach out on Twitter. For more in-depth WordPress tutorials and development tips, be sure to check out my previous articles!

    — Presley

  • Managing Environment Variables in FastAPI Applications

    Managing Environment Variables in FastAPI Applications

    As a backend developer, one of the foundational best practices is to keep sensitive information such as API keys, database credentials, and configuration settings out of your codebase. Instead, we use environment variables. In this article, I’ll walk you through practical techniques for managing environment variables effectively in your FastAPI projects.

    Why Use Environment Variables?

    Environment variables provide a secure and flexible way to configure your application from outside the code. Storing secrets in version-controlled Python files risks accidental exposure and makes changing configurations across environments (development, staging, production) cumbersome.

    Loading Environment Variables

    Let’s consider a typical FastAPI setup. The two common approaches for loading environment variables are:

    1. The Standard Library (os.environ)
    2. Third-party Packages (python-dotenv, pydantic settings)

    Using python-dotenv for Local Development

    The python-dotenv package lets you define a .env file in your project root:

    DATABASE_URL=postgresql://user:pass@localhost/db
    SECRET_KEY=supersecretkey
    

    Then, load these variables at startup:

    from dotenv import load_dotenv
    import os
    
    load_dotenv()  # Loads variables from .env into the environment
    
    DATABASE_URL = os.getenv("DATABASE_URL")
    SECRET_KEY = os.getenv("SECRET_KEY")
    

    Using Pydantic Settings Management

    Pydantic (FastAPI’s favorite data validation library) provides a clean way to centralize app configuration:

    from pydantic import BaseSettings
    
    class Settings(BaseSettings):
        database_url: str
        secret_key: str
    
        class Config:
            env_file = ".env"
    
    settings = Settings()
    

    You can then import settings wherever you need configuration values. This method also validates the types of your environment variables and falls back to system os.environ if needed.

    Injecting Settings into FastAPI Dependencies

    A tidy way to use settings in your app is via dependency injection:

    from fastapi import Depends, FastAPI
    
    app = FastAPI()
    
    def get_settings():
        return settings
    
    @app.get("/info")
    def read_info(settings: Settings = Depends(get_settings)):
        return {"db": settings.database_url}
    

    This technique brings testability and configurability to your endpoints.

    Summary Tips

    • Never commit your .env file if it contains secrets. Add it to .gitignore.
    • Leverage Pydantic settings for type safety and validation.
    • Use dependency injection to make config available wherever you need it.

    Managing environment variables well sets the foundation for robust, secure FastAPI services—whether you’re running locally or deploying to production.

    Happy coding!

    — Fast Eddy