TECHI Reviews
WordPress plugin — structured product reviews for TECHi.com
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/irfanra/techi-reviews/archive/refs/heads/main.zipA self-contained WordPress plugin that stores product review scores as structured, sortable, schema-ready data for TECHi.com — not stuck in paragraphs.
What It Does
- Registers a
techi_reviewcustom post type (public, archive, block editor, REST) with a hierarchicalreview_categorytaxonomy. - Adds a hand-built meta box (no field framework) for: product name, score (0–10, one decimal), verdict (140 chars), price in PKR, review date, and repeatable pros/cons.
- Prepends a designed score card to single reviews via
the_content, confined to single review pages only (never excerpts, feeds, or other post types). - Outputs valid schema.org Review JSON-LD in
<head>. - Exposes
GET /wp-json/techi/v1/reviews— paginated, withcategory,min_score,orderby,order,search,page,per_page(capped at 50), each validated and sanitized. - Provides a Tools screen to seed and delete 25 synthetic reviews (nonce + capability checked).
Installation
- Copy the
techi-reviewsfolder intowp-content/plugins/. - In the WordPress admin, go to Plugins and activate TECHi Reviews.
- Go to Settings → Permalinks and click Save Changes (or ensure a non-Plain permalink structure is selected). This is required for the custom post type's single pages and archive to resolve.
- (Optional) Go to Reviews → Tools and click Seed 25 Reviews for instant demo data.
Versions Tested
- WordPress 6.x
- PHP 8.2 (via XAMPP)
- Theme: Twenty Twenty-Five (default block theme)
Done
- Custom post type + hierarchical taxonomy, rewrite rules flushed on activation only.
- All seven meta fields with a custom editor UI, per-field sanitization, nonce + capability checks, autosave skip.
- Repeatable pros/cons stored as separate meta rows (queryable), with a delete-then-add save pattern and whitespace-only entries filtered out.
- Score card via
the_content, confined withis_singular+in_the_loop+is_main_query+!is_feed. - Valid schema.org Review JSON-LD (verified in Google's Rich Results Test).
- REST endpoint with validated/sanitized args,
min_scorerange validation, enum-whitelistedorderby/order,per_pagecap, pagination headers, explicit publicpermission_callback. - Tools screen: seed + delete synthetic reviews, admin-only, nonce protected.
Stretch (all done)
- Sortable Score column in the admin Reviews list.
- Transient caching on the REST endpoint, invalidated on save and delete.
[techi_review_grid]shortcode with vanilla JS category filtering that degrades gracefully (reviews render server-side without JS).
Not Done / Known Limitations
- The plugin uses inline styles for the score card and grid rather than an enqueued stylesheet, to keep the submission self-contained and readable. In production these would move to a proper CSS file via
wp_enqueue_style. - Requires a non-Plain permalink structure (noted in install steps).
Key Decisions
-
Review date as a custom meta field, not the publish date. The brief lists "review date" under meta, and separating it from the publish date lets the editorial review date differ from when the post goes live.
-
Repeatable pros/cons stored as multiple meta rows (not a serialized string). Using
add_post_metawithout the unique flag makes each entry an individual, queryable row, retrievable directly as an array — cleaner than splitting a comma-separated string. -
Enum-whitelisted
orderby/orderand aper_pagecap. Becauseorderbyfeeds into the query, restricting it to a fixed set of allowed values (and boundingper_pageat 50) keeps the endpoint safe and its queries bounded.
Time Spent
Approximately 12–15 hours, spread over multiple sessions. This includes learning time — built while learning PHP and WordPress internals, with every line typed by hand rather than pasted.
AI Disclosure
AI (Claude) was used as a mentor/tutor throughout: explaining concepts, reviewing my code like a senior developer, and helping me debug. I typed all code myself, tested each step locally, and caught/fixed several bugs during the build (e.g. a floatval sanitize-callback argument error, a numeric meta_query comparison bug, and a whitespace-only pros entry). No boilerplate was pasted in blindly.