DailySmith Sync
DailySmith Sync: a WordPress plugin that pulls your DailySmith blog into WordPress on a schedule. Content, SEO fields, featured images, rich-content styling. Never overwrites your own posts.
by DailySmith · github.com/technicalinsideti/dailysmith-wordpress-plugin · website
Install
The author publishes release zips, so WP-CLI can install straight from GitHub:
wp plugin install https://github.com/technicalinsideti/dailysmith-wordpress-plugin/releases/download/v0.2.0/dailysmith-sync.zipReadme
DailySmith Sync for WordPress
A WordPress plugin that mirrors a DailySmith blog into your WordPress. On a schedule (hourly by default) it polls DailySmith's public delivery API and creates or updates local posts: the rendered article, the SEO fields for Yoast SEO and Rank Math, the featured image, and the stylesheet the rich components need. It never overwrites a post it did not create.
DailySmith also has a push channel that writes into WordPress over the REST API with an application password and needs no plugin. This plugin is the pull alternative. Nothing secret is entered anywhere; the only value you type in is the site's public key. Both channels are documented at dailysmith.com/docs/wordpress.
Install
Requires WordPress 5.9 or newer and PHP 7.4 or newer.
- Download dailysmith-sync.zip (always the latest release; every release also carries a versioned copy), or build it yourself with
./build.sh. - In WordPress, go to Plugins, Add New, Upload Plugin, and activate it.
- Open Settings, DailySmith Sync. Enter your site's public key (
pk_..., from the site page in the DailySmith dashboard). Leave the API base URL alone unless you self-host DailySmith. - Press Test connection. It lists the blogs that will sync.
- Wait for the schedule, or press Sync now.
WP-Cron fires on page views. On a low-traffic site, point a real cron job at wp-cron.php so the hourly sync runs on time.
What it does
Each run walks every blog on the site and every language the blog publishes in, from the last checkpoint forward. For each post in the feed it either creates a WordPress post, updates the one it created earlier, or skips it when nothing changed upstream.
Ownership works through one custom field. Every synced post carries the DailySmith post id in _baas_post_id. Updates and takedowns go only to the post carrying the id being synced, found by that field and never by slug or title. If one of your own posts sits on a synced post's slug, WordPress gives the synced copy a suffixed slug and yours is not touched.
Once a day the plugin does a full walk and sets local copies that are no longer published in DailySmith to draft. Draft, never trash. A republish in DailySmith updates the same post again.
A blog that publishes in several languages fans one article out into a translation group. Each language arrives as its own WordPress post with its own marker and a _baas_locale field.
SEO fields land only when the plugin that reads them is installed. Yoast SEO gets _yoast_wpseo_focuskw, _yoast_wpseo_metadesc and _yoast_wpseo_title. Rank Math gets rank_math_focus_keyword, rank_math_description and rank_math_title.
The featured image is sideloaded once per hero URL and set as the post thumbnail with its alt text. A regenerated hero is a new URL and triggers exactly one new upload.
Posts that use DailySmith's rich components (callouts, steps, charts, timelines) load one stylesheet from the API, /v1/sdk/md2.css, plus the blog's palette from the sync feed. Both are scoped to the .baas-wrap wrapper, so they cannot restyle the rest of your theme. Plain posts load nothing.
Running it next to push delivery
The plugin also registers the SEO fields and the ownership marker for the REST API, which is what DailySmith's push channel needs in order to set them. Installing it replaces the must-use bridge snippet from the docs. A site running both channels converges on one WordPress post per article, because both write the same marker. If push already covers a site, turn off "Scheduled sync" in the settings and keep the plugin for the bridge and the styling.
The wire contract
The custom fields keep the _baas_ prefix (_baas_post_id, _baas_updated_at, _baas_base_path, _baas_hero_url, _baas_locale) and the content wrapper is <div class="baas-wrap md2" data-baas-theme="light">. "baas" was the product's working name. It is still what the DailySmith API writes through its push channel and what it scopes its stylesheet to. Renaming either side alone would orphan every synced post or unstyle every rich one, so both stay.
Development
| Path | What |
|---|---|
dailysmith-sync.php |
Plugin header, hook wiring, cron schedule, legacy option migration |
includes/class-dailysmith-sync-settings.php |
The two options: settings and sync state |
includes/class-dailysmith-sync-api.php |
HTTP client for the delivery API |
includes/class-dailysmith-sync-engine.php |
The sync: walk, create or update, sideload, reconcile |
includes/class-dailysmith-sync-bridge.php |
REST registration of the SEO fields and the marker |
includes/class-dailysmith-sync-assets.php |
Stylesheet and palette enqueue on synced posts |
includes/class-dailysmith-sync-admin.php |
Settings screen, Test connection, Sync now |
uninstall.php |
Removes the options and the schedule. Posts stay |
build.sh |
Lints, then zips dist/dailysmith-sync-<version>.zip |
tests/smoke/ |
End-to-end run against a real WordPress in Docker |
Lint (needs php, or docker):
find . -name '*.php' -not -path './dist/*' -print0 | xargs -0 -n1 php -l
Build the zip:
./build.sh
The smoke test starts WordPress, MariaDB and a stub delivery API as plain docker run containers, activates the plugin, syncs several fixture sites, and asserts ownership, KSES survival, the featured image, Yoast fields, update in place, takedown, front-end styling, multi-language groups and a cursor walk that survives a mid-walk edit. It takes a few minutes and pulls images from Docker Hub and Yoast from wordpress.org.
tests/smoke/run-smoke.sh
For a local WordPress, symlink or bind-mount this directory as wp-content/plugins/dailysmith-sync. The folder name must match the plugin slug.
CI and releases
Every push and pull request runs ci.yml: php -l on PHP 7.4 and 8.3, ./build.sh, and the Docker smoke test.
A release is a version bump merged to main. Set Version in dailysmith-sync.php and Stable tag in readme.txt to the same value and add a = <version> = entry under the readme's changelog; build.sh refuses to package if any of the three disagree. When CI is green on main, release.yml sees that the version has no release yet, builds the zip, and publishes a GitHub release tagged v<version> with the changelog entry as its notes and the zip attached under both its versioned name and the stable dailysmith-sync.zip. A version that is already released is left alone, so the workflow can be re-run by hand at any time. Nothing is tagged manually.
License
MIT. See LICENSE.
Read the full README on GitHub →