今日已更新 256 条资讯 | 累计 40701 条内容
关于我们

标签:#word

找到 97 篇相关文章

开发者

WordPress Sitelerini Yavaşlatan 7 Yaygın Hata

WordPress sitelerinde hız problemi yaşandığında genellikle ilk refleks bir cache eklentisi kurmak oluyor. Bazen gerçekten fark yaratıyor, bazen de PageSpeed puanı biraz yükselmesine rağmen site hâlâ yavaş hissettiriyor. Bunun nedeni WordPress performansının tek bir ayardan oluşmaması. Hosting, tema, eklentiler, görseller, JavaScript dosyaları ve veritabanı aynı anda sayfanın yüklenme süresini etkileyebiliyor. Bu nedenle bir siteyi hızlandırmaya başlamadan önce asıl problemin nerede olduğunu bulmak gerekiyor. WordPress projelerinde sık karşılaştığım 7 performans hatasını aşağıda topladım. Gereğinden büyük görseller kullanmak En sık karşılaştığım problemlerden biri bu. Sayfada 700 piksel genişliğinde görüntülenecek bir görselin 4000-5000 piksel olarak yüklenmesi oldukça yaygın. Özellikle yüksek çözünürlüklü stok fotoğraflar doğrudan WordPress'e yüklendiğinde tek bir görsel birkaç megabayta ulaşabiliyor. Bu da özellikle mobil bağlantılarda ciddi yük oluşturuyor. Görselleri yüklemeden önce kullanılacağı alana uygun boyuta getirmek, sıkıştırmak ve mümkün olduğunda WebP veya AVIF gibi modern formatları tercih etmek önemli. Ancak yalnızca dosya formatını değiştirmek yeterli değil. 4000 piksel genişliğindeki bir görseli WebP'ye çevirmek, görselin gereğinden büyük olduğu gerçeğini değiştirmiyor. Her problemi cache eklentisiyle çözmeye çalışmak Cache WordPress performansında önemli bir yere sahip. Fakat cache eklentisi kurmak her hız problemini ortadan kaldırmaz. Sunucu geç cevap veriyorsa, çok fazla JavaScript çalışıyorsa veya veritabanında ağır sorgular varsa cache yalnızca problemin bir bölümünü gizleyebilir. Ayrıca aynı anda birden fazla optimizasyon eklentisi kullanmak da başka sorunlara yol açabiliyor. Örneğin bir eklentide JavaScript erteleme, başka bir eklentide tekrar JavaScript optimizasyonu ve hosting panelinde üçüncü bir optimizasyon sistemi açıldığında hangi ayarın ne yaptığını takip etmek zorlaşıyor. Ben mümkün olduğunca tek bir ana cache sistemi üzerinden ilerl

2026-08-11 原文 →
开发者

How to Secure Your WordPress Dashboard and Prevent Clients from Breaking Their Sites

A guide on using Admin Extension Access Control to lock down WordPress plugins and prevent unauthorized changes. How to Secure Your WordPress Dashboard and Prevent Clients from Breaking Their Sites If you are a freelance web developer or run an agency, you have probably experienced the dread of a client accidentally bringing down their WordPress site. You spend weeks building a robust, performant website, only for an unauthorized user to log into the dashboard, start deactivating essential plugins, or install poorly coded extensions that break everything. WordPress is fantastic because of its flexibility, but out of the box, any Administrator can touch everything . To solve this problem, I want to introduce a lightweight solution: Admin Extension Access Control . What is Admin Extension Access Control? Admin Extension Access Control is a WordPress plugin designed to give you granular control over who can see, modify, install, or delete plugins on your site. Built for modern environments (PHP 8.1+ and WordPress 6.0+), it allows you to configure strict role-based access rules without writing custom PHP functions in your functions.php file every time. Key Features Global Lockdown : Completely remove the plugins page for specific user roles. Granular Permissions : Restrict the ability to add, delete, activate, deactivate, or install plugins on a per-role basis. Exempt Users Whitelist : Designate trusted administrators (like yourself) who bypass all lockdown rules. Only exempt users can configure the access control settings. Dashboard Cleanup : Hide the plugins menu item from unauthorized users to keep the dashboard less confusing for clients. How It Works Once installed and activated, the user who activates the plugin is automatically added to the Exempt Users list. This prevents you from accidentally locking yourself out. From the settings panel, you can select which roles should be restricted from managing plugins. For example, you can give your client an "Administrat

