Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,9 @@ jobs:
R=$(grep -oE 'Stable tag: [0-9.]+' readme.txt | awk '{print $3}')
echo "header $H constant $C readme $R"
test "$H" = "$C" -a "$H" = "$R"
grep -q "^## \[$H\]" CHANGELOG.md || { echo "CHANGELOG.md has no entry for $H"; exit 1; }
grep -q "^= $H =" readme.txt || { echo "readme.txt changelog has no entry for $H"; exit 1; }
# Headings: "## v0.1.19 - 2026-10-04" (older ones "## [0.1.18] — …") and "= 0.1.19 - 2026-10-04 =" (or "= 0.1.18 =").
grep -qE "^## (v$H |\[$H\])" CHANGELOG.md || { echo "CHANGELOG.md has no entry for $H"; exit 1; }
grep -qE "^= v?$H( |=)" readme.txt || { echo "readme.txt changelog has no entry for $H"; exit 1; }

browser:
name: Chromium on WordPress
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

All notable changes to the MonoRanks WordPress plugin. The format follows [Keep a Changelog](https://keepachangelog.com/); versions follow [Semantic Versioning](https://semver.org/).

## v0.1.19 - 2026-10-04

- **New:** "What to do next" on the Overview: outreach, backlinks, competitors and keyword movers.
- **New:** A MonoRanks box in the post editor with search, visits, revenue and lost links for the page.
- **Enhancement:** The Posts list card shows clicks, revenue and lost links.
- **Fix:** Persian translation file header.

## [0.1.18] — unreleased

- After every write and undo, the plugin asks the active page caches to drop the page that changed, so the new title, description, canonical, noindex, alt text, opening paragraph or redirect shows right away instead of when the cache expires (#11). SEO fields and the opening paragraph purge the post's URL, plus the home page when the post is the static front page; alt text purges the post the image belongs to; a redirect purges its source URL; llms.txt and the AI crawler rules purge `/llms.txt` or `/robots.txt` as before.
Expand Down
2 changes: 1 addition & 1 deletion build/main.css

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions build/main.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions build/post-panel.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 41 additions & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,48 @@ Since 0.1.15 an SEO field (`seo_title`, `seo_description`, `canonical`, `noindex

The plugin's status, sent after connecting, on "Send content now" and daily (the same object as `GET /wp-json/monoranks/v1/status` without the user fields). `seo_plugin` is `yoast`, `rankmath`, `aioseo`, `tsf` (The SEO Framework, since 0.1.15), `other` (an SEO plugin MonoRanks cannot write into, since 0.1.15) or `none`; `seo_plugin_name` (since 0.1.15) is its name, or `""`. If MonoRanks answers 400 to a status whose `seo_plugin` is `tsf` or `other`, the plugin sends it once more with `seo_plugin: "none"`.

## What to do next and per-post data: API v1 reads

The Overview's **What to do next** cards and the **MonoRanks** box in the post editor read MonoRanks API v1 with the same key: `GET {api_base}/api/v1/sites/{site_id}/<route>`, `Authorization: Bearer <connector key>`. `site_id` is the one stored at pairing (or the overview's `site_id` for a key pasted by hand). The full shapes are in MonoRanks' `/api/v1/openapi.json`; the plugin keeps only the fields below and ignores the rest.

| Shown in WordPress | Route | Scope |
| --- | --- | --- |
| Outreach card: targets to contact, the top 3 with why | `outreach?status=to_contact&per=3` | `search:read` |
| Backlinks card: websites won and lost in 28 days, to review for spam, newest strong ones | `backlinks?view=new&per=3&sort=strength` | `search:read` |
| Competitors card: top 3 (the ones that drive gaps first), gap count, top 3 gap keywords | `competitors`, `competitors/gaps?view=gaps&per=3` | `search:read` |
| Keyword movers card: tracked keywords up and down since a week ago | `keywords?view=tracked&sort=change&dir=desc&per=10` and `dir=asc` | `search:read` |
| Latest report line | `reports?limit=1` (monoranks/monoranks#199) | `sites:read` |
| Post box and column card: visits, key events and revenue per page (28 days) | `analytics/pages?limit=1000&sort=-revenue` | `analytics:read` |
| Same, clicks only, when Google Analytics is not connected (409) | `search/rows?dimension=page&limit=1000&from=…&to=…` | `search:read` |
| Post box and column card: lost links to win back for the page | `outreach?source=lost_link&per=200` (grouped by `reason.lostTo`) | `search:read` |
| Post box: last change MonoRanks saw | `pages/history?limit=10&url=<permalink>` | `pages:read` |
| Post box: top searches for the page | `search/rows?dimension=query_page&limit=5&from=…&to=…&page=<permalink>` | `search:read` |

The 28 days end three days ago, the last day of final Search Console data, as MonoRanks uses by default.

Keys made by a WordPress pairing once monoranks/monoranks#199 is released carry `search:read` and `analytics:read` next to the three locked plugin scopes. Plugin keys paired earlier get the two scopes once, from a one-time job in the same release. If the owner unticks them, the cards say the key cannot read this yet and link to the website's Integrations screen in MonoRanks.

How each answer is used:

- `200`: shown. An empty list is shown as a plain "nothing yet" line, never as an error.
- `403 missing_scope` (or the key owner left the workspace): the card says the key cannot read it yet. The key is **not** marked revoked.
- `503 api_disabled` or `404 no_route` (an older MonoRanks): "Not available in your MonoRanks yet".
- `409 ga4_not_connected` / `ga4_no_access` on `analytics/pages`: the post box offers to connect Google Analytics and shows clicks from `search/rows` instead.
- Anything else (timeouts, `429`, `5xx`): "could not be reached", asked again within the hour.

How often:

- The cards: one pull of at most 7 calls when the Overview opens and the cache is older than six hours (one hour after a failed section), within a 12-second budget; sections it had no time for are finished by WP-Cron.
- Page values (analytics or search rows, plus lost links): at most 3 calls a day, in the background (WP-Cron) when a Posts list or the post editor opens, never while the list renders.
- The post box: 2 calls per post, when the editor opens and that post's reads are older than twelve hours (one hour after a failure). The box loads after the editor, so opening a post never waits on MonoRanks.

All of it is read in the admin only, by administrators (`manage_options`); nothing is fetched on the public site.

## Storage on the WordPress side

- Option `monoranks_insights` (not autoloaded): `status` (ok | none | unsupported | error | revoked), `fetched_at`, `overview`, `pages_synced_at`.
- Post meta `_monoranks_score` (the page row above) and `_monoranks_health` (integer, for sorting the column).
- Disconnecting or deleting the plugin removes all of it.
- Transient `monoranks_grow` (kept 3 days, fresh for 6 hours): the What to do next cards, one entry per section with its `state` (ok | empty | no_access | off | error | pending).
- Transient `monoranks_page_values` (kept 3 days, fresh for a day): per page path, clicks, impressions and position, and with Google Analytics sessions, key events and revenue; lost links per page; the currency and period.
- Transients `monoranks_post_<id>` (12 hours): the post box's last change and top searches for that post.
- Disconnecting, connecting a new key, or deleting the plugin removes all of it.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
160 changes: 149 additions & 11 deletions languages/monoranks-fa_IR-admin.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"translation-revision-date": "2026-09-30T11:29:37+00:00",
"translation-revision-date": "2026-10-04T07:14:07+00:00",
"generator": "WP-CLI/2.12.0",
"source": "resources/admin",
"domain": "messages",
Expand All @@ -8,7 +8,7 @@
"": {
"domain": "messages",
"lang": "fa_IR",
"plural-forms": "nplurals=2; plural=(n != 1);"
"plural-forms": "nplurals=2; plural=(n > 1);"
},
"No changes yet": [
"هنوز تغییری نیست"
Expand Down Expand Up @@ -215,6 +215,144 @@
"Connect": [
"اتصال"
],
"(opens in a new tab)": [
"(در زبانهٔ تازه باز می‌شود)"
],
"What to do next": [
"گام‌های بعدی"
],
"Updated %s": [
"به‌روزشده %s"
],
"The MonoRanks key of this site cannot read this yet. Allow it under Integrations in MonoRanks, or connect again.": [
"کلید مونورنکس این سایت هنوز اجازهٔ خواندن این را ندارد. در مونورنکس از بخش یکپارچه‌سازی‌ها اجازه دهید، یا دوباره متصل کنید."
],
"Open Integrations": [
"باز کردن یکپارچه‌سازی‌ها"
],
"Not available in your MonoRanks yet.": [
"هنوز در مونورنکس شما در دسترس نیست."
],
"MonoRanks could not be reached. The plugin tries again within the hour.": [
"دسترسی به مونورنکس ممکن نشد. افزونه تا یک ساعت دیگر دوباره تلاش می‌کند."
],
"Still loading. Reload this screen in a minute.": [
"هنوز در حال بارگذاری است. یک دقیقهٔ دیگر این صفحه را بازخوانی کنید."
],
"Outreach": [
"جذب لینک"
],
"%s to contact": [
"%s برای تماس",
"%s برای تماس"
],
"All targets": [
"همهٔ هدف‌ها"
],
"Every target is contacted. MonoRanks looks for new ones each week.": [
"با همهٔ هدف‌ها تماس گرفته شده. مونورنکس هر هفته هدف‌های تازه پیدا می‌کند."
],
"Sites worth asking for a link or a mention. MonoRanks never sends email; you reach out and set the status there.": [
"سایت‌هایی که ارزش دارد از آن‌ها لینک یا نام‌بردن بخواهید. مونورنکس هرگز ایمیل نمی‌فرستد؛ تماس با شماست و وضعیت را در مونورنکس ثبت می‌کنید."
],
"No outreach targets yet. MonoRanks looks for pages worth a link each week.": [
"هنوز هدفی برای جذب لینک نیست. مونورنکس هر هفته صفحه‌هایی را پیدا می‌کند که ارزش لینک‌گرفتن دارند."
],
"Backlinks": [
"بک‌لینک‌ها"
],
"All backlinks": [
"همهٔ بک‌لینک‌ها"
],
"websites linking to you, won and lost in 28 days": [
"سایت‌هایی که به شما لینک می‌دهند، به‌دست‌آمده و ازدست‌رفته در ۲۸ روز"
],
"%s website links to you": [
"%s سایت به شما لینک می‌دهد",
"%s سایت به شما لینک می‌دهند"
],
"%s to review for spam": [
"%s مورد برای بررسی اسپم",
"%s مورد برای بررسی اسپم"
],
"Newest strong links": [
"تازه‌ترین لینک‌های قوی"
],
"strength %s": [
"قدرت %s"
],
"No backlink data yet. MonoRanks refreshes it weekly.": [
"هنوز داده‌ای از بک‌لینک‌ها نیست. مونورنکس آن را هر هفته به‌روز می‌کند."
],
"Competitors": [
"رقیبان"
],
"%s keyword gap": [
"%s شکاف کلیدواژه",
"%s شکاف کلیدواژه"
],
"All competitors": [
"همهٔ رقیبان"
],
"suggested": [
"پیشنهادی"
],
"%1$s shared keyword, %2$s where they rank higher": [
"%1$s کلیدواژهٔ مشترک، در %2$s مورد بالاتر از شما",
"%1$s کلیدواژهٔ مشترک، در %2$s مورد بالاتر از شما"
],
"They rank for these, you do not": [
"آن‌ها برای این‌ها رتبه دارند، شما نه"
],
"%s/mo": [
"%s در ماه"
],
"No competitors yet. Pick some in MonoRanks to see the keywords they win.": [
"هنوز رقیبی نیست. در مونورنکس چند رقیب انتخاب کنید تا کلیدواژه‌هایی را که می‌برند ببینید."
],
"up": [
"بالا"
],
"down": [
"پایین"
],
"%1$s → %2$s": [
"%1$s ← %2$s"
],
"Keyword movers this week": [
"جابه‌جایی کلیدواژه‌ها در این هفته"
],
"All keywords": [
"همهٔ کلیدواژه‌ها"
],
"Up": [
"بالا رفته"
],
"Down": [
"پایین آمده"
],
"Your %s tracked keyword held its place this week.": [
"%s کلیدواژهٔ پیگیری‌شدهٔ شما این هفته جایگاهش را حفظ کرد.",
"%s کلیدواژهٔ پیگیری‌شدهٔ شما این هفته جایگاهشان را حفظ کردند."
],
"No tracked keywords yet. Track some in MonoRanks to see them move here.": [
"هنوز کلیدواژهٔ پیگیری‌شده‌ای نیست. در مونورنکس چند کلیدواژه را پیگیری کنید تا جابه‌جایی‌شان را اینجا ببینید."
],
"Latest client report": [
"تازه‌ترین گزارش مشتری"
],
"Latest report": [
"تازه‌ترین گزارش"
],
"Open report": [
"باز کردن گزارش"
],
"No reports yet. Create a website or client report in MonoRanks to share progress.": [
"هنوز گزارشی نیست. برای به‌اشتراک‌گذاشتن پیشرفت، در مونورنکس گزارش سایت یا مشتری بسازید."
],
"Open reports": [
"باز کردن گزارش‌ها"
],
"Connect MonoRanks": [
"اتصال مونورنکس"
],
Expand All @@ -231,12 +369,21 @@
"%s آمادهٔ اعمال",
"%s آمادهٔ اعمال"
],
"Connect Google Search Console in MonoRanks to see clicks here.": [
"برای دیدن کلیک‌ها، گوگل سرچ کنسول را در مونورنکس متصل کنید."
],
"Overview": [
"نمای کلی"
],
"Site": [
"سایت"
],
"Health score": [
"امتیاز سلامت"
],
"AEO score": [
"امتیاز AEO"
],
"Could not load the overview.": [
"بارگذاری نمای کلی ممکن نشد."
],
Expand All @@ -255,19 +402,13 @@
"Sync content now": [
"همگام‌سازی محتوا"
],
"Health score": [
"امتیاز سلامت"
],
"Technical, on-page, links, speed": [
"فنی، درون‌صفحه، پیوندها، سرعت"
],
"Site average, %s page": [
"میانگین سایت، %s صفحه",
"میانگین سایت، %s صفحه"
],
"AEO score": [
"امتیاز AEO"
],
"Answer-first, structure, entities": [
"پاسخ‌محوری، ساختار، موجودیت‌ها"
],
Expand All @@ -280,9 +421,6 @@
"From Google Search Console, through MonoRanks": [
"از گوگل سرچ کنسول، از طریق مونورنکس"
],
"Connect Google Search Console in MonoRanks to see clicks here.": [
"برای دیدن کلیک‌ها، گوگل سرچ کنسول را در مونورنکس متصل کنید."
],
"%s ready": [
"%s آماده"
],
Expand Down
Binary file modified languages/monoranks-fa_IR.mo
Binary file not shown.
Loading
Loading