2026-08-10 原文 →
开发者

Excited to finally join DEV!

👋 Hello DEV Community! I'm excited to finally join DEV! I'm a developer, entrepreneur, and lifelong learner who enjoys building practical web solutions with WordPress, PHP, and modern web technologies. Over the past few years I've been working on: 🚀 WordPress plugins and starter websites 💻 Affordable web solutions for individuals and small businesses 📈 Web analytics and digital marketing tools 🌱 Exploring software architecture, clean code, and open-source development I'm also building and experimenting with digital products that solve real-world problems while documenting what I learn along the way. Here you'll find posts about: WordPress development PHP programming Building and launching web products Software engineering lessons Productivity and business insights for developers Occasionally, mathematics and calculus when it connects to programming or analytics I'm looking forward to learning from this amazing community, contributing where I can, and connecting with fellow developers. Thanks for having me! 😊

2026-08-07 原文 →
AI 资讯

Passwords Are Losing, and the Numbers Finally Prove It

What the report found The FIDO Alliance — the industry group behind the passwordless authentication standard — released its State of Passkeys 2026 report in May, based on research across 11,000 consumers and 1,400 enterprise decision-makers in ten countries. A few numbers stand out: passkeys now see a 93% sign-in success rate compared to 63% for passwords, and average sign-in time drops to roughly 8.5 seconds versus over 30 seconds for password-based logins. Awareness has also jumped to 90% of consumers, with about 5 billion passkeys now active worldwide. The security case is the more important one. Passkeys are built to be phishing-resistant by design — unlike a password, there’s no shared secret that can be typed into a fake login page, because the credential is cryptographically tied to the real site and your device. That’s a structural fix, not a behavioral one — it doesn’t depend on you spotting a scam email, which is precisely where most password-based breaches start. Why adoption still lags Here’s the more interesting number: even among organizations that have rolled out passkeys, the majority still keep passwords running in parallel as a fallback, and a large share of individual users still don’t use passkeys everywhere they’re offered. The barrier at this point isn’t awareness — it’s habit. People default to what’s familiar, even when the safer option is one tap away. The practical takeaway Most major platforms — Google, Apple, Microsoft, and a growing list of banks and retailers — now offer passkeys as a login option, usually sitting quietly in account security settings labeled “passkey” or “sign in without a password.” The action worth taking today: pick your two or three most important accounts (email first, since it’s the recovery path to everything else) and set up a passkey where it’s offered, instead of waiting for a breach to force the decision. Passkeys aren’t foolproof — device loss and account-recovery flows are still an active area of security r

2026-08-06 原文 →
AI 资讯

How to Actually A/B Test AI Avatar vs. Text Chat Conversion (A Technical Approach)

Following up on a common claim in the AI avatar space — that voice/video avatars convert better than plain text chat — there's surprisingly little rigorous testing behind it. If you're building or embedding one of these widgets, here's a practical way to actually measure it instead of trusting vendor case studies. Why This Is Harder Than a Normal A/B Test Standard A/B testing swaps one variable (a button color, a headline) while holding everything else constant. Avatar vs. text chat isn't that clean — you're changing interaction modality, response latency expectations, and visual real estate simultaneously. You need to isolate the variable that actually matters: does voice/video presence drive conversion, independent of the underlying conversation quality? A Cleaner Experimental Setup javascript // Pseudocode for variant assignment function assignVariant(sessionId) { const hash = hashSessionId(sessionId); return hash % 2 === 0 ? 'avatar' : 'text'; } Key controls to hold constant across both variants: Same LLM backend and prompt/knowledge base — the conversation logic shouldn't differ, only the presentation layer Same lead capture form and CTA placement — don't let UI differences beyond avatar-vs-text confound the result Same traffic source — segment by acquisition channel if traffic mix varies, since paid vs. organic visitors convert differently regardless of chat UI Minimum sample size before evaluating — novelty effects are real; running this for 3 days will overstate the avatar's lift. Run for at least 2-3 weeks to let novelty decay. Metrics to Track (Not Just Conversion Rate) Conversion rate alone hides why one variant wins or loses: session_start_to_first_message (engagement friction) message_count_per_session (depth of interaction) time_to_form_completion (avatar/video adds latency — does it cost or gain time?) bounce_rate_before_first_response lead_quality_score (if you can grade downstream — a lead isn't a conversion if it's junk) A common finding worth watc

2026-08-05 原文 →
AI 资讯

When "select all" checkboxes don't actually select anything — verifying after `check()`, not just trusting it

WordPress's plugin and theme update screens both have a "select all" checkbox. Calling check() on it with Playwright succeeds — no error, no exception. But look at the individual checkboxes afterward, and sometimes none of them are actually checked. Note: Playwright's check() ticks a checkbox. The click itself can succeed even if the page's JavaScript handler never fires, leaving what the form actually submits out of sync with what the screen visually shows. What actually happens The "select all" checkbox is usually wired up with a JavaScript handler: clicking it is supposed to check every individual checkbox underneath it. Playwright's check(force=True) can force the DOM state of that one checkbox — but that only changes that checkbox's own state . It doesn't guarantee the JavaScript handler that's supposed to propagate the change to the individual checkboxes actually fires. # Looks like it worked, but the individual checkboxes are still unchecked select_all . first . check ( force = True ) page . click ( ' input[type= " submit " ][name= " upgrade " ] ' ) Clicking the update button submits whatever the form's actual state is — which is "nothing checked." Nothing updates. No error is thrown, so on the surface it looks like the run completed normally. The fix — verify right after checking, every time Right after checking "select all," confirm that the individual checkboxes underneath are actually checked. If they aren't, fall back to checking each one individually. sel_all_sel = ' input[type= " checkbox " ][id^= " plugins-select-all " ] ' select_all = plugin_form . locator ( sel_all_sel ) if select_all . count () > 0 : select_all . first . check ( force = True ) page . wait_for_timeout ( 500 ) # Verification step — confirm checkboxes are actually checked chk_sel_check = ' input[type= " checkbox " ][name= " checked[] " ]:checked ' any_checked = plugin_form . locator ( chk_sel_check ). count () > 0 if not any_checked : # Select-all had no effect; switch to individual s

2026-08-04 原文 →
AI 资讯

When `update-core.php` version scraping goes wrong — telling a plugin version number apart from WordPress core

On hosting without SSH access, a common pattern is to open update-core.php (the WordPress update screen) with Playwright and read "what version is WordPress core currently running" straight off the page text. In one deployment, the recorded core version came back as something like 1.7.11 — a number that has never existed for WordPress core. Note: update-core.php is the WordPress admin's "Updates" page, listing pending updates for core, plugins, themes, and translations all on one screen. What was actually happening That page doesn't only show the core version string — it's packed with version numbers belonging to pending plugin and translation updates too. A line like "Update Plugin X to 1.7.11" is typical. # First implementation — grabs the first N.N.N-shaped number on the page match = re . search ( r ' \d+\.\d+(?:\.\d+)? ' , page_text ) version = match . group ( 0 ) if match else None This naive regex grabs whatever N.N.N -shaped number appears first on the page. Because of how the page is laid out, a plugin's pending update can render above the core version message, so 1.7.11 (a plugin's version) ended up recorded as the WordPress core version. Why this is hard to catch The bug doesn't throw an exception — the regex matches successfully, just on the wrong value. Nothing about it looks broken until someone notices the report shows a version that WordPress core has never shipped (there's no 1.x series for core). The fix — a three-stage guard Prefer a dedicated selector first — look for specific DOM locations where core's update message actually renders, like p.response > strong or #wp-version-message strong Fall back to keyword-anchored regex — if no selector matches, only accept a number immediately following the words "WordPress," "バージョン," or "Version" Validate plausibility as a final check — whichever path produced a value, run it through a function that checks the major version number falls within 4–9 def is_plausible_wp_core_version ( ver : str ) -> bool : m =

2026-08-03 原文 →
AI 资讯

Migrating 10 WordPress Sites to Cloudflare Pages: What Broke

A few months ago I moved a batch of WordPress sites off a shared LAMP host and onto Cloudflare Pages as static exports. The pitch is obvious: no PHP process to keep patched, no MySQL to babysit, effectively free hosting, and a CDN in front of everything by default. What the pitch doesn't tell you is how many small, boring things break on the way there. This post is a rundown of what actually went wrong migrating a set of ten WordPress sites — one of them is burningtribe.tokyo , which I'll use as the concrete example — and how I fixed each issue. The approach The migration itself is conceptually simple: crawl the live WordPress site, save every URL as a static HTML file plus its assets, and serve that tree from Cloudflare Pages. I used a combination of wget --mirror and a custom crawler for a couple of sites where wget choked on query-string-based pagination. The static output then gets pushed with wrangler pages deploy . No build step, no framework, just files. That simplicity is exactly why it seemed low-risk. It was not. Problem 1: relative canonical tags pointed everything at the homepage The first thing I noticed after deploying was that Google Search Console started reporting most inner pages as "duplicate, Google chose different canonical" — and the canonical it picked was the homepage. The cause was almost funny once I found it: the WordPress theme emitted <link rel="canonical" href="/"> as a relative path in a few cached page fragments, instead of an absolute URL like https://burningtribe.tokyo/some-post/ . On the original WordPress install this didn't matter because the page itself resolved the relative reference correctly at the point of caching. Once the HTML was frozen and served statically from a different origin structure (Pages serves everything from the apex), that relative canonical collapsed to the site root for every single page that had it. The fix was a straightforward but tedious pass: grep every exported HTML file for rel="canonical" , and rew

2026-08-03 原文 →
AI 资讯

Essential WordPress Plugins Every New Website Needs (And Which Ones to Avoid)

When you first install WordPress, it is easy to think that every popular plugin will improve your website. After all, the WordPress plugin directory contains tens of thousands of plugins, each promising better SEO, stronger security, faster performance, or beautiful design. That is exactly where many beginners make their first mistake. A new website does not need 30, 40, or 50 plugins. Every plugin you install adds more code that must be maintained, updated, and secured. While the number of plugins alone does not determine performance, unnecessary or poorly coded plugins increase the chances of conflicts, slowdowns, and security issues. Security experts also continue to report that plugins account for the overwhelming majority of WordPress vulnerabilities. The better approach is simple. Install only the plugins that solve an essential problem. Choose one high quality plugin for each task, avoid duplicates, and ignore everything else until you actually need it. Here are the only five to six plugins that most brand new WordPress websites need. The Minimalist Plugin Rule Before installing anything, remember this simple rule: One plugin, one job. If one plugin already handles SEO, you do not need another SEO plugin. If one caching plugin is active, never install a second one. If your hosting company already performs automatic backups, you may not need a backup plugin running every day. Keeping your plugin list small makes your website easier to manage, faster to update, and less likely to develop compatibility problems. An SEO Plugin Recommended: Rank Math SEO or Yoast SEO Every website needs an SEO plugin. Without one, you miss important features such as: XML sitemaps Meta titles and descriptions Search engine indexing controls Schema markup Social sharing previews For beginners, Rank Math's free version includes a generous feature set, while Yoast SEO remains one of the most established and beginner friendly alternatives. Either option works well. The important rule i

2026-08-02 原文 →
AI 资讯

How to Safely Update WordPress Plugins and Themes Without Breaking Your Site

If you've ever delayed updating your WordPress plugins or themes because you were afraid something might break, you're not alone. Many beginners avoid updates for weeks or even months because they've heard horror stories about websites crashing after a single click. Others do the exact opposite. They click "Update All" without preparing, then panic when their homepage displays an error or their layout suddenly changes. The good news is that updating WordPress doesn't have to be risky. With a simple maintenance routine, you can keep your website secure, stable, and running smoothly without the fear of losing your content. In this guide, you'll learn how to create reliable backups, update safely, test your website after every change, and recover quickly if something goes wrong. Why You Should Never Ignore WordPress Updates Updates exist for a reason. Plugin developers, theme creators, and the WordPress core team regularly release updates to: Fix security vulnerabilities Patch software bugs Improve compatibility with newer versions of WordPress and PHP Add useful features Improve website performance Running outdated plugins or themes leaves your website exposed to known security issues. In many cases, attackers specifically target websites that haven't been updated. At the same time, installing every available update without preparation isn't the answer either. A single incompatible plugin or poorly coded update can create conflicts that affect your website. The goal isn't to update everything as quickly as possible. The goal is to update carefully and confidently. A Safe WordPress Update Routine Follow this routine every time you update your website. Step 1: Create an Automatic Off-Site Backup Before changing anything, make sure you have a complete backup stored somewhere other than your web hosting account. If your hosting server experiences problems, a backup stored on the same server may not help. Instead, configure automatic backups to services such as: Google Dri

2026-08-02 原文 →
AI 资讯

60 AI-written WordPress plugins, and JavaScript escaping that is safe by accident

This post has two halves: what "escape your output" actually means once the obvious answer stops working, and then a study of whether current AI assistants get that harder version right. It continues a series on what coding assistants actually produce when a non-expert asks them for WordPress code. Start with a line that passes review and still leaves a hole: echo '<a href="' . esc_html ( $url ) . '">Visit</a>' ; There is an escaping function wrapped around the value. A grep for esc_ finds it. A quick review passes it. Now set $url to javascript:alert(document.cookie) . The link still runs when the visitor clicks it. esc_html() escapes characters that matter in HTML text, like < and > . It does nothing about a dangerous URL scheme. The code is escaped. It is escaped for the wrong context. From the outside, correct escaping and wrong-context escaping look identical. A URL is a different context and needs its own escaper. That escaper is esc_url() , and it returns an empty string for a javascript: URL. Which escaper goes where Escaping is context-dependent. "Sanitize on input, escape on output" is the rule the first post of this series covers, but "escape on output" hides a second decision: which escaper. The answer depends on where the value lands on the page. Where the value lands Escaper Visible text between tags ( <p>HERE</p> ) esc_html() Inside an attribute ( title="HERE" ) esc_attr() A URL slot ( href="HERE" , src="HERE" ) esc_url() , which also enforces a safe scheme Inside a tag attribute that holds JavaScript ( onclick="greet('HERE')" ) esc_js() , scoped to this slot by core's own documentation Any value handed to JavaScript inside a <script> block ( var data = HERE ) wp_json_encode() , which writes its own quotes; add JSON_HEX_TAG when the value is untrusted HTML you want to keep, like a formatted post body wp_kses() with an explicit allow-list Six functions, one job each. The mistake is almost never "forgot to escape". It is "escaped for the wrong context",

2026-08-02 原文 →
AI 资讯

Your A/B test has three goals and they disagree. Now what?

Every A/B testing tutorial ends the same way: run the test, wait for significance, ship the winner. Then you run a real test and variant B converts 12% better on newsletter signups, brings in 4% less revenue per visitor, and bounce is flat. Nothing is significant except the signups. Ship it? I spent an embarrassing amount of time on this question while building an A/B engine, and most of what I read online didn't help, because most of it assumes one metric. This post is what I ended up with. It's not novel — the statistics are decades old — but I couldn't find it written down in one place with working code, so here it is. Why the p-value doesn't answer the question you're asking Two problems, and the second one is the bad one. Multiple comparisons. Three metrics at α = 0.05 means roughly a 14% chance of at least one false positive if nothing is actually different. Bonferroni fixes this, but now you need α = 0.017 per metric and your test needs to run three times as long. On a site doing 300 conversions a month that's not a fix, it's a refusal. The p-value is answering a different question. It tells you the probability of your data assuming no difference exists. What you actually want to know is: if I ship B, how much do I expect to lose if I'm wrong? Those are not the same question and no amount of Bonferroni turns one into the other. There's also the peeking problem — everyone checks the dashboard daily and stops when it goes green, which quietly inflates the false positive rate well past whatever α you wrote down. I'll come back to that, because Bayesian methods do not magically solve it, whatever you may have read. Posterior first, decision second For a conversion rate, the Beta-Binomial conjugate pair gives you the posterior in one line. With a uniform prior, after c conversions out of n visitors: p | data ~ Beta ( 1 + c , 1 + n - c ) That's it. No closed-form comparison between two Betas that's worth implementing, so sample. PHP has no Beta sampler in core, and

2026-08-02 原文 →
开发者

What "18 years in web dev" actually means when your clients are small businesses, not startups

Most dev-to content about longevity comes from people who scaled one product for a decade. My version of 18 years is different: 235+ separate small projects, each with a different client, budget, and expectation. That produces a completely different set of lessons. Every project restarts the trust clock. In a startup, trust compounds — the team, the codebase, the client relationship all carry forward. In agency work for small businesses, you start from zero credibility on every single engagement. The client has no idea if you're competent until you prove it, usually within the first draft. That reality shaped how we scope: front-load a visible win early, even a small one, rather than saving the "impressive part" for the end. Most client requests aren't really about the website. "Can we change the homepage headline" is often actually "I'm nervous this won't generate leads" or "my business partner didn't like it." Treating every request as a literal design brief instead of what it's actually about leads to a lot of pointless revision cycles. Asking one clarifying question — "what's this in response to?" — before touching the page has cut our revision count more than any process change. Consistency beats innovation for this client base. A small business owner doesn't want a novel UX pattern. They want their site to look like the successful competitor's site, load fast, and not embarrass them. Chasing design trends for this audience is optimizing for the wrong judge — they're not evaluating craft, they're evaluating "does this look like it'll work." The real skill is saying no to the wrong project, not saying yes to more of them. Early on I took every lead. Now the highest-leverage thing I do is a 10-minute pre-call that filters out projects where the client's expectations and budget don't match — before either of us spends real time on it. That single filter has done more for margin than any pricing change. None of this shows up in a portfolio. But if you're a develope

2026-08-01 原文 →
AI 资讯

🛡️ Building AbilityGuard: Monitoring the WordPress Abilities API in Production

A few weeks ago I wrote about the WordPress Abilities API — what it is, why WordPress 6.9 shipped it, and what it means for how plugins will talk to each other and to AI agents going forward. That post was theory. This one is the part where theory meets a composer.json file and a stubborn bug at 1 AM. This is the story of building AbilityGuard — a plugin that monitors Abilities API usage in production, so you actually know what's happening when abilities get registered, called, and (occasionally) abused. 👀 Why monitoring, and why now Here's the thing about the Abilities API that got me nervous the first time I really understood it: it's a capability surface . Any plugin can register an ability. Any authorized caller — a human-triggered action, an automation, or increasingly, an AI agent — can invoke one. That's the whole point of the API, and it's genuinely exciting. But it also means your site now has a growing list of "things that can be done to it programmatically," and most WordPress admins have zero visibility into that list. I've spent enough years debugging WordPress sites in production to know what happens when you can't see something: you find out about it during an incident, not before. Slow queries, rogue cron jobs, plugin conflicts — they all follow the same pattern. Nobody notices the small thing until the small thing becomes the outage. So the idea for AbilityGuard was simple: give site owners a dashboard and a log for every ability registered on their site, every time one gets called, and by whom. Not another abstract "security scanner" — just honest, readable visibility into a part of WordPress that's brand new and mostly invisible right now. 🔌 Where I started: hooking into the registry, not fighting it The Abilities API exposes a central registry ( wp_get_ability_registry() under the hood, with helper functions layered on top). My first instinct was to intercept ability calls by wrapping core functions — and I killed that idea within the hour. Wrapp

2026-07-30 原文 →
AI 资讯

Why scheduled posts don't publish on time — inspecting WP-Cron with WP-CLI

A post scheduled to publish at a specific time doesn't go live when expected. A plugin's recurring email notification never arrives. This tends to happen on low-traffic sites, and there's a specific reason for it. Note: WP-Cron is WordPress’s built-in scheduling system. It sounds like the OS-level cron daemon, but the underlying mechanism is quite different. WordPress’s WP-Cron doesn’t work like a real OS cron daemon. On every page load, WordPress checks whether any scheduled task is past its due time and, if so, runs it. This is what's known as "pseudo-cron" — and its weakness is that nothing runs without a page visit . Schedule a post to publish at 3am on a site with little overnight traffic, and the publish task can sit unexecuted until the next visitor happens to load a page. WP-CLI lets you look inside this otherwise invisible system and run exactly the task you need, right now. Listing what's scheduled wp cron event list hook next_run_gmt recurrence publish_future_post 2026-06-20 03:00:00 - wp_version_check 2026-06-20 06:12:00 12 hours wp_scheduled_delete 2026-06-21 00:00:00 daily hook is the task's identifier, next_run_gmt is the next scheduled run time in UTC, and recurrence is the repeat interval. If publish_future_post is still listed despite its time having already passed, that confirms the task is overdue simply because no page load has triggered it yet. Running a task right now To trigger a specific task immediately: # Run a specific hook right now wp cron event run publish_future_post # Run every overdue task at once wp cron event run --due-now --due-now finds every task whose scheduled time has passed but hasn't run yet, and executes all of them. Instead of waiting for a visitor to trigger the check, this one command runs the post publish, the email notification, or whatever else is pending. Confirming WP-Cron itself is working wp cron test This checks whether the WP-Cron scheduler is functioning at all. On sites where wp-config.php has define('DISABL

2026-07-30 原文 →
AI 资讯

Latency Is the Real UX Problem in AI Avatars, Not the Voice

Everyone evaluating AI avatar platforms focuses on voice quality. The bigger UX killer is almost always latency — and it's a harder problem than picking a good TTS provider. Where the delay actually comes from: User speaks/types → STT (if voice input) → LLM generates response (streaming helps, but first-token latency matters) → TTS converts text to audio → Audio playback + lip-sync rendering Each hop adds latency. A naive implementation that waits for the full LLM response before starting TTS can easily hit 2-4 seconds of dead air — long enough for a user to assume the bot is broken. How production systems actually solve this: Token streaming into TTS — start synthesizing audio on partial LLM output (sentence-by-sentence chunks) instead of waiting for the full response Speculative rendering — start lip-sync animation slightly ahead of audio using predicted phoneme timing WebSocket/SSE persistent connections — avoid the overhead of repeated HTTP round-trips per turn Regional API routing — TTS/LLM provider latency varies a lot by user geography; this matters more than most benchmarks show A practical note: platforms that advertise "real-time" avatars but load all logic behind a single request/response cycle will feel noticeably worse than ones built around streaming pipelines, even if they use the identical LLM and TTS providers underneath. If you're evaluating a platform (or building one), test with realistic network conditions, not office wifi — that's where the architecture differences actually show up. Bottom line: the voice provider matters less than people think. The orchestration around it — how aggressively you stream and pipeline each stage — is what separates a "wow" demo from a production-ready conversational agent.

2026-07-30 原文 →
AI 资讯

Locked out of wp-admin? Why WP-CLI works when `wp-login.php` doesn’t

A forgotten password, a security plugin that blocked your own IP by mistake, a plugin bug that turns the admin screen white — the causes vary, but the result is the same: you can’t log in to wp-admin. Note: WP-CLI is a command-line tool for managing WordPress, invoked as wp . It operates directly on the server, without going through a browser. This is exactly the situation where WP-CLI is useful. It works here because it never touches wp-login.php — it reads and writes the WordPress database and filesystem directly, so a broken login screen doesn’t affect it at all. Why WP-CLI keeps working when wp-admin doesn't A normal login follows the path: browser → wp-login.php → authentication → wp-admin. If anything along that path is broken — a plugin throwing a fatal error during authentication, a security plugin blocking your IP, a fatal error in the admin theme — the login itself can’t complete. WP-CLI connects over SSH and reads/writes the wp_users and wp_options tables (and the filesystem) directly. The code in wp-login.php is never executed, so problems on that path don’t matter. This does require that SSH access itself still works — on most hosting providers, SSH is a separate access path from the admin dashboard, so it usually still works even when wp-admin doesn’t. Scenario 1: Forgotten password # List administrator accounts wp user list --role = administrator --fields = ID,user_login,user_email # Overwrite the password directly wp user update 1 --user_pass = 'a-strong-new-password' wp user update writes the new password directly to the database row — no password-reset email, no token, no waiting on a delivery that might land in spam or not arrive at all. Scenario 2: A security plugin blocked your own IP Login-attempt-limiting plugins occasionally misclassify legitimate activity as an attack and add the working IP to a block list. # Deactivate the plugin responsible for the block wp plugin deactivate <plugin-causing-the-lockout> # Re-enable it later, after reviewin

2026-07-29 原文 →
AI 资讯

WordPress Plugin Cross Post for Dev.to: my solution to abandoned and unmaintained plugins

I’ve released Cross Post for Dev.to , a WordPress plugin that mirrors a post to Dev.to the moment you publish it on your own site. The plugin itself is simple: one hook, one API call, one published mirror. The interesting part of this release isn’t the feature. It’s what had to be true for a zero-dependency plugin to stay trustworthy over time without me babysitting it. The problem Most small WordPress plugins rot over time. They’re built against whatever WordPress version happens to be current, they lean on a third-party library or two to save time, and neither the plugin nor the library gets revisited until something breaks. Usually a major WordPress release, sometimes a PHP version bump. At that point the maintainer generally abandons the project and so many of these lesser used plugins become useless for users. Cross-Post for Dev.to needed to cross-post reliably from WordPress to Dev.to without letting that happen so easily. No bundled third-party SDKs, no external service sitting between the plugin and the Dev.to API, no dependency that could go unmaintained while the plugin using it kept shipping. Why zero-dependency isn’t the whole answer Removing dependencies fixes one kind of rot but not the other. A plugin with no third-party packages can still quietly break against a new WordPress release; deprecated hooks, changed REST behaviour, PHP version drift. Zero dependencies means less that can fail underneath you; it says nothing about whether the plugin still works today. Those are two different guarantees, and conflating them is how “lightweight” plugins end up just as unmaintained as heavy ones, only with fewer visible warning signs. So the actual problem wasn’t “avoid dependencies.” It was “know, continuously and automatically, whether this plugin still works”. Which is a validation problem, not a packaging problem. The validation loop Two layers of the same idea, one local and one continuous. Locally , a pre-push hook runs before any commit leaves my machin

2026-07-28 原文 →
AI 资讯

Why phpMyAdmin migrations break plugin settings — and why `wp search-replace` doesn’t

After a domain migration or HTTPS switch, "all plugin settings are gone" or "Elementor layouts are broken" is a common outcome. The cause, in most cases, is running a string replacement against the WordPress database without accounting for PHP serialized data. WordPress stores plugin configurations, custom field values, and widget settings in PHP’s serialized format. Standard SQL replacements — phpMyAdmin’s find-and-replace, raw UPDATE statements, sed on a .sql dump — rewrite the string value without updating the length metadata that serialization embeds alongside it. The result is a database that appears intact but returns false on every read of the affected values. wp search-replace handles this correctly. Understanding why makes the pre- and post-execution steps more deliberate. What PHP serialization stores alongside the value A serialized entry in WordPress looks like this: a : 2 : { s : 4 : "home" ; s : 22 : "http://example.com/top" ; s : 5 : "title" ; s : 8 : "My Site" ;} The segment s:22:"http://example.com/top" means "a string of 22 bytes." The s:N: prefix records the byte length. When a simple string replacement changes http://example.com to https://example.com : Before: s:22:"http://example.com/top" (22 bytes) After: s:22:"https://example.com/top" (23 bytes) The s:22 stays unchanged even though the actual string is now 23 bytes. PHP’s unserialize() detects this mismatch and returns false . The plugin reads false instead of its configuration array and behaves as though the settings were never saved. phpMyAdmin’s find-and-replace executes a SQL UPDATE at the storage layer. No PHP context exists there — it can’t know the column contains serialized data, and it doesn’t adjust the length prefix. How wp search-replace handles it wp search-replace operates at the PHP layer, not the SQL layer: Reads each column value Checks whether it’s serialized using is_serialized() If serialized: calls unserialize() to expand it into a PHP array or object Applies the string r

2026-07-28 原文 →