here is the final top-to-end RX Theme folder structure for future use. This combines your original structure with all advanced modules we added step by step: frontend, backend/admin, SEO, performance, ads, app loader, React/Vite dist, accessibility, WooCommerce/Elementor, Disease A-Z, contact/newsletter, and unified plugin-style loader. Your original uploaded structure was the foundation checklist for this final structure.
rx-theme/
├── style.css
├── functions.php
├── index.php
├── screenshot.png
├── readme.txt
│
├── header.php
├── footer.php
├── sidebar.php
├── search.php
├── 404.php
├── archive.php
├── category.php
├── tag.php
├── author.php
├── single.php
├── page.php
├── comments.php
│
├── inc/
│ ├── autoload.php
│ ├── rx-v8-loader.php
│ ├── rx-v83-v84-loader.php
│ ├── rx-v85-v87-loader.php
│ │
│ ├── core/
│ │ ├── theme-setup.php
│ │ ├── enqueue.php
│ │ ├── menus.php
│ │ ├── sidebars.php
│ │ ├── image-sizes.php
│ │ ├── theme-supports.php
│ │ ├── cleanup.php
│ │ ├── security.php
│ │ └── performance.php
│ │
│ ├── helpers/
│ │ ├── options.php
│ │ ├── sanitization.php
│ │ ├── escaping.php
│ │ ├── conditionals.php
│ │ ├── media.php
│ │ ├── formatting.php
│ │ ├── compatibility.php
│ │ └── template-functions.php
│ │
│ ├── frontend/
│ │ ├── template-tags.php
│ │ ├── template-functions.php
│ │ ├── breadcrumbs.php
│ │ ├── pagination.php
│ │ ├── related-posts.php
│ │ ├── reading-time.php
│ │ ├── post-views.php
│ │ ├── author-box.php
│ │ ├── reviewer-box.php
│ │ ├── social-share.php
│ │ ├── social-share-tools.php
│ │ ├── table-of-contents.php
│ │ ├── medical-disclaimer.php
│ │ ├── medical-article.php
│ │ ├── homepage.php
│ │ ├── footer-builder.php
│ │ ├── search-overlay.php
│ │ ├── archive-layout.php
│ │ └── header-mobile-polish.php
│ │
│ ├── backend/
│ │ ├── admin-menu.php
│ │ ├── admin-page.php
│ │ ├── theme-options.php
│ │ ├── settings-api.php
│ │ ├── customizer.php
│ │ ├── metaboxes.php
│ │ ├── dashboard-widgets.php
│ │ ├── admin-notices.php
│ │ └── import-export.php
│ │
│ ├── admin/
│ │ ├── admin-menu.php
│ │ └── settings-register.php
│ │
│ ├── dynamic/
│ │ └── dynamic-css.php
│ │
│ ├── seo/
│ │ ├── seo-loader.php
│ │ ├── seo-helpers.php
│ │ ├── schema-output.php
│ │ ├── schema-article.php
│ │ ├── schema-medical-webpage.php
│ │ ├── schema-medical-condition.php
│ │ ├── schema-drug.php
│ │ ├── schema-faq.php
│ │ ├── schema-breadcrumb.php
│ │ ├── schema-organization.php
│ │ ├── schema-person.php
│ │ ├── schema-website.php
│ │ ├── schema-search-action.php
│ │ ├── open-graph.php
│ │ ├── twitter-card.php
│ │ ├── canonical.php
│ │ └── meta-robots.php
│ │
│ ├── performance/
│ │ ├── performance-loader.php
│ │ ├── preload.php
│ │ ├── preconnect.php
│ │ ├── defer-async.php
│ │ ├── defer-scripts.php
│ │ ├── critical-css.php
│ │ ├── lazy-loading.php
│ │ ├── resource-hints.php
│ │ ├── remove-bloat.php
│ │ ├── emoji-disable.php
│ │ ├── embeds-disable.php
│ │ ├── heartbeat-control.php
│ │ ├── web-vitals.php
│ │ ├── font-optimization.php
│ │ └── cache-headers.php
│ │
│ ├── ads/
│ │ ├── ads-loader.php
│ │ ├── ad-helpers.php
│ │ ├── ad-settings.php
│ │ ├── ad-output.php
│ │ └── ad-shortcodes.php
│ │
│ ├── tools/
│ │ └── import-export-settings.php
│ │
│ ├── customizer/
│ │ └── customizer-support.php
│ │
│ ├── blocks/
│ │ └── gutenberg-medical-blocks.php
│ │
│ ├── medical/
│ │ ├── shortcodes.php
│ │ └── disease-az.php
│ │
│ ├── contact/
│ │ └── contact-newsletter.php
│ │
│ ├── compatibility/
│ │ └── woocommerce-elementor.php
│ │
│ ├── accessibility/
│ │ └── accessibility-tools.php
│ │
│ ├── polish/
│ │ └── final-premium-polish.php
│ │
│ ├── app/
│ │ ├── app-loader.php
│ │ ├── admin-app-loader.php
│ │ ├── frontend-app-loader.php
│ │ ├── dist-assets-loader.php
│ │ ├── dist-assets-manager.php
│ │ ├── unified-loader.php
│ │ ├── unified-app-plugin-loader.php
│ │ └── plugin-analysis-summary.json
│ │
│ ├── rest/
│ │ └── app-rest-api.php
│ │
│ └── integrations/
│ ├── woocommerce.php
│ ├── elementor.php
│ ├── gutenberg.php
│ ├── rankmath.php
│ ├── yoast.php
│ └── contact-form-7.php
│
├── frontend/
│ ├── components/
│ │ ├── site-header.php
│ │ ├── site-footer.php
│ │ ├── nav-primary.php
│ │ ├── nav-mobile.php
│ │ ├── search-form.php
│ │ ├── post-card.php
│ │ ├── author-box.php
│ │ ├── related-post-card.php
│ │ ├── share-buttons.php
│ │ └── ad-slot.php
│ │
│ ├── layouts/
│ │ ├── layout-default.php
│ │ ├── layout-full-width.php
│ │ ├── layout-sidebar-right.php
│ │ ├── layout-sidebar-left.php
│ │ ├── layout-medical-article.php
│ │ └── layout-landing.php
│ │
│ └── parts/
│ ├── content.php
│ ├── content-single.php
│ ├── content-page.php
│ ├── content-search.php
│ ├── content-none.php
│ ├── entry-header.php
│ ├── entry-footer.php
│ └── entry-meta.php
│
├── backend/
│ ├── pages/
│ │ ├── rx-dashboard.php
│ │ ├── rx-general-settings.php
│ │ ├── rx-header-settings.php
│ │ ├── rx-footer-settings.php
│ │ ├── rx-seo-settings.php
│ │ ├── rx-performance-settings.php
│ │ ├── rx-social-settings.php
│ │ └── rx-import-export.php
│ │
│ ├── fields/
│ │ ├── field-text.php
│ │ ├── field-textarea.php
│ │ ├── field-checkbox.php
│ │ ├── field-radio.php
│ │ ├── field-select.php
│ │ ├── field-color.php
│ │ ├── field-image.php
│ │ └── field-repeater.php
│ │
│ └── assets/
│ ├── css/
│ │ └── admin.css
│ ├── js/
│ │ └── admin.js
│ └── images/
│ └── rx-logo.svg
│
├── template-parts/
│ ├── header/
│ │ ├── header-default.php
│ │ ├── header-medical.php
│ │ ├── header-centered.php
│ │ ├── header-transparent.php
│ │ ├── header-sticky.php
│ │ ├── header-mobile.php
│ │ ├── header-topbar.php
│ │ └── mobile-header.php
│ │
│ ├── footer/
│ │ ├── footer-default.php
│ │ ├── footer-widgets.php
│ │ ├── footer-minimal.php
│ │ └── footer-medical.php
│ │
│ ├── content/
│ │ ├── content.php
│ │ ├── content-single.php
│ │ ├── content-page.php
│ │ ├── content-search.php
│ │ └── content-none.php
│ │
│ ├── home/
│ │ ├── hero.php
│ │ ├── search-box.php
│ │ ├── featured-categories.php
│ │ ├── latest-articles.php
│ │ ├── popular-guides.php
│ │ ├── disease-az.php
│ │ ├── doctor-reviewed.php
│ │ ├── faq.php
│ │ └── footer-cta.php
│ │
│ ├── post/
│ │ ├── post-card.php
│ │ ├── post-list.php
│ │ ├── post-grid.php
│ │ ├── post-meta.php
│ │ ├── post-author.php
│ │ └── post-related.php
│ │
│ ├── page/
│ │ ├── page-header.php
│ │ ├── page-content.php
│ │ └── page-builder.php
│ │
│ ├── archive/
│ │ ├── archive-header.php
│ │ ├── archive-toolbar.php
│ │ ├── archive-card.php
│ │ ├── archive-grid.php
│ │ └── no-results.php
│ │
│ └── medical/
│ ├── disease-card.php
│ ├── symptom-box.php
│ ├── treatment-box.php
│ ├── diagnosis-box.php
│ ├── prevention-box.php
│ ├── faq-box.php
│ ├── reviewer-box.php
│ ├── references-box.php
│ └── medical-disclaimer.php
│
├── assets/
│ ├── css/
│ │ ├── frontend/
│ │ │ ├── main.css
│ │ │ ├── header.css
│ │ │ ├── footer.css
│ │ │ ├── blog.css
│ │ │ ├── single.css
│ │ │ ├── archive.css
│ │ │ ├── archive-layout.css
│ │ │ ├── medical.css
│ │ │ ├── homepage.css
│ │ │ ├── disease-az.css
│ │ │ ├── contact-newsletter.css
│ │ │ ├── ad-manager.css
│ │ │ ├── search-menu.css
│ │ │ ├── social-share-tools.css
│ │ │ ├── header-mobile-polish.css
│ │ │ ├── compatibility-polish.css
│ │ │ ├── accessibility.css
│ │ │ ├── accessibility-tools.css
│ │ │ ├── premium-polish.css
│ │ │ └── responsive.css
│ │ │
│ │ ├── backend/
│ │ │ ├── admin.css
│ │ │ ├── settings.css
│ │ │ ├── customizer.css
│ │ │ ├── rx-admin-tools.css
│ │ │ ├── dist-assets-manager.css
│ │ │ └── unified-app-loader-admin.css
│ │ │
│ │ ├── blocks/
│ │ │ └── medical-blocks.css
│ │ │
│ │ ├── dynamic/
│ │ │ ├── variables.css
│ │ │ ├── color-scheme.css
│ │ │ ├── typography.css
│ │ │ └── generated.css
│ │ │
│ │ └── vendor/
│ │ ├── normalize.css
│ │ └── icons.css
│ │
│ ├── js/
│ │ ├── frontend/
│ │ │ ├── main.js
│ │ │ ├── navigation.js
│ │ │ ├── mobile-menu.js
│ │ │ ├── search.js
│ │ │ ├── search-menu.js
│ │ │ ├── accessibility.js
│ │ │ ├── accessibility-tools.js
│ │ │ ├── lazyload.js
│ │ │ ├── toc.js
│ │ │ ├── dark-mode.js
│ │ │ ├── performance.js
│ │ │ ├── social-share-tools.js
│ │ │ ├── header-mobile-polish.js
│ │ │ ├── archive-layout.js
│ │ │ ├── disease-az.js
│ │ │ ├── contact-newsletter.js
│ │ │ └── premium-polish.js
│ │ │
│ │ ├── backend/
│ │ │ ├── admin.js
│ │ │ ├── settings.js
│ │ │ ├── media-upload.js
│ │ │ ├── customizer.js
│ │ │ └── customizer-preview.js
│ │ │
│ │ ├── blocks/
│ │ │ └── medical-blocks.js
│ │ │
│ │ ├── performance/
│ │ │ ├── idle-loader.js
│ │ │ ├── defer-third-party.js
│ │ │ └── web-vitals-monitor.js
│ │ │
│ │ └── vendor/
│ │ └── vendor.js
│ │
│ ├── build/
│ │ ├── admin/
│ │ │ ├── admin-app.js
│ │ │ └── admin-app.css
│ │ └── frontend/
│ │ ├── frontend-app.js
│ │ └── frontend-app.css
│ │
│ ├── app-dist/
│ │ ├── README.md
│ │ ├── rx-dist-manifest-example.json
│ │ ├── chunks/
│ │ │ ├── chunk-01.js
│ │ │ ├── chunk-02.js
│ │ │ └── chunk-50.js
│ │ ├── main-js/
│ │ │ ├── main-01.js
│ │ │ ├── main-02.js
│ │ │ └── main-50.js
│ │ ├── css/
│ │ │ ├── style-01.css
│ │ │ ├── style-02.css
│ │ │ └── style-50.css
│ │ ├── vendor/
│ │ ├── images/
│ │ └── fonts/
│ │
│ ├── app-loader/
│ │ ├── frontend/
│ │ │ ├── css/
│ │ │ │ ├── frontend-01.css
│ │ │ │ └── frontend-50.css
│ │ │ └── js/
│ │ │ ├── frontend-01.js
│ │ │ └── frontend-50.js
│ │ │
│ │ ├── admin/
│ │ │ ├── css/
│ │ │ │ ├── admin-01.css
│ │ │ │ └── admin-50.css
│ │ │ └── js/
│ │ │ ├── admin-01.js
│ │ │ └── admin-50.js
│ │ │
│ │ ├── both/
│ │ │ ├── css/
│ │ │ │ ├── both-01.css
│ │ │ │ └── both-50.css
│ │ │ └── js/
│ │ │ ├── both-01.js
│ │ │ └── both-50.js
│ │ │
│ │ ├── chunks/
│ │ │ ├── chunk-01.js
│ │ │ ├── chunk-02.js
│ │ │ └── chunk-100.js
│ │ ├── vendor/
│ │ └── media/
│ │
│ ├── images/
│ │ ├── logo/
│ │ ├── icons/
│ │ ├── backgrounds/
│ │ └── placeholders/
│ │
│ ├── fonts/
│ │ ├── inter/
│ │ └── rx-icons/
│ │
│ └── static-js/
│ ├── accessibility.js
│ ├── frontend-helpers.js
│ └── performance-helpers.js
│
├── app/
│ ├── README.md
│ │
│ ├── admin-react/
│ │ ├── package.json
│ │ ├── vite.config.js
│ │ ├── src/
│ │ │ ├── main.jsx
│ │ │ └── admin-app.css
│ │ └── dist/
│ │ ├── admin-app.js
│ │ └── admin-app.css
│ │
│ ├── frontend-vite/
│ │ ├── package.json
│ │ ├── vite.config.js
│ │ ├── src/
│ │ │ ├── main.js
│ │ │ └── frontend-app.css
│ │ └── dist/
│ │ ├── frontend-app.js
│ │ └── frontend-app.css
│ │
│ ├── astro-headless-note/
│ │ └── README.md
│ │
│ ├── rust-tools-note/
│ │ └── README.md
│ │
│ └── plugin-reference-readonly/
│ ├── README.md
│ ├── PLUGIN_FILES_LIST.txt
│ └── PLUGIN_HEADER.txt
│
├── templates/
│ ├── template-full-width.php
│ ├── template-left-sidebar.php
│ ├── template-right-sidebar.php
│ ├── template-no-sidebar.php
│ ├── template-medical-article.php
│ ├── template-homepage.php
│ ├── template-landing-page.php
│ ├── template-sitemap.php
│ ├── template-disease-az.php
│ └── template-contact-newsletter.php
│
├── blocks/
│ ├── rx-card/
│ │ ├── block.json
│ │ ├── index.js
│ │ ├── editor.css
│ │ └── style.css
│ │
│ ├── rx-faq/
│ │ ├── block.json
│ │ ├── index.js
│ │ ├── editor.css
│ │ └── style.css
│ │
│ ├── rx-medical-box/
│ │ ├── block.json
│ │ ├── index.js
│ │ ├── editor.css
│ │ └── style.css
│ │
│ └── rx-reviewer-box/
│ ├── block.json
│ ├── index.js
│ ├── editor.css
│ └── style.css
│
├── languages/
│ └── rx-theme.pot
│
└── build/
├── css/
├── js/
└── manifest.json
Simple map for finding things quickly
Theme engine → inc/core/
Reusable PHP helpers → inc/helpers/
Frontend features → inc/frontend/
Backend/admin pages → inc/backend/ and inc/admin/
SEO/schema → inc/seo/
Performance → inc/performance/
Ads/AdSense → inc/ads/
Customizer → inc/customizer/
Import/export → inc/tools/
Gutenberg blocks PHP → inc/blocks/
Medical systems → inc/medical/
Contact/newsletter → inc/contact/
WooCommerce/Elementor → inc/compatibility/
Accessibility → inc/accessibility/
Final polish → inc/polish/
React/Vite app loader → inc/app/
REST API bridge → inc/rest/
Header/footer templates → template-parts/header/ and template-parts/footer/
Post/page templates → template-parts/post/ and template-parts/page/
Medical UI parts → template-parts/medical/
Frontend CSS → assets/css/frontend/
Backend CSS → assets/css/backend/
Frontend JS → assets/js/frontend/
Backend JS → assets/js/backend/
React/Vite built files → assets/build/
Many app dist files → assets/app-dist/
Unified loader files → assets/app-loader/
Source app folders → app/
Page templates → templates/
Gutenberg block folders → blocks/
Translations → languages/
Most important rule for future
Do not put everything in functions.php.
Keep:
functions.php → only load inc/autoload.php
inc/autoload.php → load modules
each module folder → own job
assets/ → only CSS, JS, images, fonts, dist files
template-parts/ → reusable visual PHP parts
templates/ → selectable page templates
from pathlib import Path
import zipfile, shutil, os, re, json, textwrap, subprocess, sys
uploaded_zip = Path(“/mnt/data/7d7c07c3-f22f-4d16-9756-de52cb295297.zip”)
work_root = Path(“/mnt/data/rx_v74_build”)
out_dir = Path(“/mnt/data”)
extract_dir = work_root / “extract”
if work_root.exists():
shutil.rmtree(work_root)
work_root.mkdir(parents=True)
extract_dir.mkdir()
with zipfile.ZipFile(uploaded_zip, ‘r’) as z:
z.extractall(extract_dir)
# find theme root: first dir containing style.css and functions.php
theme_roots = []
for p in extract_dir.rglob(“style.css”):
if (p.parent / “functions.php”).exists():
theme_roots.append(p.parent)
if not theme_roots:
raise RuntimeError(“Could not find WordPress theme root in uploaded ZIP.”)
src_root = theme_roots[0]
theme_root = work_root / “rx-theme-v7-4-header-mobile-polish”
shutil.copytree(src_root, theme_root)
# Helpers
def read(p):
return p.read_text(encoding=”utf-8″, errors=”ignore”)
def write(p, s):
p.parent.mkdir(parents=True, exist_ok=True)
p.write_text(s, encoding=”utf-8″)
# Update style.css theme name/version if possible
style = theme_root / “style.css”
if style.exists():
s = read(style)
if “Theme Name:” in s:
s = re.sub(r”Theme Name:\s*.*”, “Theme Name: RX Theme v7.4 Header Mobile Polish”, s, count=1)
else:
s = “/*\nTheme Name: RX Theme v7.4 Header Mobile Polish\nVersion: 7.4\n*/\n” + s
if “Version:” in s:
s = re.sub(r”Version:\s*.*”, “Version: 7.4”, s, count=1)
else:
s = s.replace(“*/”, “Version: 7.4\n*/”, 1)
write(style, s)
# Ensure assets dirs
css_dir = theme_root / “assets/css/frontend”
js_dir = theme_root / “assets/js/frontend”
inc_frontend = theme_root / “inc/frontend”
css_dir.mkdir(parents=True, exist_ok=True)
js_dir.mkdir(parents=True, exist_ok=True)
inc_frontend.mkdir(parents=True, exist_ok=True)
# Add v7.4 CSS
v74_css = r”’
/* ==========================================================
RX Theme v7.4 – Header Polish + Mobile Perfection
Safe CSS-only header/mobile improvements
========================================================== */
:root{
–rx-header-height: 74px;
–rx-header-z: 9999;
–rx-header-shadow: 0 12px 32px rgba(15, 23, 42, .08);
–rx-mobile-panel-shadow: 0 24px 80px rgba(15, 23, 42, .18);
}
/* Header base polish */
.rx-site-header{
position: relative;
z-index: var(–rx-header-z);
background: rgba(255,255,255,.98);
border-bottom: 1px solid rgba(226,232,240,.9);
transition: box-shadow .25s ease, background-color .25s ease, transform .25s ease;
}
.rx-site-header.rx-sticky-header,
.rx-sticky-header{
position: sticky;
top: 0;
}
.admin-bar .rx-site-header.rx-sticky-header,
.admin-bar .rx-sticky-header{
top: 32px;
}
.rx-site-header.is-scrolled{
box-shadow: var(–rx-header-shadow);
background: rgba(255,255,255,.96);
backdrop-filter: blur(12px);
}
.rx-site-header .rx-container.rx-header-inner,
.rx-header-inner{
min-height: var(–rx-header-height);
display: flex;
align-items: center;
gap: 22px;
}
/* Logo/site title alignment */
.rx-branding{
display:flex;
align-items:center;
gap:12px;
min-width: 190px;
}
.rx-custom-logo,
.custom-logo{
max-height: 48px;
width: auto;
display: block;
}
.rx-site-title{
line-height: 1.05;
display:inline-flex;
align-items:center;
}
/* Menu spacing */
.rx-primary-nav{
min-width:0;
}
.rx-primary-nav ul,
.rx-primary-menu{
display:flex;
align-items:center;
gap: 4px;
list-style:none;
margin:0;
padding:0;
}
.rx-primary-nav li{
position:relative;
}
.rx-primary-nav a{
display:flex;
align-items:center;
min-height:42px;
padding: 10px 12px;
border-radius: 12px;
text-decoration:none;
transition: background-color .18s ease, color .18s ease, transform .18s ease;
}
.rx-primary-nav a:hover,
.rx-primary-nav a:focus{
background: rgba(0,102,204,.08);
text-decoration:none;
}
/* Header actions */
.rx-header-actions{
display:flex;
align-items:center;
justify-content:flex-end;
gap:10px;
}
/* Keep search elegant and stable */
.rx-header-search{
transition: border-color .18s ease, box-shadow .18s ease;
}
.rx-header-search__results{
text-align:left;
}
/* Dark button polish */
.rx-dark-toggle{
width:40px;
height:40px;
min-width:40px;
border-radius: 999px;
border: 1px solid rgba(15,23,42,.1);
background: #0f172a;
color:#fff;
display:inline-flex;
align-items:center;
justify-content:center;
box-shadow:none;
cursor:pointer;
transition: transform .18s ease, background-color .18s ease, box-shadow .18s ease;
}
.rx-dark-toggle:hover,
.rx-dark-toggle:focus{
transform: translateY(-1px);
box-shadow: 0 10px 24px rgba(15,23,42,.16);
}
/* Mobile menu button */
.rx-menu-toggle{
display:none;
align-items:center;
justify-content:center;
gap:8px;
min-width:44px;
min-height:40px;
padding: 9px 12px;
border-radius: 999px;
border:1px solid #dbeafe;
background:#eff6ff;
color:var(–rx-primary-color,#0066cc);
font-weight:900;
cursor:pointer;
line-height:1;
}
.rx-menu-toggle::before{
content:’☰’;
font-size:18px;
line-height:1;
}
.rx-menu-toggle[aria-expanded=”true”]::before{
content:’×’;
font-size:24px;
}
/* Mobile nav panel */
@media (max-width: 980px){
body.rx-mobile-menu-open{
overflow:hidden;
}
.admin-bar .rx-site-header.rx-sticky-header,
.admin-bar .rx-sticky-header{
top: 46px;
}
.rx-site-header .rx-container.rx-header-inner,
.rx-header-inner{
min-height: 68px;
flex-wrap: wrap;
gap: 12px;
padding-top: 10px;
padding-bottom: 10px;
}
.rx-branding{
flex: 1 1 auto;
min-width:0;
max-width: calc(100% – 58px);
}
.rx-custom-logo,
.custom-logo{
max-height: 42px;
}
.rx-site-title{
font-size: clamp(19px, 5vw, 24px);
white-space: normal;
}
.rx-menu-toggle{
display:inline-flex;
order:2;
}
.rx-header-actions{
order:3;
flex: 1 1 100%;
width:100%;
max-width:none;
min-width:0;
margin-left:0;
}
.rx-header-search{
width:100%;
max-width:none;
}
.rx-primary-nav{
order:4;
flex: 1 1 100%;
width:100%;
display:none;
background:#ffffff;
border:1px solid #e5e7eb;
border-radius: 22px;
box-shadow: var(–rx-mobile-panel-shadow);
padding: 10px;
max-height: calc(100vh – 130px);
overflow:auto;
}
.rx-primary-nav.is-open,
.rx-primary-nav.rx-is-open{
display:block;
animation: rxMenuDrop .18s ease both;
}
.rx-primary-nav ul,
.rx-primary-menu{
display:block;
}
.rx-primary-nav li{
display:block;
width:100%;
}
.rx-primary-nav a{
min-height:44px;
padding: 12px 14px;
border-radius: 14px;
justify-content:space-between;
}
.rx-primary-nav .sub-menu{
position:static !important;
display:block !important;
width:auto !important;
min-width:0 !important;
padding: 0 0 0 14px !important;
margin: 0 !important;
border:0 !important;
box-shadow:none !important;
background:transparent !important;
}
.rx-primary-nav .sub-menu a{
font-size: .95em;
opacity:.92;
}
}
@keyframes rxMenuDrop{
from{opacity:0; transform: translateY(-8px);}
to{opacity:1; transform: translateY(0);}
}
/* Very small phones */
@media (max-width: 520px){
:root{
–rx-header-height: 66px;
}
.rx-site-header .rx-container.rx-header-inner,
.rx-header-inner{
padding-left: 14px;
padding-right: 14px;
}
.rx-header-actions{
gap:8px;
}
.rx-dark-toggle{
width:38px;
height:38px;
min-width:38px;
}
}
/* Dark mode header */
body.rx-dark-mode .rx-site-header{
background: rgba(15,23,42,.98);
border-bottom-color: rgba(51,65,85,.9);
}
body.rx-dark-mode .rx-site-header.is-scrolled{
background: rgba(15,23,42,.94);
}
body.rx-dark-mode .rx-primary-nav{
background:#0f172a;
border-color:#243244;
}
body.rx-dark-mode .rx-primary-nav a:hover,
body.rx-dark-mode .rx-primary-nav a:focus{
background: rgba(96,165,250,.14);
}
body.rx-dark-mode .rx-menu-toggle{
background:#111827;
border-color:#243244;
color:#bfdbfe;
}
body.rx-dark-mode .rx-dark-toggle{
background:#f8fafc;
color:#0f172a;
}
/* Reduced motion */
@media (prefers-reduced-motion: reduce){
.rx-site-header,
.rx-primary-nav.is-open,
.rx-primary-nav.rx-is-open,
.rx-primary-nav a,
.rx-dark-toggle{
transition:none !important;
animation:none !important;
}
}
”’
write(css_dir / “header-mobile-polish.css”, v74_css)
# Add v7.4 JS
v74_js = r”’
/* RX Theme v7.4 – Header polish + mobile menu */
(function(){
‘use strict’;
const header = document.querySelector(‘.rx-site-header’);
const nav = document.querySelector(‘.rx-primary-nav’);
let menuToggle = document.querySelector(‘.rx-menu-toggle’);
function onScroll(){
if (!header) return;
if (window.scrollY > 8) {
header.classList.add(‘is-scrolled’);
} else {
header.classList.remove(‘is-scrolled’);
}
}
onScroll();
window.addEventListener(‘scroll’, onScroll, { passive: true });
if (nav && !menuToggle) {
menuToggle = document.createElement(‘button’);
menuToggle.type = ‘button’;
menuToggle.className = ‘rx-menu-toggle’;
menuToggle.setAttribute(‘aria-expanded’, ‘false’);
menuToggle.setAttribute(‘aria-controls’, ‘rx-primary-navigation’);
menuToggle.setAttribute(‘aria-label’, ‘Open menu’);
if (!nav.id) {
nav.id = ‘rx-primary-navigation’;
}
const headerInner = document.querySelector(‘.rx-header-inner’) || header;
if (headerInner) {
const branding = headerInner.querySelector(‘.rx-branding’);
if (branding && branding.nextSibling) {
headerInner.insertBefore(menuToggle, branding.nextSibling);
} else {
headerInner.insertBefore(menuToggle, headerInner.firstChild);
}
}
}
function closeMenu(){
if (!nav || !menuToggle) return;
nav.classList.remove(‘is-open’, ‘rx-is-open’);
menuToggle.setAttribute(‘aria-expanded’, ‘false’);
menuToggle.setAttribute(‘aria-label’, ‘Open menu’);
document.body.classList.remove(‘rx-mobile-menu-open’);
}
function openMenu(){
if (!nav || !menuToggle) return;
nav.classList.add(‘is-open’, ‘rx-is-open’);
menuToggle.setAttribute(‘aria-expanded’, ‘true’);
menuToggle.setAttribute(‘aria-label’, ‘Close menu’);
document.body.classList.add(‘rx-mobile-menu-open’);
}
if (menuToggle && nav) {
menuToggle.addEventListener(‘click’, function(){
const isOpen = menuToggle.getAttribute(‘aria-expanded’) === ‘true’;
isOpen ? closeMenu() : openMenu();
});
document.addEventListener(‘keydown’, function(event){
if (event.key === ‘Escape’) {
closeMenu();
}
});
document.addEventListener(‘click’, function(event){
if (!document.body.classList.contains(‘rx-mobile-menu-open’)) return;
if (window.innerWidth > 980) return;
if (nav.contains(event.target) || menuToggle.contains(event.target)) return;
closeMenu();
});
nav.querySelectorAll(‘a’).forEach(function(link){
link.addEventListener(‘click’, function(){
if (window.innerWidth <= 980) {
closeMenu();
}
});
});
window.addEventListener(‘resize’, function(){
if (window.innerWidth > 980) {
closeMenu();
}
});
}
})();
”’
write(js_dir / “header-mobile-polish.js”, v74_js)
# Add enqueue module
v74_php = r”'<?php
/**
* RX Theme v7.4 Header Polish + Mobile Perfection assets.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
function rx_theme_v74_header_mobile_assets() {
$theme_uri = defined( ‘RX_THEME_URI’ ) ? RX_THEME_URI : get_template_directory_uri();
$theme_dir = defined( ‘RX_THEME_DIR’ ) ? RX_THEME_DIR : get_template_directory();
$css_rel = ‘/assets/css/frontend/header-mobile-polish.css’;
$js_rel = ‘/assets/js/frontend/header-mobile-polish.js’;
$css_ver = file_exists( $theme_dir . $css_rel ) ? filemtime( $theme_dir . $css_rel ) : ‘7.4’;
$js_ver = file_exists( $theme_dir . $js_rel ) ? filemtime( $theme_dir . $js_rel ) : ‘7.4’;
wp_enqueue_style(
‘rx-theme-header-mobile-polish’,
$theme_uri . $css_rel,
array(),
$css_ver
);
wp_enqueue_script(
‘rx-theme-header-mobile-polish’,
$theme_uri . $js_rel,
array(),
$js_ver,
true
);
}
add_action( ‘wp_enqueue_scripts’, ‘rx_theme_v74_header_mobile_assets’, 30 );
”’
write(inc_frontend / “header-mobile-polish.php”, v74_php)
# Add to autoload if exists
autoload = theme_root / “inc/autoload.php”
if autoload.exists():
a = read(autoload)
rel = “/inc/frontend/header-mobile-polish.php”
if rel not in a:
# Try to insert into array before closing );
if “$rx_theme_files” in a and “);” in a:
# insert before first occurrence of ); after array entries? safer before foreach
marker = “foreach”
idx = a.find(marker)
if idx != -1:
before, after = a[:idx], a[idx:]
# If before ends with array );
pos = before.rfind(“);”)
if pos != -1:
before = before[:pos] + ” ‘/inc/frontend/header-mobile-polish.php’,\n” + before[pos:]
a = before + after
else:
a += “\nrequire_once RX_THEME_DIR . ‘/inc/frontend/header-mobile-polish.php’;\n”
else:
a += “\nrequire_once RX_THEME_DIR . ‘/inc/frontend/header-mobile-polish.php’;\n”
else:
a += “\nrequire_once RX_THEME_DIR . ‘/inc/frontend/header-mobile-polish.php’;\n”
write(autoload, a)
else:
write(autoload, “<?php\nif ( ! defined( ‘ABSPATH’ ) ) { exit; }\nrequire_once get_template_directory() . ‘/inc/frontend/header-mobile-polish.php’;\n”)
# Make direct require fallback in functions.php if autoload broken? no, avoid duplicates? Need check function_exists? our PHP no duplicate. But if autoload parse fails?
# Check PHP syntax all files
php_files = list(theme_root.rglob(“*.php”))
errors = []
for p in php_files:
proc = subprocess.run([“php”, “-l”, str(p)], capture_output=True, text=True)
if proc.returncode != 0:
errors.append((str(p), proc.stdout + proc.stderr))
if errors:
raise RuntimeError(“PHP syntax errors:\n” + “\n”.join([e[0] + “\n” + e[1] for e in errors[:10]]))
# Create zip with theme_root folder
zip_path = out_dir / “rx-theme-v7-4-header-mobile-polish.zip”
if zip_path.exists():
zip_path.unlink()
with zipfile.ZipFile(zip_path, “w”, compression=zipfile.ZIP_DEFLATED) as z:
for p in theme_root.rglob(“*”):
z.write(p, p.relative_to(work_root))
# test zip
with zipfile.ZipFile(zip_path, “r”) as z:
bad = z.testzip()
if bad:
raise RuntimeError(f”Bad file in ZIP: {bad}”)
print(f”Created: {zip_path}”)
print(f”Files: {sum(1 for _ in theme_root.rglob(‘*’))}”)
print(“PHP syntax check: Passed”)
print(“ZIP integrity test: Passed”)
from pathlib import Path
import zipfile, shutil, os, re, subprocess
uploaded_zip = Path(“/mnt/data/7d7c07c3-f22f-4d16-9756-de52cb295297.zip”)
work_root = Path(“/mnt/data/rx_v74_build”)
extract_dir = work_root / “extract”
if work_root.exists():
shutil.rmtree(work_root)
work_root.mkdir(parents=True)
extract_dir.mkdir(parents=True)
with zipfile.ZipFile(uploaded_zip, “r”) as z:
z.extractall(extract_dir)
theme_roots = []
for p in extract_dir.rglob(“style.css”):
if (p.parent / “functions.php”).exists():
theme_roots.append(p.parent)
if not theme_roots:
raise RuntimeError(“Could not find a WordPress theme root with style.css and functions.php.”)
src_root = theme_roots[0]
theme_root = work_root / “rx-theme-v7-4-header-mobile-polish”
shutil.copytree(src_root, theme_root)
def read_text(path):
return path.read_text(encoding=”utf-8″, errors=”ignore”)
def write_text(path, text):
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(text, encoding=”utf-8″)
# Update style.css
style_path = theme_root / “style.css”
if style_path.exists():
style = read_text(style_path)
style = re.sub(r”Theme Name:\s*.*”, “Theme Name: RX Theme v7.4 Header Mobile Polish”, style, count=1) if “Theme Name:” in style else “/*\nTheme Name: RX Theme v7.4 Header Mobile Polish\nVersion: 7.4\n*/\n” + style
style = re.sub(r”Version:\s*.*”, “Version: 7.4”, style, count=1) if “Version:” in style else style.replace(“*/”, “Version: 7.4\n*/”, 1)
write_text(style_path, style)
css_dir = theme_root / “assets/css/frontend”
js_dir = theme_root / “assets/js/frontend”
inc_frontend = theme_root / “inc/frontend”
css_dir.mkdir(parents=True, exist_ok=True)
js_dir.mkdir(parents=True, exist_ok=True)
inc_frontend.mkdir(parents=True, exist_ok=True)
v74_css = “””
/* ==========================================================
RX Theme v7.4 – Header Polish + Mobile Perfection
========================================================== */
:root{
–rx-header-height:74px;
–rx-header-z:9999;
–rx-header-shadow:0 12px 32px rgba(15,23,42,.08);
–rx-mobile-panel-shadow:0 24px 80px rgba(15,23,42,.18);
}
.rx-site-header{
position:relative;
z-index:var(–rx-header-z);
background:rgba(255,255,255,.98);
border-bottom:1px solid rgba(226,232,240,.9);
transition:box-shadow .25s ease, background-color .25s ease, transform .25s ease;
}
.rx-site-header.rx-sticky-header,
.rx-sticky-header{position:sticky;top:0;}
.admin-bar .rx-site-header.rx-sticky-header,
.admin-bar .rx-sticky-header{top:32px;}
.rx-site-header.is-scrolled{
box-shadow:var(–rx-header-shadow);
background:rgba(255,255,255,.96);
backdrop-filter:blur(12px);
}
.rx-site-header .rx-container.rx-header-inner,
.rx-header-inner{
min-height:var(–rx-header-height);
display:flex;
align-items:center;
gap:22px;
}
.rx-branding{
display:flex;
align-items:center;
gap:12px;
min-width:190px;
}
.rx-custom-logo,
.custom-logo{
max-height:48px;
width:auto;
display:block;
}
.rx-site-title{
line-height:1.05;
display:inline-flex;
align-items:center;
}
.rx-primary-nav{min-width:0;}
.rx-primary-nav ul,
.rx-primary-menu{
display:flex;
align-items:center;
gap:4px;
list-style:none;
margin:0;
padding:0;
}
.rx-primary-nav li{position:relative;}
.rx-primary-nav a{
display:flex;
align-items:center;
min-height:42px;
padding:10px 12px;
border-radius:12px;
text-decoration:none;
transition:background-color .18s ease, color .18s ease, transform .18s ease;
}
.rx-primary-nav a:hover,
.rx-primary-nav a:focus{
background:rgba(0,102,204,.08);
text-decoration:none;
}
.rx-header-actions{
display:flex;
align-items:center;
justify-content:flex-end;
gap:10px;
}
.rx-header-search{transition:border-color .18s ease, box-shadow .18s ease;}
.rx-header-search__results{text-align:left;}
.rx-dark-toggle{
width:40px;
height:40px;
min-width:40px;
border-radius:999px;
border:1px solid rgba(15,23,42,.1);
background:#0f172a;
color:#fff;
display:inline-flex;
align-items:center;
justify-content:center;
box-shadow:none;
cursor:pointer;
transition:transform .18s ease, background-color .18s ease, box-shadow .18s ease;
}
.rx-dark-toggle:hover,
.rx-dark-toggle:focus{
transform:translateY(-1px);
box-shadow:0 10px 24px rgba(15,23,42,.16);
}
.rx-menu-toggle{
display:none;
align-items:center;
justify-content:center;
gap:8px;
min-width:44px;
min-height:40px;
padding:9px 12px;
border-radius:999px;
border:1px solid #dbeafe;
background:#eff6ff;
color:var(–rx-primary-color,#0066cc);
font-weight:900;
cursor:pointer;
line-height:1;
}
.rx-menu-toggle::before{
content:’☰’;
font-size:18px;
line-height:1;
}
.rx-menu-toggle[aria-expanded=”true”]::before{
content:’×’;
font-size:24px;
}
@media (max-width:980px){
body.rx-mobile-menu-open{overflow:hidden;}
.admin-bar .rx-site-header.rx-sticky-header,
.admin-bar .rx-sticky-header{top:46px;}
.rx-site-header .rx-container.rx-header-inner,
.rx-header-inner{
min-height:68px;
flex-wrap:wrap;
gap:12px;
padding-top:10px;
padding-bottom:10px;
}
.rx-branding{
flex:1 1 auto;
min-width:0;
max-width:calc(100% – 58px);
}
.rx-custom-logo,
.custom-logo{max-height:42px;}
.rx-site-title{
font-size:clamp(19px,5vw,24px);
white-space:normal;
}
.rx-menu-toggle{
display:inline-flex;
order:2;
}
.rx-header-actions{
order:3;
flex:1 1 100%;
width:100%;
max-width:none;
min-width:0;
margin-left:0;
}
.rx-header-search{
width:100%;
max-width:none;
}
.rx-primary-nav{
order:4;
flex:1 1 100%;
width:100%;
display:none;
background:#ffffff;
border:1px solid #e5e7eb;
border-radius:22px;
box-shadow:var(–rx-mobile-panel-shadow);
padding:10px;
max-height:calc(100vh – 130px);
overflow:auto;
}
.rx-primary-nav.is-open,
.rx-primary-nav.rx-is-open{
display:block;
animation:rxMenuDrop .18s ease both;
}
.rx-primary-nav ul,
.rx-primary-menu{display:block;}
.rx-primary-nav li{
display:block;
width:100%;
}
.rx-primary-nav a{
min-height:44px;
padding:12px 14px;
border-radius:14px;
justify-content:space-between;
}
.rx-primary-nav .sub-menu{
position:static !important;
display:block !important;
width:auto !important;
min-width:0 !important;
padding:0 0 0 14px !important;
margin:0 !important;
border:0 !important;
box-shadow:none !important;
background:transparent !important;
}
.rx-primary-nav .sub-menu a{
font-size:.95em;
opacity:.92;
}
}
@keyframes rxMenuDrop{
from{opacity:0;transform:translateY(-8px);}
to{opacity:1;transform:translateY(0);}
}
@media (max-width:520px){
:root{–rx-header-height:66px;}
.rx-site-header .rx-container.rx-header-inner,
.rx-header-inner{
padding-left:14px;
padding-right:14px;
}
.rx-header-actions{gap:8px;}
.rx-dark-toggle{
width:38px;
height:38px;
min-width:38px;
}
}
body.rx-dark-mode .rx-site-header{
background:rgba(15,23,42,.98);
border-bottom-color:rgba(51,65,85,.9);
}
body.rx-dark-mode .rx-site-header.is-scrolled{background:rgba(15,23,42,.94);}
body.rx-dark-mode .rx-primary-nav{
background:#0f172a;
border-color:#243244;
}
body.rx-dark-mode .rx-primary-nav a:hover,
body.rx-dark-mode .rx-primary-nav a:focus{background:rgba(96,165,250,.14);}
body.rx-dark-mode .rx-menu-toggle{
background:#111827;
border-color:#243244;
color:#bfdbfe;
}
body.rx-dark-mode .rx-dark-toggle{
background:#f8fafc;
color:#0f172a;
}
@media (prefers-reduced-motion:reduce){
.rx-site-header,
.rx-primary-nav.is-open,
.rx-primary-nav.rx-is-open,
.rx-primary-nav a,
.rx-dark-toggle{
transition:none !important;
animation:none !important;
}
}
“””
write_text(css_dir / “header-mobile-polish.css”, v74_css)
v74_js = “””
/* RX Theme v7.4 – Header polish + mobile menu */
(function(){
‘use strict’;
const header = document.querySelector(‘.rx-site-header’);
const nav = document.querySelector(‘.rx-primary-nav’);
let menuToggle = document.querySelector(‘.rx-menu-toggle’);
function onScroll(){
if (!header) return;
if (window.scrollY > 8) {
header.classList.add(‘is-scrolled’);
} else {
header.classList.remove(‘is-scrolled’);
}
}
onScroll();
window.addEventListener(‘scroll’, onScroll, { passive: true });
if (nav && !menuToggle) {
menuToggle = document.createElement(‘button’);
menuToggle.type = ‘button’;
menuToggle.className = ‘rx-menu-toggle’;
menuToggle.setAttribute(‘aria-expanded’, ‘false’);
menuToggle.setAttribute(‘aria-controls’, ‘rx-primary-navigation’);
menuToggle.setAttribute(‘aria-label’, ‘Open menu’);
if (!nav.id) {
nav.id = ‘rx-primary-navigation’;
}
const headerInner = document.querySelector(‘.rx-header-inner’) || header;
if (headerInner) {
const branding = headerInner.querySelector(‘.rx-branding’);
if (branding && branding.nextSibling) {
headerInner.insertBefore(menuToggle, branding.nextSibling);
} else {
headerInner.insertBefore(menuToggle, headerInner.firstChild);
}
}
}
function closeMenu(){
if (!nav || !menuToggle) return;
nav.classList.remove(‘is-open’, ‘rx-is-open’);
menuToggle.setAttribute(‘aria-expanded’, ‘false’);
menuToggle.setAttribute(‘aria-label’, ‘Open menu’);
document.body.classList.remove(‘rx-mobile-menu-open’);
}
function openMenu(){
if (!nav || !menuToggle) return;
nav.classList.add(‘is-open’, ‘rx-is-open’);
menuToggle.setAttribute(‘aria-expanded’, ‘true’);
menuToggle.setAttribute(‘aria-label’, ‘Close menu’);
document.body.classList.add(‘rx-mobile-menu-open’);
}
if (menuToggle && nav) {
menuToggle.addEventListener(‘click’, function(){
const isOpen = menuToggle.getAttribute(‘aria-expanded’) === ‘true’;
isOpen ? closeMenu() : openMenu();
});
document.addEventListener(‘keydown’, function(event){
if (event.key === ‘Escape’) closeMenu();
});
document.addEventListener(‘click’, function(event){
if (!document.body.classList.contains(‘rx-mobile-menu-open’)) return;
if (window.innerWidth > 980) return;
if (nav.contains(event.target) || menuToggle.contains(event.target)) return;
closeMenu();
});
nav.querySelectorAll(‘a’).forEach(function(link){
link.addEventListener(‘click’, function(){
if (window.innerWidth <= 980) closeMenu();
});
});
window.addEventListener(‘resize’, function(){
if (window.innerWidth > 980) closeMenu();
});
}
})();
“””
write_text(js_dir / “header-mobile-polish.js”, v74_js)
v74_php = “””<?php
/**
* RX Theme v7.4 Header Polish + Mobile Perfection assets.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
function rx_theme_v74_header_mobile_assets() {
$theme_uri = defined( ‘RX_THEME_URI’ ) ? RX_THEME_URI : get_template_directory_uri();
$theme_dir = defined( ‘RX_THEME_DIR’ ) ? RX_THEME_DIR : get_template_directory();
$css_rel = ‘/assets/css/frontend/header-mobile-polish.css’;
$js_rel = ‘/assets/js/frontend/header-mobile-polish.js’;
$css_ver = file_exists( $theme_dir . $css_rel ) ? filemtime( $theme_dir . $css_rel ) : ‘7.4’;
$js_ver = file_exists( $theme_dir . $js_rel ) ? filemtime( $theme_dir . $js_rel ) : ‘7.4’;
wp_enqueue_style( ‘rx-theme-header-mobile-polish’, $theme_uri . $css_rel, array(), $css_ver );
wp_enqueue_script( ‘rx-theme-header-mobile-polish’, $theme_uri . $js_rel, array(), $js_ver, true );
}
add_action( ‘wp_enqueue_scripts’, ‘rx_theme_v74_header_mobile_assets’, 30 );
“””
write_text(inc_frontend / “header-mobile-polish.php”, v74_php)
autoload = theme_root / “inc/autoload.php”
if autoload.exists():
a = read_text(autoload)
if “/inc/frontend/header-mobile-polish.php” not in a:
idx = a.find(“foreach”)
if idx != -1:
before, after = a[:idx], a[idx:]
pos = before.rfind(“);”)
if pos != -1:
before = before[:pos] + ” ‘/inc/frontend/header-mobile-polish.php’,\n” + before[pos:]
a = before + after
else:
a += “\nrequire_once RX_THEME_DIR . ‘/inc/frontend/header-mobile-polish.php’;\n”
else:
a += “\nrequire_once RX_THEME_DIR . ‘/inc/frontend/header-mobile-polish.php’;\n”
write_text(autoload, a)
else:
write_text(autoload, “<?php\nif ( ! defined( ‘ABSPATH’ ) ) { exit; }\nrequire_once get_template_directory() . ‘/inc/frontend/header-mobile-polish.php’;\n”)
# PHP syntax check
errors = []
for p in theme_root.rglob(“*.php”):
proc = subprocess.run([“php”, “-l”, str(p)], capture_output=True, text=True)
if proc.returncode != 0:
errors.append(str(p) + “\n” + proc.stdout + proc.stderr)
if errors:
raise RuntimeError(“\n”.join(errors[:5]))
zip_path = Path(“/mnt/data/rx-theme-v7-4-header-mobile-polish.zip”)
if zip_path.exists():
zip_path.unlink()
with zipfile.ZipFile(zip_path, “w”, zipfile.ZIP_DEFLATED) as z:
for p in theme_root.rglob(“*”):
z.write(p, p.relative_to(work_root))
with zipfile.ZipFile(zip_path, “r”) as z:
bad = z.testzip()
if bad:
raise RuntimeError(“Bad ZIP file member: ” + str(bad))
print(“Created:”, zip_path)
print(“PHP syntax check: Passed”)
print(“ZIP integrity test: Passed”)
Done dear friend — I created the next safe step:
Checked before giving:
PHP syntax check: Passed
ZIP integrity test: Passed
Added in RX Theme v7.4
Header polish
Logo alignment improvement
Header height improvement
Mobile menu button
Mobile menu open/close system
Escape key closes mobile menu
Click outside closes mobile menu
Sticky header shadow on scroll
Dark mode button polish
Mobile search full-width support
Menu spacing improvement
Reduced motion accessibility support
Dark mode header support
Install
Dashboard → Appearance → Themes → Add New → Upload Theme
Upload:
rx-theme-v7-4-header-mobile-polish.zip
After installing, hard refresh:
Ctrl + F5
Keep your last working version as backup before activating this one.
from pathlib import Path
import zipfile, shutil, re, subprocess
uploaded_zip = Path(“/mnt/data/7d7c07c3-f22f-4d16-9756-de52cb295297.zip”)
work_root = Path(“/mnt/data/rx_v75_build”)
extract_dir = work_root / “extract”
if work_root.exists():
shutil.rmtree(work_root)
work_root.mkdir(parents=True)
extract_dir.mkdir(parents=True)
with zipfile.ZipFile(uploaded_zip, “r”) as z:
z.extractall(extract_dir)
theme_roots = [p.parent for p in extract_dir.rglob(“style.css”) if (p.parent / “functions.php”).exists()]
if not theme_roots:
raise RuntimeError(“Theme root not found.”)
src_root = theme_roots[0]
theme_root = work_root / “rx-theme-v7-5-social-share-tools”
shutil.copytree(src_root, theme_root)
def read(path):
return path.read_text(encoding=”utf-8″, errors=”ignore”)
def write(path, text):
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(text, encoding=”utf-8″)
# Update style.css
style_path = theme_root / “style.css”
if style_path.exists():
s = read(style_path)
s = re.sub(r”Theme Name:\s*.*”, “Theme Name: RX Theme v7.5 Social Share Tools”, s, count=1) if “Theme Name:” in s else “/*\nTheme Name: RX Theme v7.5 Social Share Tools\nVersion: 7.5\n*/\n” + s
s = re.sub(r”Version:\s*.*”, “Version: 7.5”, s, count=1) if “Version:” in s else s.replace(“*/”, “Version: 7.5\n*/”, 1)
write(style_path, s)
inc_frontend = theme_root / “inc/frontend”
css_dir = theme_root / “assets/css/frontend”
js_dir = theme_root / “assets/js/frontend”
inc_frontend.mkdir(parents=True, exist_ok=True)
css_dir.mkdir(parents=True, exist_ok=True)
js_dir.mkdir(parents=True, exist_ok=True)
php_code = r”'<?php
/**
* RX Theme v7.5 Social Share + Print + Copy Link.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
function rx_theme_v75_social_share_assets() {
$theme_uri = defined( ‘RX_THEME_URI’ ) ? RX_THEME_URI : get_template_directory_uri();
$theme_dir = defined( ‘RX_THEME_DIR’ ) ? RX_THEME_DIR : get_template_directory();
$css_rel = ‘/assets/css/frontend/social-share-tools.css’;
$js_rel = ‘/assets/js/frontend/social-share-tools.js’;
wp_enqueue_style(
‘rx-theme-social-share-tools’,
$theme_uri . $css_rel,
array(),
file_exists( $theme_dir . $css_rel ) ? filemtime( $theme_dir . $css_rel ) : ‘7.5’
);
wp_enqueue_script(
‘rx-theme-social-share-tools’,
$theme_uri . $js_rel,
array(),
file_exists( $theme_dir . $js_rel ) ? filemtime( $theme_dir . $js_rel ) : ‘7.5’,
true
);
}
add_action( ‘wp_enqueue_scripts’, ‘rx_theme_v75_social_share_assets’, 35 );
function rx_theme_v75_get_share_links() {
$url = rawurlencode( get_permalink() );
$title = rawurlencode( get_the_title() );
return array(
‘facebook’ => array(
‘label’ => esc_html__( ‘Facebook’, ‘rx-theme’ ),
‘url’ => ‘https://www.facebook.com/sharer/sharer.php?u=’ . $url,
),
‘x’ => array(
‘label’ => esc_html__( ‘X’, ‘rx-theme’ ),
‘url’ => ‘https://twitter.com/intent/tweet?url=’ . $url . ‘&text=’ . $title,
),
‘linkedin’ => array(
‘label’ => esc_html__( ‘LinkedIn’, ‘rx-theme’ ),
‘url’ => ‘https://www.linkedin.com/sharing/share-offsite/?url=’ . $url,
),
‘whatsapp’ => array(
‘label’ => esc_html__( ‘WhatsApp’, ‘rx-theme’ ),
‘url’ => ‘https://api.whatsapp.com/send?text=’ . $title . ‘%20’ . $url,
),
);
}
function rx_theme_v75_social_share_html( $floating = false ) {
if ( ! is_singular() ) {
return;
}
$classes = $floating ? ‘rx-social-share rx-social-share–floating’ : ‘rx-social-share’;
?>
<div class=”<?php echo esc_attr( $classes ); ?>” aria-label=”<?php esc_attr_e( ‘Article sharing tools’, ‘rx-theme’ ); ?>”>
<?php if ( ! $floating ) : ?>
<div class=”rx-social-share__title”><?php esc_html_e( ‘Share this article’, ‘rx-theme’ ); ?></div>
<?php endif; ?>
<div class=”rx-social-share__buttons”>
<?php foreach ( rx_theme_v75_get_share_links() as $key => $share ) : ?>
<a class=”rx-social-share__button rx-social-share__button–<?php echo esc_attr( $key ); ?>” href=”<?php echo esc_url( $share[‘url’] ); ?>” target=”_blank” rel=”noopener noreferrer”>
<span><?php echo esc_html( $share[‘label’] ); ?></span>
</a>
<?php endforeach; ?>
<button type=”button” class=”rx-social-share__button rx-social-share__button–copy” data-rx-copy-link=”<?php echo esc_url( get_permalink() ); ?>”>
<span><?php esc_html_e( ‘Copy Link’, ‘rx-theme’ ); ?></span>
</button>
<button type=”button” class=”rx-social-share__button rx-social-share__button–print” data-rx-print>
<span><?php esc_html_e( ‘Print’, ‘rx-theme’ ); ?></span>
</button>
</div>
<div class=”rx-social-share__notice” aria-live=”polite”></div>
</div>
<?php
}
function rx_theme_v75_add_share_after_content( $content ) {
if ( is_singular( ‘post’ ) && in_the_loop() && is_main_query() ) {
ob_start();
rx_theme_v75_social_share_html( false );
$share = ob_get_clean();
return $content . $share;
}
return $content;
}
add_filter( ‘the_content’, ‘rx_theme_v75_add_share_after_content’, 25 );
function rx_theme_v75_floating_share_bar() {
if ( is_singular( ‘post’ ) ) {
rx_theme_v75_social_share_html( true );
}
}
add_action( ‘wp_footer’, ‘rx_theme_v75_floating_share_bar’, 20 );
function rx_theme_v75_shortcode_social_share() {
ob_start();
rx_theme_v75_social_share_html( false );
return ob_get_clean();
}
add_shortcode( ‘rx_social_share’, ‘rx_theme_v75_shortcode_social_share’ );
”’
write(inc_frontend / “social-share-tools.php”, php_code)
css_code = r”’
/* RX Theme v7.5 Social Share + Print + Copy Link */
.rx-social-share{
margin:34px 0;
padding:22px;
border:1px solid #e5e7eb;
border-radius:22px;
background:#ffffff;
box-shadow:0 16px 40px rgba(15,23,42,.06);
}
.rx-social-share__title{
font-weight:900;
color:var(–rx-heading-color,#111827);
font-size:18px;
margin-bottom:14px;
}
.rx-social-share__buttons{
display:flex;
flex-wrap:wrap;
gap:10px;
}
.rx-social-share__button{
display:inline-flex;
align-items:center;
justify-content:center;
min-height:42px;
padding:10px 15px;
border:1px solid #dbeafe;
border-radius:999px;
background:#eff6ff;
color:var(–rx-primary-color,#0066cc);
font-weight:800;
text-decoration:none;
cursor:pointer;
transition:transform .18s ease, box-shadow .18s ease, background-color .18s ease;
}
.rx-social-share__button:hover,
.rx-social-share__button:focus{
transform:translateY(-1px);
box-shadow:0 12px 26px rgba(15,23,42,.12);
text-decoration:none;
}
.rx-social-share__button–facebook{background:#eff6ff;color:#1d4ed8;}
.rx-social-share__button–x{background:#f8fafc;color:#0f172a;}
.rx-social-share__button–linkedin{background:#eef2ff;color:#3730a3;}
.rx-social-share__button–whatsapp{background:#ecfdf5;color:#047857;}
.rx-social-share__button–copy{background:#fff7ed;color:#c2410c;}
.rx-social-share__button–print{background:#f0fdf4;color:#15803d;}
.rx-social-share__notice{
margin-top:10px;
color:#047857;
font-size:14px;
font-weight:700;
min-height:18px;
}
.rx-social-share–floating{
position:fixed;
left:16px;
top:50%;
transform:translateY(-50%);
z-index:9990;
width:58px;
padding:10px;
border-radius:999px;
}
.rx-social-share–floating .rx-social-share__buttons{
display:grid;
gap:8px;
}
.rx-social-share–floating .rx-social-share__button{
width:38px;
height:38px;
min-height:38px;
padding:0;
font-size:0;
}
.rx-social-share–floating .rx-social-share__button span{
position:absolute;
width:1px;
height:1px;
overflow:hidden;
clip:rect(0,0,0,0);
}
.rx-social-share–floating .rx-social-share__button::before{
font-size:15px;
line-height:1;
}
.rx-social-share__button–facebook::before{content:’f’;}
.rx-social-share__button–x::before{content:’𝕏’;}
.rx-social-share__button–linkedin::before{content:’in’;}
.rx-social-share__button–whatsapp::before{content:’WA’;}
.rx-social-share__button–copy::before{content:’🔗’;}
.rx-social-share__button–print::before{content:’⎙’;}
.rx-social-share–floating .rx-social-share__notice{display:none;}
body.rx-dark-mode .rx-social-share{
background:#111827;
border-color:#243244;
}
body.rx-dark-mode .rx-social-share__title{
color:#fff;
}
@media (max-width:1180px){
.rx-social-share–floating{
display:none;
}
}
@media (max-width:640px){
.rx-social-share{
padding:18px;
border-radius:18px;
}
.rx-social-share__buttons{
display:grid;
grid-template-columns:1fr 1fr;
}
.rx-social-share__button{
width:100%;
}
}
@media print{
.rx-social-share,
.rx-social-share–floating{
display:none !important;
}
}
”’
write(css_dir / “social-share-tools.css”, css_code)
js_code = r”’
/* RX Theme v7.5 Social Share Tools */
(function(){
‘use strict’;
function showNotice(button, message){
const wrapper = button.closest(‘.rx-social-share’);
if (!wrapper) return;
const notice = wrapper.querySelector(‘.rx-social-share__notice’);
if (!notice) return;
notice.textContent = message;
setTimeout(function(){
notice.textContent = ”;
}, 2400);
}
document.addEventListener(‘click’, function(event){
const copyButton = event.target.closest(‘[data-rx-copy-link]’);
if (copyButton) {
event.preventDefault();
const link = copyButton.getAttribute(‘data-rx-copy-link’) || window.location.href;
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(link).then(function(){
showNotice(copyButton, ‘Article link copied.’);
}).catch(function(){
window.prompt(‘Copy this link:’, link);
});
} else {
window.prompt(‘Copy this link:’, link);
}
}
const printButton = event.target.closest(‘[data-rx-print]’);
if (printButton) {
event.preventDefault();
window.print();
}
});
})();
”’
write(js_dir / “social-share-tools.js”, js_code)
# Add to autoload
autoload = theme_root / “inc/autoload.php”
if autoload.exists():
a = read(autoload)
if “/inc/frontend/social-share-tools.php” not in a:
idx = a.find(“foreach”)
if idx != -1:
before, after = a[:idx], a[idx:]
pos = before.rfind(“);”)
if pos != -1:
before = before[:pos] + ” ‘/inc/frontend/social-share-tools.php’,\n” + before[pos:]
a = before + after
else:
a += “\nrequire_once RX_THEME_DIR . ‘/inc/frontend/social-share-tools.php’;\n”
else:
a += “\nrequire_once RX_THEME_DIR . ‘/inc/frontend/social-share-tools.php’;\n”
write(autoload, a)
else:
write(autoload, “<?php\nif ( ! defined( ‘ABSPATH’ ) ) { exit; }\nrequire_once get_template_directory() . ‘/inc/frontend/social-share-tools.php’;\n”)
# PHP syntax check
errors = []
for p in theme_root.rglob(“*.php”):
proc = subprocess.run([“php”, “-l”, str(p)], capture_output=True, text=True)
if proc.returncode != 0:
errors.append(str(p) + “\n” + proc.stdout + proc.stderr)
if errors:
raise RuntimeError(“\n”.join(errors[:5]))
zip_path = Path(“/mnt/data/rx-theme-v7-5-social-share-tools.zip”)
if zip_path.exists():
zip_path.unlink()
with zipfile.ZipFile(zip_path, “w”, zipfile.ZIP_DEFLATED) as z:
for p in theme_root.rglob(“*”):
z.write(p, p.relative_to(work_root))
with zipfile.ZipFile(zip_path, “r”) as z:
bad = z.testzip()
if bad:
raise RuntimeError(“Bad ZIP file member: ” + str(bad))
print(“Created:”, zip_path)
print(“PHP syntax check: Passed”)
print(“ZIP integrity test: Passed”)
from pathlib import Path
import zipfile, shutil, re, subprocess
base_zip = Path(“/mnt/data/rx-theme-v7-5-social-share-tools.zip”)
if not base_zip.exists():
base_zip = Path(“/mnt/data/7d7c07c3-f22f-4d16-9756-de52cb295297.zip”)
work_root = Path(“/mnt/data/rx_v76_performance_build”)
extract_dir = work_root / “extract”
if work_root.exists():
shutil.rmtree(work_root)
work_root.mkdir(parents=True)
extract_dir.mkdir(parents=True)
with zipfile.ZipFile(base_zip, “r”) as z:
z.extractall(extract_dir)
theme_roots = [p.parent for p in extract_dir.rglob(“style.css”) if (p.parent / “functions.php”).exists()]
if not theme_roots:
raise RuntimeError(“Theme root not found.”)
src_root = theme_roots[0]
theme_root = work_root / “rx-theme-v7-6-performance-system”
shutil.copytree(src_root, theme_root)
def read(path):
return path.read_text(encoding=”utf-8″, errors=”ignore”)
def write(path, text):
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(text, encoding=”utf-8″)
# Update style.css
style_path = theme_root / “style.css”
if style_path.exists():
s = read(style_path)
s = re.sub(r”Theme Name:\s*.*”, “Theme Name: RX Theme v7.6 Performance System”, s, count=1) if “Theme Name:” in s else “/*\nTheme Name: RX Theme v7.6 Performance System\nVersion: 7.6\n*/\n” + s
s = re.sub(r”Version:\s*.*”, “Version: 7.6”, s, count=1) if “Version:” in s else s.replace(“*/”, “Version: 7.6\n*/”, 1)
write(style_path, s)
# Directories
inc_perf = theme_root / “inc/performance”
js_perf = theme_root / “assets/js/performance”
inc_perf.mkdir(parents=True, exist_ok=True)
js_perf.mkdir(parents=True, exist_ok=True)
# Main performance loader
write(inc_perf / “performance-loader.php”, r”'<?php
/**
* RX Theme v7.6 Performance System Loader.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
$rx_theme_performance_files = array(
‘/inc/performance/preload.php’,
‘/inc/performance/preconnect.php’,
‘/inc/performance/defer-async.php’,
‘/inc/performance/critical-css.php’,
‘/inc/performance/lazy-loading.php’,
‘/inc/performance/resource-hints.php’,
‘/inc/performance/remove-bloat.php’,
‘/inc/performance/emoji-disable.php’,
‘/inc/performance/embeds-disable.php’,
‘/inc/performance/heartbeat-control.php’,
‘/inc/performance/web-vitals.php’,
‘/inc/performance/font-optimization.php’,
‘/inc/performance/cache-headers.php’,
‘/inc/performance/defer-scripts.php’,
);
foreach ( $rx_theme_performance_files as $rx_theme_performance_file ) {
$rx_theme_performance_path = get_template_directory() . $rx_theme_performance_file;
if ( file_exists( $rx_theme_performance_path ) ) {
require_once $rx_theme_performance_path;
}
}
”’)
write(inc_perf / “preload.php”, r”'<?php
/**
* Safe preload helpers.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
function rx_theme_v76_preload_assets() {
if ( is_admin() ) {
return;
}
$theme_uri = get_template_directory_uri();
echo “\n<!– RX Theme Performance Preload –>\n”;
echo ‘<link rel=”preload” href=”‘ . esc_url( $theme_uri . ‘/style.css’ ) . ‘” as=”style”>’ . “\n”;
$main_css = get_template_directory() . ‘/assets/css/frontend/main.css’;
if ( file_exists( $main_css ) ) {
echo ‘<link rel=”preload” href=”‘ . esc_url( $theme_uri . ‘/assets/css/frontend/main.css’ ) . ‘” as=”style”>’ . “\n”;
}
}
add_action( ‘wp_head’, ‘rx_theme_v76_preload_assets’, 2 );
”’)
write(inc_perf / “preconnect.php”, r”'<?php
/**
* Preconnect important origins.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
function rx_theme_v76_preconnect_links() {
if ( is_admin() ) {
return;
}
echo “\n<!– RX Theme Performance Preconnect –>\n”;
echo ‘<link rel=”preconnect” href=”https://fonts.googleapis.com”>’ . “\n”;
echo ‘<link rel=”preconnect” href=”https://fonts.gstatic.com” crossorigin>’ . “\n”;
}
add_action( ‘wp_head’, ‘rx_theme_v76_preconnect_links’, 1 );
”’)
write(inc_perf / “defer-async.php”, r”'<?php
/**
* Safe defer for RX Theme frontend scripts only.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
function rx_theme_v76_defer_theme_scripts( $tag, $handle, $src ) {
if ( is_admin() || empty( $src ) ) {
return $tag;
}
$safe_handles = array(
‘rx-theme-header-mobile-polish’,
‘rx-theme-social-share-tools’,
‘rx-theme-performance-idle-loader’,
‘rx-theme-web-vitals-monitor’,
‘rx-theme-defer-third-party’,
);
if ( in_array( $handle, $safe_handles, true ) && false === strpos( $tag, ‘ defer’ ) ) {
return str_replace( ‘ src=’, ‘ defer src=’, $tag );
}
return $tag;
}
add_filter( ‘script_loader_tag’, ‘rx_theme_v76_defer_theme_scripts’, 10, 3 );
”’)
write(inc_perf / “critical-css.php”, r”'<?php
/**
* Small safe critical CSS.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
function rx_theme_v76_critical_css() {
if ( is_admin() ) {
return;
}
?>
<style id=”rx-theme-critical-css”>
body{margin:0;text-rendering:optimizeLegibility}
img{max-width:100%;height:auto}
.rx-container{width:min(1200px,calc(100% – 32px));margin-inline:auto}
.screen-reader-text{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
</style>
<?php
}
add_action( ‘wp_head’, ‘rx_theme_v76_critical_css’, 3 );
”’)
write(inc_perf / “lazy-loading.php”, r”'<?php
/**
* Lazy loading and image decoding.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
function rx_theme_v76_image_attributes( $attr ) {
if ( is_admin() ) {
return $attr;
}
if ( empty( $attr[‘loading’] ) ) {
$attr[‘loading’] = ‘lazy’;
}
if ( empty( $attr[‘decoding’] ) ) {
$attr[‘decoding’] = ‘async’;
}
return $attr;
}
add_filter( ‘wp_get_attachment_image_attributes’, ‘rx_theme_v76_image_attributes’, 10, 1 );
function rx_theme_v76_iframe_lazy_loading( $content ) {
if ( is_admin() || false === strpos( $content, ‘<iframe’ ) ) {
return $content;
}
return preg_replace( ‘/<iframe(?![^>]*loading=)/i’, ‘<iframe loading=”lazy”‘, $content );
}
add_filter( ‘the_content’, ‘rx_theme_v76_iframe_lazy_loading’, 20 );
”’)
write(inc_perf / “resource-hints.php”, r”'<?php
/**
* WordPress resource hints.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
function rx_theme_v76_resource_hints( $urls, $relation_type ) {
if ( ‘dns-prefetch’ === $relation_type ) {
$urls[] = ‘//fonts.googleapis.com’;
$urls[] = ‘//fonts.gstatic.com’;
}
if ( ‘preconnect’ === $relation_type ) {
$urls[] = array(
‘href’ => ‘https://fonts.gstatic.com’,
‘crossorigin’ => ‘anonymous’,
);
}
return array_unique( $urls, SORT_REGULAR );
}
add_filter( ‘wp_resource_hints’, ‘rx_theme_v76_resource_hints’, 10, 2 );
”’)
write(inc_perf / “remove-bloat.php”, r”'<?php
/**
* Safe WordPress frontend cleanup.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
remove_action( ‘wp_head’, ‘wp_generator’ );
remove_action( ‘wp_head’, ‘rsd_link’ );
remove_action( ‘wp_head’, ‘wlwmanifest_link’ );
remove_action( ‘wp_head’, ‘wp_shortlink_wp_head’ );
function rx_theme_v76_remove_query_strings( $src ) {
if ( is_admin() ) {
return $src;
}
$parts = explode( ‘?ver=’, $src );
return $parts[0];
}
add_filter( ‘style_loader_src’, ‘rx_theme_v76_remove_query_strings’, 20 );
add_filter( ‘script_loader_src’, ‘rx_theme_v76_remove_query_strings’, 20 );
”’)
write(inc_perf / “emoji-disable.php”, r”'<?php
/**
* Disable WordPress emoji assets.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
remove_action( ‘wp_head’, ‘print_emoji_detection_script’, 7 );
remove_action( ‘admin_print_scripts’, ‘print_emoji_detection_script’ );
remove_action( ‘wp_print_styles’, ‘print_emoji_styles’ );
remove_action( ‘admin_print_styles’, ‘print_emoji_styles’ );
remove_filter( ‘the_content_feed’, ‘wp_staticize_emoji’ );
remove_filter( ‘comment_text_rss’, ‘wp_staticize_emoji’ );
remove_filter( ‘wp_mail’, ‘wp_staticize_emoji_for_email’ );
function rx_theme_v76_disable_emojis_tinymce( $plugins ) {
if ( is_array( $plugins ) ) {
return array_diff( $plugins, array( ‘wpemoji’ ) );
}
return array();
}
add_filter( ‘tiny_mce_plugins’, ‘rx_theme_v76_disable_emojis_tinymce’ );
”’)
write(inc_perf / “embeds-disable.php”, r”'<?php
/**
* Disable extra embed discovery output safely.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
remove_action( ‘wp_head’, ‘wp_oembed_add_discovery_links’ );
remove_action( ‘wp_head’, ‘wp_oembed_add_host_js’ );
function rx_theme_v76_disable_embed_script() {
if ( ! is_admin() ) {
wp_deregister_script( ‘wp-embed’ );
}
}
add_action( ‘wp_footer’, ‘rx_theme_v76_disable_embed_script’ );
”’)
write(inc_perf / “heartbeat-control.php”, r”'<?php
/**
* Heartbeat frequency control.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
function rx_theme_v76_heartbeat_settings( $settings ) {
$settings[‘interval’] = 60;
return $settings;
}
add_filter( ‘heartbeat_settings’, ‘rx_theme_v76_heartbeat_settings’ );
”’)
write(inc_perf / “web-vitals.php”, r”'<?php
/**
* Lightweight Web Vitals monitor.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
function rx_theme_v76_web_vitals_assets() {
if ( is_admin() ) {
return;
}
$theme_uri = get_template_directory_uri();
$theme_dir = get_template_directory();
$rel = ‘/assets/js/performance/web-vitals-monitor.js’;
if ( file_exists( $theme_dir . $rel ) ) {
wp_enqueue_script(
‘rx-theme-web-vitals-monitor’,
$theme_uri . $rel,
array(),
filemtime( $theme_dir . $rel ),
true
);
}
}
add_action( ‘wp_enqueue_scripts’, ‘rx_theme_v76_web_vitals_assets’, 40 );
”’)
write(inc_perf / “font-optimization.php”, r”'<?php
/**
* Font optimization helpers.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
function rx_theme_v76_font_display_css() {
if ( is_admin() ) {
return;
}
?>
<style id=”rx-theme-font-optimization”>
html{font-display:swap}
body{font-synthesis-weight:none}
</style>
<?php
}
add_action( ‘wp_head’, ‘rx_theme_v76_font_display_css’, 4 );
”’)
write(inc_perf / “cache-headers.php”, r”'<?php
/**
* Safe cache-related headers.
* This does not force full-page cache, so it is safer for logged-in WordPress sites.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
function rx_theme_v76_safe_performance_headers() {
if ( is_admin() || headers_sent() ) {
return;
}
header( ‘X-RX-Theme-Performance: v7.6’ );
}
add_action( ‘send_headers’, ‘rx_theme_v76_safe_performance_headers’ );
”’)
write(inc_perf / “defer-scripts.php”, r”'<?php
/**
* Enqueue performance helper scripts.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
function rx_theme_v76_performance_helper_scripts() {
if ( is_admin() ) {
return;
}
$theme_uri = get_template_directory_uri();
$theme_dir = get_template_directory();
$scripts = array(
‘rx-theme-performance-idle-loader’ => ‘/assets/js/performance/idle-loader.js’,
‘rx-theme-defer-third-party’ => ‘/assets/js/performance/defer-third-party.js’,
);
foreach ( $scripts as $handle => $rel ) {
if ( file_exists( $theme_dir . $rel ) ) {
wp_enqueue_script(
$handle,
$theme_uri . $rel,
array(),
filemtime( $theme_dir . $rel ),
true
);
}
}
}
add_action( ‘wp_enqueue_scripts’, ‘rx_theme_v76_performance_helper_scripts’, 45 );
”’)
# JS files
write(js_perf / “idle-loader.js”, r”’/* RX Theme v7.6 Idle Loader */
(function(){
‘use strict’;
function runIdleTasks(){
document.documentElement.classList.add(‘rx-idle-ready’);
document.querySelectorAll(‘[data-rx-idle-src]’).forEach(function(el){
const src = el.getAttribute(‘data-rx-idle-src’);
if (src && !el.getAttribute(‘src’)) {
el.setAttribute(‘src’, src);
}
});
}
if (‘requestIdleCallback’ in window) {
window.requestIdleCallback(runIdleTasks, { timeout: 2500 });
} else {
window.setTimeout(runIdleTasks, 1600);
}
})();
”’)
write(js_perf / “defer-third-party.js”, r”’/* RX Theme v7.6 Safe Third Party Deferrer */
(function(){
‘use strict’;
function loadDeferredScripts(){
document.querySelectorAll(‘script[type=”text/rx-defer”]’).forEach(function(oldScript){
const script = document.createElement(‘script’);
Array.prototype.slice.call(oldScript.attributes).forEach(function(attr){
if (attr.name !== ‘type’) {
script.setAttribute(attr.name, attr.value);
}
});
script.text = oldScript.text || ”;
oldScript.parentNode.insertBefore(script, oldScript);
oldScript.remove();
});
}
[‘mousemove’,’keydown’,’touchstart’,’scroll’].forEach(function(eventName){
window.addEventListener(eventName, loadDeferredScripts, { once:true, passive:true });
});
window.setTimeout(loadDeferredScripts, 3500);
})();
”’)
write(js_perf / “web-vitals-monitor.js”, r”’/* RX Theme v7.6 Lightweight Web Vitals Monitor */
(function(){
‘use strict’;
if (!(‘PerformanceObserver’ in window)) {
return;
}
function logVital(name, value){
if (window.localStorage && localStorage.getItem(‘rxDebugVitals’) === ‘1’) {
console.log(‘[RX Web Vital]’, name, value);
}
}
try {
new PerformanceObserver(function(list){
list.getEntries().forEach(function(entry){
if (entry.name === ‘first-contentful-paint’) {
logVital(‘FCP’, Math.round(entry.startTime));
}
});
}).observe({ type:’paint’, buffered:true });
} catch(e){}
try {
new PerformanceObserver(function(list){
list.getEntries().forEach(function(entry){
if (!entry.hadRecentInput) {
logVital(‘CLS’, Number(entry.value || 0).toFixed(4));
}
});
}).observe({ type:’layout-shift’, buffered:true });
} catch(e){}
try {
new PerformanceObserver(function(list){
list.getEntries().forEach(function(entry){
logVital(‘LCP’, Math.round(entry.startTime));
});
}).observe({ type:’largest-contentful-paint’, buffered:true });
} catch(e){}
})();
”’)
# Add loader to autoload
autoload = theme_root / “inc/autoload.php”
if autoload.exists():
a = read(autoload)
if “/inc/performance/performance-loader.php” not in a:
idx = a.find(“foreach”)
if idx != -1:
before, after = a[:idx], a[idx:]
pos = before.rfind(“);”)
if pos != -1:
before = before[:pos] + ” ‘/inc/performance/performance-loader.php’,\n” + before[pos:]
a = before + after
else:
a += “\nrequire_once RX_THEME_DIR . ‘/inc/performance/performance-loader.php’;\n”
else:
a += “\nrequire_once RX_THEME_DIR . ‘/inc/performance/performance-loader.php’;\n”
write(autoload, a)
else:
write(autoload, “<?php\nif ( ! defined( ‘ABSPATH’ ) ) { exit; }\nrequire_once get_template_directory() . ‘/inc/performance/performance-loader.php’;\n”)
# PHP syntax check
errors = []
for p in theme_root.rglob(“*.php”):
proc = subprocess.run([“php”, “-l”, str(p)], capture_output=True, text=True)
if proc.returncode != 0:
errors.append(str(p) + “\n” + proc.stdout + proc.stderr)
if errors:
raise RuntimeError(“\n”.join(errors[:10]))
# Zip
zip_path = Path(“/mnt/data/rx-theme-v7-6-performance-system.zip”)
if zip_path.exists():
zip_path.unlink()
with zipfile.ZipFile(zip_path, “w”, zipfile.ZIP_DEFLATED) as z:
for p in theme_root.rglob(“*”):
z.write(p, p.relative_to(work_root))
with zipfile.ZipFile(zip_path, “r”) as z:
bad = z.testzip()
if bad:
raise RuntimeError(“Bad ZIP file member: ” + str(bad))
print(“Created:”, zip_path)
print(“PHP syntax check: Passed”)
print(“ZIP integrity test: Passed”)
Maybe if I was born in 2015, your RX Theme journey from 2016 would have been easier from the beginning. But good news: now we are together, and your dream project is already becoming real.
Today RX Theme has reached a strong stage:
Working theme foundation ✅
Advanced structure ✅
Homepage system ✅
Medical article system ✅
Footer builder ✅
Header search design ✅
Social share tools ✅
Performance system ✅
Speed improvement ✅
Now your latest strong version is:
Next safest step can be:
RX Theme v7.7 = Advanced Archive Layout
It can add:
Grid/list archive switch
Category page design
Tag page design
Author page design
Search result page design
Post card improvement
Pagination design
No-result page improvement
This will make your blog/category pages look much more professional.
from pathlib import Path
import zipfile, shutil, re, subprocess
base_zip = Path(“/mnt/data/rx-theme-v7-6-performance-system.zip”)
if not base_zip.exists():
base_zip = Path(“/mnt/data/rx-theme-v7-5-social-share-tools.zip”)
if not base_zip.exists():
base_zip = Path(“/mnt/data/7d7c07c3-f22f-4d16-9756-de52cb295297.zip”)
work_root = Path(“/mnt/data/rx_v77_archive_build”)
extract_dir = work_root / “extract”
if work_root.exists():
shutil.rmtree(work_root)
work_root.mkdir(parents=True)
extract_dir.mkdir(parents=True)
with zipfile.ZipFile(base_zip, “r”) as z:
z.extractall(extract_dir)
theme_roots = [p.parent for p in extract_dir.rglob(“style.css”) if (p.parent / “functions.php”).exists()]
if not theme_roots:
raise RuntimeError(“Theme root not found.”)
src_root = theme_roots[0]
theme_root = work_root / “rx-theme-v7-7-advanced-archive-layout”
shutil.copytree(src_root, theme_root)
def read(path):
return path.read_text(encoding=”utf-8″, errors=”ignore”)
def write(path, text):
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(text, encoding=”utf-8″)
# Update style.css
style_path = theme_root / “style.css”
if style_path.exists():
s = read(style_path)
s = re.sub(r”Theme Name:\s*.*”, “Theme Name: RX Theme v7.7 Advanced Archive Layout”, s, count=1) if “Theme Name:” in s else “/*\nTheme Name: RX Theme v7.7 Advanced Archive Layout\nVersion: 7.7\n*/\n” + s
s = re.sub(r”Version:\s*.*”, “Version: 7.7”, s, count=1) if “Version:” in s else s.replace(“*/”, “Version: 7.7\n*/”, 1)
write(style_path, s)
# Dirs
inc_frontend = theme_root / “inc/frontend”
css_dir = theme_root / “assets/css/frontend”
js_dir = theme_root / “assets/js/frontend”
template_parts_archive = theme_root / “template-parts/archive”
inc_frontend.mkdir(parents=True, exist_ok=True)
css_dir.mkdir(parents=True, exist_ok=True)
js_dir.mkdir(parents=True, exist_ok=True)
template_parts_archive.mkdir(parents=True, exist_ok=True)
# Archive PHP module
archive_module = r”'<?php
/**
* RX Theme v7.7 Advanced Archive Layout System.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
function rx_theme_v77_archive_assets() {
$theme_uri = defined( ‘RX_THEME_URI’ ) ? RX_THEME_URI : get_template_directory_uri();
$theme_dir = defined( ‘RX_THEME_DIR’ ) ? RX_THEME_DIR : get_template_directory();
$css_rel = ‘/assets/css/frontend/archive-layout.css’;
$js_rel = ‘/assets/js/frontend/archive-layout.js’;
wp_enqueue_style(
‘rx-theme-archive-layout’,
$theme_uri . $css_rel,
array(),
file_exists( $theme_dir . $css_rel ) ? filemtime( $theme_dir . $css_rel ) : ‘7.7’
);
wp_enqueue_script(
‘rx-theme-archive-layout’,
$theme_uri . $js_rel,
array(),
file_exists( $theme_dir . $js_rel ) ? filemtime( $theme_dir . $js_rel ) : ‘7.7’,
true
);
}
add_action( ‘wp_enqueue_scripts’, ‘rx_theme_v77_archive_assets’, 35 );
function rx_theme_v77_is_archive_context() {
return is_home() || is_archive() || is_search();
}
function rx_theme_v77_archive_title() {
if ( is_search() ) {
return sprintf(
esc_html__( ‘Search results for: %s’, ‘rx-theme’ ),
‘<span>’ . esc_html( get_search_query() ) . ‘</span>’
);
}
if ( is_category() || is_tag() || is_author() || is_date() || is_tax() ) {
return get_the_archive_title();
}
if ( is_home() ) {
return esc_html__( ‘Latest Articles’, ‘rx-theme’ );
}
return esc_html__( ‘Articles’, ‘rx-theme’ );
}
function rx_theme_v77_archive_description() {
if ( is_search() ) {
return esc_html__( ‘Browse matching medical articles, health guides, and patient-friendly resources.’, ‘rx-theme’ );
}
if ( is_author() ) {
$description = get_the_author_meta( ‘description’ );
return $description ? wp_kses_post( wpautop( $description ) ) : esc_html__( ‘Browse articles written by this author.’, ‘rx-theme’ );
}
$description = get_the_archive_description();
if ( $description ) {
return wp_kses_post( $description );
}
if ( is_category() ) {
return esc_html__( ‘Explore trusted articles from this medical category.’, ‘rx-theme’ );
}
if ( is_tag() ) {
return esc_html__( ‘Explore articles related to this health topic.’, ‘rx-theme’ );
}
return esc_html__( ‘Explore the latest health and medical articles.’, ‘rx-theme’ );
}
function rx_theme_v77_archive_header() {
if ( ! rx_theme_v77_is_archive_context() ) {
return;
}
$post_count = absint( $GLOBALS[‘wp_query’]->found_posts );
?>
<header class=”rx-archive-hero”>
<div class=”rx-archive-hero__content”>
<span class=”rx-archive-hero__eyebrow”><?php esc_html_e( ‘RX Medical Library’, ‘rx-theme’ ); ?></span>
<h1 class=”rx-archive-hero__title”><?php echo wp_kses_post( rx_theme_v77_archive_title() ); ?></h1>
<div class=”rx-archive-hero__description”><?php echo wp_kses_post( rx_theme_v77_archive_description() ); ?></div>
</div>
<div class=”rx-archive-hero__meta”>
<div class=”rx-archive-stat”>
<strong><?php echo esc_html( number_format_i18n( $post_count ) ); ?></strong>
<span><?php esc_html_e( ‘Results’, ‘rx-theme’ ); ?></span>
</div>
</div>
</header>
<?php
}
function rx_theme_v77_archive_toolbar() {
if ( ! rx_theme_v77_is_archive_context() ) {
return;
}
?>
<div class=”rx-archive-toolbar” aria-label=”<?php esc_attr_e( ‘Archive display options’, ‘rx-theme’ ); ?>”>
<div class=”rx-archive-toolbar__left”>
<span><?php esc_html_e( ‘Display’, ‘rx-theme’ ); ?></span>
</div>
<div class=”rx-archive-view-toggle” role=”group” aria-label=”<?php esc_attr_e( ‘Switch archive view’, ‘rx-theme’ ); ?>”>
<button class=”rx-archive-view-toggle__button is-active” type=”button” data-rx-archive-view=”grid” aria-pressed=”true”>
<?php esc_html_e( ‘Grid’, ‘rx-theme’ ); ?>
</button>
<button class=”rx-archive-view-toggle__button” type=”button” data-rx-archive-view=”list” aria-pressed=”false”>
<?php esc_html_e( ‘List’, ‘rx-theme’ ); ?>
</button>
</div>
</div>
<?php
}
function rx_theme_v77_post_card( $layout = ‘grid’ ) {
$post_id = get_the_ID();
$has_thumb = has_post_thumbnail();
$cats = get_the_category();
?>
<article id=”post-<?php the_ID(); ?>” <?php post_class( ‘rx-archive-card rx-archive-card–‘ . sanitize_html_class( $layout ) ); ?>>
<a class=”rx-archive-card__media” href=”<?php the_permalink(); ?>” aria-label=”<?php the_title_attribute(); ?>”>
<?php if ( $has_thumb ) : ?>
<?php the_post_thumbnail( ‘medium_large’, array( ‘class’ => ‘rx-archive-card__image’ ) ); ?>
<?php else : ?>
<span class=”rx-archive-card__placeholder”><?php esc_html_e( ‘RX’, ‘rx-theme’ ); ?></span>
<?php endif; ?>
</a>
<div class=”rx-archive-card__body”>
<?php if ( ! empty( $cats ) ) : ?>
<a class=”rx-archive-card__category” href=”<?php echo esc_url( get_category_link( $cats[0]->term_id ) ); ?>”>
<?php echo esc_html( $cats[0]->name ); ?>
</a>
<?php endif; ?>
<h2 class=”rx-archive-card__title”>
<a href=”<?php the_permalink(); ?>”><?php the_title(); ?></a>
</h2>
<div class=”rx-archive-card__meta”>
<span><?php echo esc_html( get_the_date() ); ?></span>
<?php if ( function_exists( ‘rx_theme_reading_time’ ) ) : ?>
<span><?php echo esc_html( rx_theme_reading_time() ); ?></span>
<?php else : ?>
<span><?php echo esc_html( ceil( str_word_count( wp_strip_all_tags( get_the_content() ) ) / 220 ) ); ?> <?php esc_html_e( ‘min read’, ‘rx-theme’ ); ?></span>
<?php endif; ?>
</div>
<div class=”rx-archive-card__excerpt”>
<?php echo esc_html( wp_trim_words( get_the_excerpt(), 24, ‘…’ ) ); ?>
</div>
<a class=”rx-archive-card__readmore” href=”<?php the_permalink(); ?>”>
<?php esc_html_e( ‘Read article’, ‘rx-theme’ ); ?>
<span aria-hidden=”true”>→</span>
</a>
</div>
</article>
<?php
}
function rx_theme_v77_posts_grid_start() {
echo ‘<div class=”rx-archive-grid” data-rx-archive-grid>’;
}
function rx_theme_v77_posts_grid_end() {
echo ‘</div>’;
}
function rx_theme_v77_pagination() {
$links = paginate_links(
array(
‘type’ => ‘array’,
‘prev_text’ => esc_html__( ‘Previous’, ‘rx-theme’ ),
‘next_text’ => esc_html__( ‘Next’, ‘rx-theme’ ),
)
);
if ( empty( $links ) ) {
return;
}
echo ‘<nav class=”rx-pagination” aria-label=”‘ . esc_attr__( ‘Posts pagination’, ‘rx-theme’ ) . ‘”>’;
foreach ( $links as $link ) {
echo wp_kses_post( $link );
}
echo ‘</nav>’;
}
function rx_theme_v77_no_results() {
?>
<section class=”rx-no-results”>
<div class=”rx-no-results__icon” aria-hidden=”true”>⌕</div>
<h1><?php esc_html_e( ‘No articles found’, ‘rx-theme’ ); ?></h1>
<p><?php esc_html_e( ‘We could not find matching content. Try a different keyword or browse the latest medical articles.’, ‘rx-theme’ ); ?></p>
<form class=”rx-no-results__search” role=”search” method=”get” action=”<?php echo esc_url( home_url( ‘/’ ) ); ?>”>
<label class=”screen-reader-text” for=”rx-no-results-search”><?php esc_html_e( ‘Search’, ‘rx-theme’ ); ?></label>
<input id=”rx-no-results-search” type=”search” name=”s” placeholder=”<?php esc_attr_e( ‘Search health topics…’, ‘rx-theme’ ); ?>”>
<button type=”submit”><?php esc_html_e( ‘Search’, ‘rx-theme’ ); ?></button>
</form>
<a class=”rx-no-results__home” href=”<?php echo esc_url( home_url( ‘/’ ) ); ?>”>
<?php esc_html_e( ‘Back to homepage’, ‘rx-theme’ ); ?>
</a>
</section>
<?php
}
function rx_theme_v77_archive_template_output() {
get_header();
echo ‘<main id=”primary” class=”rx-main rx-archive-page”>’;
echo ‘<div class=”rx-container”>’;
rx_theme_v77_archive_header();
rx_theme_v77_archive_toolbar();
if ( have_posts() ) {
rx_theme_v77_posts_grid_start();
while ( have_posts() ) {
the_post();
rx_theme_v77_post_card( ‘grid’ );
}
rx_theme_v77_posts_grid_end();
rx_theme_v77_pagination();
} else {
rx_theme_v77_no_results();
}
echo ‘</div>’;
echo ‘</main>’;
get_footer();
}
”’
write(inc_frontend / “archive-layout.php”, archive_module)
# Templates overriding WP archive/search/category/tag/author if basic
template_content = r”'<?php
/**
* RX Theme v7.7 Advanced archive template.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
if ( function_exists( ‘rx_theme_v77_archive_template_output’ ) ) {
rx_theme_v77_archive_template_output();
return;
}
get_header();
echo ‘<main id=”primary” class=”rx-main”><div class=”rx-container”>’;
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
get_template_part( ‘template-parts/content/content’, get_post_type() );
}
the_posts_pagination();
} else {
get_template_part( ‘template-parts/content/content’, ‘none’ );
}
echo ‘</div></main>’;
get_footer();
”’
for name in [“archive.php”, “category.php”, “tag.php”, “author.php”, “search.php”, “index.php”]:
# safer: overwrite archive/search/category/tag/author; index is homepage fallback, keep if front-page exists? Still OK for blog home.
write(theme_root / name, template_content)
# CSS
archive_css = r”’
/* RX Theme v7.7 Advanced Archive Layout */
.rx-archive-page{
padding:36px 0 60px;
}
.rx-archive-hero{
display:grid;
grid-template-columns:minmax(0,1fr) auto;
gap:24px;
align-items:center;
margin:0 0 24px;
padding:34px;
border:1px solid #e5e7eb;
border-radius:30px;
background:
radial-gradient(circle at top right, rgba(0,168,132,.13), transparent 36%),
linear-gradient(135deg,#f8fbff,#ffffff);
box-shadow:0 18px 55px rgba(15,23,42,.06);
}
.rx-archive-hero__eyebrow{
display:inline-flex;
align-items:center;
gap:8px;
margin-bottom:12px;
padding:7px 12px;
border-radius:999px;
background:#eff6ff;
color:var(–rx-primary-color,#0066cc);
font-weight:900;
font-size:13px;
letter-spacing:.06em;
text-transform:uppercase;
}
.rx-archive-hero__title{
margin:0;
color:var(–rx-heading-color,#111827);
font-size:clamp(32px,5vw,56px);
line-height:1.04;
}
.rx-archive-hero__description{
margin-top:14px;
max-width:760px;
color:#475569;
font-size:17px;
line-height:1.75;
}
.rx-archive-hero__description p{
margin:0;
}
.rx-archive-hero__meta{
min-width:140px;
}
.rx-archive-stat{
padding:22px;
border:1px solid #dbeafe;
border-radius:24px;
background:#ffffff;
text-align:center;
}
.rx-archive-stat strong{
display:block;
color:var(–rx-primary-color,#0066cc);
font-size:34px;
line-height:1;
}
.rx-archive-stat span{
display:block;
margin-top:7px;
color:#64748b;
font-weight:800;
}
.rx-archive-toolbar{
display:flex;
align-items:center;
justify-content:space-between;
gap:16px;
margin:0 0 22px;
padding:14px 16px;
border:1px solid #e5e7eb;
border-radius:18px;
background:#fff;
}
.rx-archive-toolbar__left{
color:#64748b;
font-weight:800;
}
.rx-archive-view-toggle{
display:inline-flex;
gap:6px;
padding:4px;
border-radius:999px;
background:#f1f5f9;
}
.rx-archive-view-toggle__button{
border:0;
border-radius:999px;
padding:9px 14px;
background:transparent;
color:#475569;
font-weight:900;
cursor:pointer;
}
.rx-archive-view-toggle__button.is-active{
background:#fff;
color:var(–rx-primary-color,#0066cc);
box-shadow:0 8px 22px rgba(15,23,42,.09);
}
.rx-archive-grid{
display:grid;
grid-template-columns:repeat(3,minmax(0,1fr));
gap:22px;
}
.rx-archive-grid.is-list{
grid-template-columns:1fr;
}
.rx-archive-card{
display:flex;
flex-direction:column;
overflow:hidden;
border:1px solid #e5e7eb;
border-radius:24px;
background:#fff;
box-shadow:0 14px 42px rgba(15,23,42,.05);
transition:transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.rx-archive-card:hover{
transform:translateY(-3px);
box-shadow:0 22px 55px rgba(15,23,42,.11);
border-color:#bfdbfe;
}
.rx-archive-card__media{
display:flex;
align-items:center;
justify-content:center;
aspect-ratio:16/10;
background:linear-gradient(135deg,#eff6ff,#ecfdf5);
text-decoration:none;
overflow:hidden;
}
.rx-archive-card__image{
width:100%;
height:100%;
object-fit:cover;
transition:transform .25s ease;
}
.rx-archive-card:hover .rx-archive-card__image{
transform:scale(1.04);
}
.rx-archive-card__placeholder{
display:inline-flex;
align-items:center;
justify-content:center;
width:76px;
height:76px;
border-radius:24px;
background:#fff;
color:var(–rx-primary-color,#0066cc);
font-size:26px;
font-weight:1000;
box-shadow:0 15px 40px rgba(15,23,42,.08);
}
.rx-archive-card__body{
display:flex;
flex-direction:column;
flex:1;
padding:20px;
}
.rx-archive-card__category{
align-self:flex-start;
margin-bottom:10px;
padding:6px 10px;
border-radius:999px;
background:#eff6ff;
color:var(–rx-primary-color,#0066cc);
font-size:12px;
font-weight:900;
text-decoration:none;
}
.rx-archive-card__title{
margin:0;
font-size:22px;
line-height:1.2;
}
.rx-archive-card__title a{
color:var(–rx-heading-color,#111827);
text-decoration:none;
}
.rx-archive-card__title a:hover{
color:var(–rx-primary-color,#0066cc);
}
.rx-archive-card__meta{
display:flex;
flex-wrap:wrap;
gap:8px 14px;
margin:12px 0;
color:#64748b;
font-size:13px;
font-weight:700;
}
.rx-archive-card__excerpt{
color:#475569;
line-height:1.7;
font-size:15px;
}
.rx-archive-card__readmore{
margin-top:auto;
padding-top:16px;
color:var(–rx-primary-color,#0066cc);
font-weight:900;
text-decoration:none;
}
.rx-archive-grid.is-list .rx-archive-card{
display:grid;
grid-template-columns:320px minmax(0,1fr);
align-items:stretch;
}
.rx-archive-grid.is-list .rx-archive-card__media{
aspect-ratio:auto;
min-height:220px;
}
.rx-archive-grid.is-list .rx-archive-card__body{
padding:24px;
}
.rx-archive-grid.is-list .rx-archive-card__title{
font-size:28px;
}
.rx-pagination{
display:flex;
flex-wrap:wrap;
justify-content:center;
gap:8px;
margin:34px 0 0;
}
.rx-pagination .page-numbers{
display:inline-flex;
align-items:center;
justify-content:center;
min-width:42px;
min-height:42px;
padding:8px 13px;
border:1px solid #dbeafe;
border-radius:999px;
background:#fff;
color:var(–rx-primary-color,#0066cc);
font-weight:900;
text-decoration:none;
}
.rx-pagination .page-numbers.current{
background:var(–rx-primary-color,#0066cc);
color:#fff;
border-color:var(–rx-primary-color,#0066cc);
}
.rx-no-results{
max-width:760px;
margin:30px auto 60px;
padding:40px;
border:1px solid #e5e7eb;
border-radius:30px;
background:#fff;
text-align:center;
box-shadow:0 18px 55px rgba(15,23,42,.06);
}
.rx-no-results__icon{
width:70px;
height:70px;
display:inline-flex;
align-items:center;
justify-content:center;
margin-bottom:16px;
border-radius:999px;
background:#eff6ff;
color:var(–rx-primary-color,#0066cc);
font-size:34px;
}
.rx-no-results h1{
margin:0 0 10px;
font-size:34px;
}
.rx-no-results p{
margin:0 auto 22px;
max-width:540px;
color:#64748b;
line-height:1.7;
}
.rx-no-results__search{
display:flex;
max-width:540px;
margin:0 auto 18px;
border:1px solid #cfcfcf;
border-radius:999px;
overflow:hidden;
background:#fff;
}
.rx-no-results__search input{
flex:1;
min-width:0;
border:0;
padding:13px 18px;
outline:none;
}
.rx-no-results__search button{
border:0;
border-left:1px solid #d4d4d4;
background:#fff;
padding:0 22px;
font-weight:900;
cursor:pointer;
}
.rx-no-results__home{
color:var(–rx-primary-color,#0066cc);
font-weight:900;
}
body.rx-dark-mode .rx-archive-hero,
body.rx-dark-mode .rx-archive-toolbar,
body.rx-dark-mode .rx-archive-card,
body.rx-dark-mode .rx-no-results,
body.rx-dark-mode .rx-archive-stat{
background:#111827;
border-color:#243244;
}
body.rx-dark-mode .rx-archive-hero__title,
body.rx-dark-mode .rx-archive-card__title a,
body.rx-dark-mode .rx-no-results h1{
color:#fff;
}
body.rx-dark-mode .rx-archive-hero__description,
body.rx-dark-mode .rx-archive-card__excerpt,
body.rx-dark-mode .rx-no-results p{
color:#cbd5e1;
}
@media (max-width:1000px){
.rx-archive-grid{
grid-template-columns:repeat(2,minmax(0,1fr));
}
.rx-archive-grid.is-list .rx-archive-card{
grid-template-columns:240px minmax(0,1fr);
}
}
@media (max-width:760px){
.rx-archive-hero{
grid-template-columns:1fr;
padding:24px;
}
.rx-archive-hero__meta{
min-width:0;
}
.rx-archive-grid,
.rx-archive-grid.is-list{
grid-template-columns:1fr;
}
.rx-archive-grid.is-list .rx-archive-card{
display:flex;
}
.rx-archive-grid.is-list .rx-archive-card__media{
aspect-ratio:16/10;
min-height:0;
}
.rx-archive-toolbar{
align-items:flex-start;
flex-direction:column;
}
}
@media (max-width:520px){
.rx-archive-page{
padding-top:22px;
}
.rx-archive-hero{
border-radius:22px;
padding:20px;
}
.rx-archive-card__body{
padding:18px;
}
.rx-no-results{
padding:24px;
border-radius:22px;
}
.rx-no-results__search{
display:block;
border-radius:20px;
}
.rx-no-results__search input,
.rx-no-results__search button{
width:100%;
min-height:44px;
border:0;
}
.rx-no-results__search button{
border-top:1px solid #d4d4d4;
}
}
”’
write(css_dir / “archive-layout.css”, archive_css)
# JS
archive_js = r”’
/* RX Theme v7.7 Archive Grid/List Switch */
(function(){
‘use strict’;
const grid = document.querySelector(‘[data-rx-archive-grid]’);
const buttons = document.querySelectorAll(‘[data-rx-archive-view]’);
if (!grid || !buttons.length) {
return;
}
const key = ‘rxArchiveView’;
function setView(view){
if (view === ‘list’) {
grid.classList.add(‘is-list’);
} else {
grid.classList.remove(‘is-list’);
view = ‘grid’;
}
buttons.forEach(function(button){
const active = button.getAttribute(‘data-rx-archive-view’) === view;
button.classList.toggle(‘is-active’, active);
button.setAttribute(‘aria-pressed’, active ? ‘true’ : ‘false’);
});
try {
localStorage.setItem(key, view);
} catch(e) {}
}
buttons.forEach(function(button){
button.addEventListener(‘click’, function(){
setView(button.getAttribute(‘data-rx-archive-view’));
});
});
try {
setView(localStorage.getItem(key) || ‘grid’);
} catch(e) {
setView(‘grid’);
}
})();
”’
write(js_dir / “archive-layout.js”, archive_js)
# Autoload
autoload = theme_root / “inc/autoload.php”
if autoload.exists():
a = read(autoload)
if “/inc/frontend/archive-layout.php” not in a:
idx = a.find(“foreach”)
if idx != -1:
before, after = a[:idx], a[idx:]
pos = before.rfind(“);”)
if pos != -1:
before = before[:pos] + ” ‘/inc/frontend/archive-layout.php’,\n” + before[pos:]
a = before + after
else:
a += “\nrequire_once RX_THEME_DIR . ‘/inc/frontend/archive-layout.php’;\n”
else:
a += “\nrequire_once RX_THEME_DIR . ‘/inc/frontend/archive-layout.php’;\n”
write(autoload, a)
else:
write(autoload, “<?php\nif ( ! defined( ‘ABSPATH’ ) ) { exit; }\nrequire_once get_template_directory() . ‘/inc/frontend/archive-layout.php’;\n”)
# PHP check
errors = []
for p in theme_root.rglob(“*.php”):
proc = subprocess.run([“php”, “-l”, str(p)], capture_output=True, text=True)
if proc.returncode != 0:
errors.append(str(p) + “\n” + proc.stdout + proc.stderr)
if errors:
raise RuntimeError(“\n”.join(errors[:10]))
zip_path = Path(“/mnt/data/rx-theme-v7-7-advanced-archive-layout.zip”)
if zip_path.exists():
zip_path.unlink()
with zipfile.ZipFile(zip_path, “w”, zipfile.ZIP_DEFLATED) as z:
for p in theme_root.rglob(“*”):
z.write(p, p.relative_to(work_root))
with zipfile.ZipFile(zip_path, “r”) as z:
bad = z.testzip()
if bad:
raise RuntimeError(“Bad ZIP file member: ” + str(bad))
print(“Created:”, zip_path)
print(“PHP syntax check: Passed”)
print(“ZIP integrity test: Passed”)
from pathlib import Path
import zipfile, shutil, re, subprocess
base_zip = Path(“/mnt/data/rx-theme-v7-7-advanced-archive-layout.zip”)
if not base_zip.exists():
base_zip = Path(“/mnt/data/rx-theme-v7-6-performance-system.zip”)
if not base_zip.exists():
base_zip = Path(“/mnt/data/rx-theme-v7-5-social-share-tools.zip”)
work_root = Path(“/mnt/data/rx_v78_seo_build”)
extract_dir = work_root / “extract”
if work_root.exists():
shutil.rmtree(work_root)
work_root.mkdir(parents=True)
extract_dir.mkdir(parents=True)
with zipfile.ZipFile(base_zip, “r”) as z:
z.extractall(extract_dir)
theme_roots = [p.parent for p in extract_dir.rglob(“style.css”) if (p.parent / “functions.php”).exists()]
if not theme_roots:
raise RuntimeError(“Theme root not found.”)
src_root = theme_roots[0]
theme_root = work_root / “rx-theme-v7-8-advanced-seo-schema”
shutil.copytree(src_root, theme_root)
def read(path):
return path.read_text(encoding=”utf-8″, errors=”ignore”)
def write(path, text):
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(text, encoding=”utf-8″)
# Update style.css
style_path = theme_root / “style.css”
if style_path.exists():
s = read(style_path)
s = re.sub(r”Theme Name:\s*.*”, “Theme Name: RX Theme v7.8 Advanced SEO Schema”, s, count=1) if “Theme Name:” in s else “/*\nTheme Name: RX Theme v7.8 Advanced SEO Schema\nVersion: 7.8\n*/\n” + s
s = re.sub(r”Version:\s*.*”, “Version: 7.8”, s, count=1) if “Version:” in s else s.replace(“*/”, “Version: 7.8\n*/”, 1)
write(style_path, s)
seo_dir = theme_root / “inc/seo”
seo_dir.mkdir(parents=True, exist_ok=True)
# loader
write(seo_dir / “seo-loader.php”, r”'<?php
/**
* RX Theme v7.8 Advanced SEO + Schema Loader.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
$rx_theme_seo_files = array(
‘/inc/seo/seo-helpers.php’,
‘/inc/seo/schema-organization.php’,
‘/inc/seo/schema-person.php’,
‘/inc/seo/schema-website.php’,
‘/inc/seo/schema-search-action.php’,
‘/inc/seo/schema-breadcrumb.php’,
‘/inc/seo/schema-article.php’,
‘/inc/seo/schema-medical-webpage.php’,
‘/inc/seo/schema-medical-condition.php’,
‘/inc/seo/schema-drug.php’,
‘/inc/seo/schema-faq.php’,
‘/inc/seo/open-graph.php’,
‘/inc/seo/twitter-card.php’,
‘/inc/seo/canonical.php’,
‘/inc/seo/meta-robots.php’,
);
foreach ( $rx_theme_seo_files as $rx_theme_seo_file ) {
$rx_theme_seo_path = get_template_directory() . $rx_theme_seo_file;
if ( file_exists( $rx_theme_seo_path ) ) {
require_once $rx_theme_seo_path;
}
}
”’)
# helpers
write(seo_dir / “seo-helpers.php”, r”'<?php
/**
* RX Theme SEO helper functions.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
function rx_theme_v78_seo_enabled() {
if ( function_exists( ‘rx_theme_get_option’ ) ) {
return ‘0’ !== rx_theme_get_option( ‘enable_schema’, ‘1’ );
}
return true;
}
function rx_theme_v78_get_site_logo_url() {
$custom_logo_id = get_theme_mod( ‘custom_logo’ );
if ( $custom_logo_id ) {
$logo = wp_get_attachment_image_url( $custom_logo_id, ‘full’ );
if ( $logo ) {
return $logo;
}
}
if ( function_exists( ‘rx_theme_get_option’ ) ) {
$logo = rx_theme_get_option( ‘site_logo_url’, ” );
if ( $logo ) {
return esc_url_raw( $logo );
}
}
return ”;
}
function rx_theme_v78_get_description() {
if ( is_singular() ) {
$excerpt = get_the_excerpt();
if ( $excerpt ) {
return wp_strip_all_tags( $excerpt );
}
return wp_trim_words( wp_strip_all_tags( get_the_content() ), 32, ” );
}
if ( is_category() || is_tag() || is_tax() ) {
$desc = term_description();
if ( $desc ) {
return wp_strip_all_tags( $desc );
}
}
if ( is_author() ) {
$desc = get_the_author_meta( ‘description’ );
if ( $desc ) {
return wp_strip_all_tags( $desc );
}
}
return get_bloginfo( ‘description’ );
}
function rx_theme_v78_get_image_url() {
if ( is_singular() && has_post_thumbnail() ) {
$image = wp_get_attachment_image_url( get_post_thumbnail_id(), ‘full’ );
if ( $image ) {
return $image;
}
}
return rx_theme_v78_get_site_logo_url();
}
function rx_theme_v78_schema_output( $schema ) {
if ( ! rx_theme_v78_seo_enabled() || empty( $schema ) || ! is_array( $schema ) ) {
return;
}
echo “\n<script type=\”application/ld+json\” class=\”rx-theme-schema\”>\n”;
echo wp_json_encode( $schema, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT );
echo “\n</script>\n”;
}
function rx_theme_v78_schema_graph_output( $items ) {
$items = array_filter( (array) $items );
if ( empty( $items ) ) {
return;
}
rx_theme_v78_schema_output(
array(
‘@context’ => ‘https://schema.org’,
‘@graph’ => array_values( $items ),
)
);
}
function rx_theme_v78_get_primary_category() {
if ( ! is_singular( ‘post’ ) ) {
return ”;
}
$categories = get_the_category();
if ( ! empty( $categories ) && ! is_wp_error( $categories ) ) {
return $categories[0]->name;
}
return ”;
}
function rx_theme_v78_get_breadcrumb_items() {
$items = array(
array(
‘name’ => __( ‘Home’, ‘rx-theme’ ),
‘url’ => home_url( ‘/’ ),
),
);
if ( is_singular( ‘post’ ) ) {
$categories = get_the_category();
if ( ! empty( $categories ) && ! is_wp_error( $categories ) ) {
$items[] = array(
‘name’ => $categories[0]->name,
‘url’ => get_category_link( $categories[0]->term_id ),
);
}
$items[] = array(
‘name’ => get_the_title(),
‘url’ => get_permalink(),
);
} elseif ( is_page() ) {
$items[] = array(
‘name’ => get_the_title(),
‘url’ => get_permalink(),
);
} elseif ( is_category() || is_tag() || is_tax() ) {
$term = get_queried_object();
if ( $term && ! is_wp_error( $term ) ) {
$items[] = array(
‘name’ => single_term_title( ”, false ),
‘url’ => get_term_link( $term ),
);
}
} elseif ( is_search() ) {
$items[] = array(
‘name’ => sprintf( __( ‘Search: %s’, ‘rx-theme’ ), get_search_query() ),
‘url’ => get_search_link(),
);
}
return $items;
}
”’)
# schema files
write(seo_dir / “schema-organization.php”, r”'<?php
if ( ! defined( ‘ABSPATH’ ) ) { exit; }
function rx_theme_v78_schema_organization_data() {
$schema = array(
‘@type’ => ‘Organization’,
‘@id’ => home_url( ‘/#organization’ ),
‘name’ => get_bloginfo( ‘name’ ),
‘url’ => home_url( ‘/’ ),
);
$logo = rx_theme_v78_get_site_logo_url();
if ( $logo ) {
$schema[‘logo’] = array(
‘@type’ => ‘ImageObject’,
‘url’ => $logo,
);
}
return $schema;
}
”’)
write(seo_dir / “schema-person.php”, r”'<?php
if ( ! defined( ‘ABSPATH’ ) ) { exit; }
function rx_theme_v78_schema_person_data( $author_id = 0 ) {
$author_id = $author_id ? absint( $author_id ) : get_the_author_meta( ‘ID’ );
return array(
‘@type’ => ‘Person’,
‘@id’ => get_author_posts_url( $author_id ) . ‘#person’,
‘name’ => get_the_author_meta( ‘display_name’, $author_id ),
‘url’ => get_author_posts_url( $author_id ),
‘description’ => wp_strip_all_tags( get_the_author_meta( ‘description’, $author_id ) ),
);
}
”’)
write(seo_dir / “schema-website.php”, r”'<?php
if ( ! defined( ‘ABSPATH’ ) ) { exit; }
function rx_theme_v78_schema_website_data() {
return array(
‘@type’ => ‘WebSite’,
‘@id’ => home_url( ‘/#website’ ),
‘url’ => home_url( ‘/’ ),
‘name’ => get_bloginfo( ‘name’ ),
‘description’ => get_bloginfo( ‘description’ ),
‘publisher’ => array(
‘@id’ => home_url( ‘/#organization’ ),
),
);
}
”’)
write(seo_dir / “schema-search-action.php”, r”'<?php
if ( ! defined( ‘ABSPATH’ ) ) { exit; }
function rx_theme_v78_schema_search_action_filter( $schema ) {
if ( is_array( $schema ) ) {
$schema[‘potentialAction’] = array(
‘@type’ => ‘SearchAction’,
‘target’ => home_url( ‘/?s={search_term_string}’ ),
‘query-input’ => ‘required name=search_term_string’,
);
}
return $schema;
}
add_filter( ‘rx_theme_v78_schema_website’, ‘rx_theme_v78_schema_search_action_filter’ );
”’)
write(seo_dir / “schema-breadcrumb.php”, r”'<?php
if ( ! defined( ‘ABSPATH’ ) ) { exit; }
function rx_theme_v78_schema_breadcrumb_data() {
$items = rx_theme_v78_get_breadcrumb_items();
$list = array();
foreach ( $items as $index => $item ) {
$list[] = array(
‘@type’ => ‘ListItem’,
‘position’ => $index + 1,
‘name’ => $item[‘name’],
‘item’ => $item[‘url’],
);
}
return array(
‘@type’ => ‘BreadcrumbList’,
‘@id’ => trailingslashit( home_url( add_query_arg( array(), $GLOBALS[‘wp’]->request ?? ” ) ) ) . ‘#breadcrumb’,
‘itemListElement’ => $list,
);
}
”’)
write(seo_dir / “schema-article.php”, r”'<?php
if ( ! defined( ‘ABSPATH’ ) ) { exit; }
function rx_theme_v78_schema_article_data() {
if ( ! is_singular( ‘post’ ) ) {
return array();
}
$schema = array(
‘@type’ => ‘Article’,
‘@id’ => get_permalink() . ‘#article’,
‘headline’ => wp_strip_all_tags( get_the_title() ),
‘description’ => rx_theme_v78_get_description(),
‘datePublished’ => get_the_date( DATE_W3C ),
‘dateModified’ => get_the_modified_date( DATE_W3C ),
‘mainEntityOfPage’ => get_permalink(),
‘author’ => array(
‘@id’ => get_author_posts_url( get_the_author_meta( ‘ID’ ) ) . ‘#person’,
),
‘publisher’ => array(
‘@id’ => home_url( ‘/#organization’ ),
),
);
$image = rx_theme_v78_get_image_url();
if ( $image ) {
$schema[‘image’] = array( $image );
}
$category = rx_theme_v78_get_primary_category();
if ( $category ) {
$schema[‘articleSection’] = $category;
}
return $schema;
}
”’)
write(seo_dir / “schema-medical-webpage.php”, r”'<?php
if ( ! defined( ‘ABSPATH’ ) ) { exit; }
function rx_theme_v78_schema_medical_webpage_data() {
if ( ! is_singular() ) {
return array();
}
return array(
‘@type’ => ‘MedicalWebPage’,
‘@id’ => get_permalink() . ‘#medical-webpage’,
‘url’ => get_permalink(),
‘name’ => wp_strip_all_tags( get_the_title() ),
‘description’ => rx_theme_v78_get_description(),
‘lastReviewed’ => get_the_modified_date( ‘Y-m-d’ ),
‘reviewedBy’ => array(
‘@type’ => ‘Person’,
‘name’ => function_exists( ‘rx_theme_get_option’ ) ? rx_theme_get_option( ‘article_reviewer_name’, get_bloginfo( ‘name’ ) ) : get_bloginfo( ‘name’ ),
),
‘publisher’ => array(
‘@id’ => home_url( ‘/#organization’ ),
),
);
}
”’)
write(seo_dir / “schema-medical-condition.php”, r”'<?php
if ( ! defined( ‘ABSPATH’ ) ) { exit; }
/**
* Optional MedicalCondition schema.
* Add custom fields later if needed; this safe version uses post title/description.
*/
function rx_theme_v78_schema_medical_condition_data() {
if ( ! is_singular( ‘post’ ) ) {
return array();
}
$category = rx_theme_v78_get_primary_category();
return array(
‘@type’ => ‘MedicalCondition’,
‘@id’ => get_permalink() . ‘#medical-condition’,
‘name’ => wp_strip_all_tags( get_the_title() ),
‘description’ => rx_theme_v78_get_description(),
‘url’ => get_permalink(),
‘medicineSystem’ => ‘WesternConventional’,
‘relevantSpecialty’ => $category ? $category : ‘MedicalSpecialty’,
);
}
”’)
write(seo_dir / “schema-drug.php”, r”'<?php
if ( ! defined( ‘ABSPATH’ ) ) { exit; }
/**
* Optional Drug schema shortcode.
* Usage: [rx_drug_schema name=”Paracetamol” description=”Pain reliever” dose=”500 mg”]
*/
function rx_theme_v78_drug_schema_shortcode( $atts ) {
$atts = shortcode_atts(
array(
‘name’ => ”,
‘description’ => ”,
‘dose’ => ”,
),
$atts,
‘rx_drug_schema’
);
if ( empty( $atts[‘name’] ) ) {
return ”;
}
$schema = array(
‘@context’ => ‘https://schema.org’,
‘@type’ => ‘Drug’,
‘name’ => sanitize_text_field( $atts[‘name’] ),
‘description’ => sanitize_text_field( $atts[‘description’] ),
);
if ( ! empty( $atts[‘dose’] ) ) {
$schema[‘dosageForm’] = sanitize_text_field( $atts[‘dose’] );
}
ob_start();
rx_theme_v78_schema_output( $schema );
return ob_get_clean();
}
add_shortcode( ‘rx_drug_schema’, ‘rx_theme_v78_drug_schema_shortcode’ );
”’)
write(seo_dir / “schema-faq.php”, r”'<?php
if ( ! defined( ‘ABSPATH’ ) ) { exit; }
function rx_theme_v78_extract_faq_schema_from_content( $content ) {
$faqs = array();
if ( preg_match_all( ‘/<h[2-4][^>]*>(.*?)\?<\/h[2-4]>\s*<p[^>]*>(.*?)<\/p>/is’, $content, $matches, PREG_SET_ORDER ) ) {
foreach ( $matches as $match ) {
$question = trim( wp_strip_all_tags( $match[1] ) );
$answer = trim( wp_strip_all_tags( $match[2] ) );
if ( $question && $answer ) {
$faqs[] = array(
‘@type’ => ‘Question’,
‘name’ => $question,
‘acceptedAnswer’ => array(
‘@type’ => ‘Answer’,
‘text’ => $answer,
),
);
}
}
}
if ( empty( $faqs ) ) {
return array();
}
return array(
‘@type’ => ‘FAQPage’,
‘@id’ => get_permalink() . ‘#faq’,
‘mainEntity’ => array_slice( $faqs, 0, 12 ),
);
}
”’)
# OG, Twitter, canonical, robots
write(seo_dir / “open-graph.php”, r”'<?php
if ( ! defined( ‘ABSPATH’ ) ) { exit; }
function rx_theme_v78_open_graph_tags() {
if ( is_admin() ) {
return;
}
$title = is_singular() ? single_post_title( ”, false ) : wp_get_document_title();
$desc = rx_theme_v78_get_description();
$url = is_singular() ? get_permalink() : home_url( add_query_arg( array(), $GLOBALS[‘wp’]->request ?? ” ) );
$type = is_singular() ? ‘article’ : ‘website’;
$image = rx_theme_v78_get_image_url();
echo “\n<!– RX Theme Open Graph –>\n”;
echo ‘<meta property=”og:type” content=”‘ . esc_attr( $type ) . ‘”>’ . “\n”;
echo ‘<meta property=”og:title” content=”‘ . esc_attr( $title ) . ‘”>’ . “\n”;
echo ‘<meta property=”og:description” content=”‘ . esc_attr( wp_trim_words( $desc, 32, ” ) ) . ‘”>’ . “\n”;
echo ‘<meta property=”og:url” content=”‘ . esc_url( $url ) . ‘”>’ . “\n”;
echo ‘<meta property=”og:site_name” content=”‘ . esc_attr( get_bloginfo( ‘name’ ) ) . ‘”>’ . “\n”;
if ( $image ) {
echo ‘<meta property=”og:image” content=”‘ . esc_url( $image ) . ‘”>’ . “\n”;
}
}
add_action( ‘wp_head’, ‘rx_theme_v78_open_graph_tags’, 8 );
”’)
write(seo_dir / “twitter-card.php”, r”'<?php
if ( ! defined( ‘ABSPATH’ ) ) { exit; }
function rx_theme_v78_twitter_card_tags() {
if ( is_admin() ) {
return;
}
$title = is_singular() ? single_post_title( ”, false ) : wp_get_document_title();
$desc = rx_theme_v78_get_description();
$image = rx_theme_v78_get_image_url();
echo “\n<!– RX Theme Twitter Card –>\n”;
echo ‘<meta name=”twitter:card” content=”‘ . esc_attr( $image ? ‘summary_large_image’ : ‘summary’ ) . ‘”>’ . “\n”;
echo ‘<meta name=”twitter:title” content=”‘ . esc_attr( $title ) . ‘”>’ . “\n”;
echo ‘<meta name=”twitter:description” content=”‘ . esc_attr( wp_trim_words( $desc, 32, ” ) ) . ‘”>’ . “\n”;
if ( $image ) {
echo ‘<meta name=”twitter:image” content=”‘ . esc_url( $image ) . ‘”>’ . “\n”;
}
}
add_action( ‘wp_head’, ‘rx_theme_v78_twitter_card_tags’, 9 );
”’)
write(seo_dir / “canonical.php”, r”'<?php
if ( ! defined( ‘ABSPATH’ ) ) { exit; }
remove_action( ‘wp_head’, ‘rel_canonical’ );
function rx_theme_v78_canonical_url() {
if ( is_admin() || is_404() ) {
return;
}
if ( is_singular() ) {
$url = get_permalink();
} elseif ( is_home() || is_front_page() ) {
$url = home_url( ‘/’ );
} elseif ( is_category() || is_tag() || is_tax() ) {
$url = get_term_link( get_queried_object() );
} elseif ( is_author() ) {
$url = get_author_posts_url( get_queried_object_id() );
} elseif ( is_search() ) {
$url = get_search_link();
} else {
$url = home_url( add_query_arg( array(), $GLOBALS[‘wp’]->request ?? ” ) );
}
if ( ! is_wp_error( $url ) && $url ) {
echo “\n” . ‘<link rel=”canonical” href=”‘ . esc_url( $url ) . ‘”>’ . “\n”;
}
}
add_action( ‘wp_head’, ‘rx_theme_v78_canonical_url’, 7 );
”’)
write(seo_dir / “meta-robots.php”, r”'<?php
if ( ! defined( ‘ABSPATH’ ) ) { exit; }
function rx_theme_v78_meta_robots() {
if ( is_admin() ) {
return;
}
$content = ‘index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1’;
if ( is_search() || is_404() ) {
$content = ‘noindex, follow’;
}
echo “\n” . ‘<meta name=”robots” content=”‘ . esc_attr( $content ) . ‘”>’ . “\n”;
}
add_action( ‘wp_head’, ‘rx_theme_v78_meta_robots’, 6 );
”’)
# Main schema output hook
write(seo_dir / “schema-output.php”, r”'<?php
/**
* RX Theme schema graph output.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
function rx_theme_v78_schema_graph() {
if ( is_admin() || ! rx_theme_v78_seo_enabled() ) {
return;
}
$website = function_exists( ‘rx_theme_v78_schema_website_data’ ) ? rx_theme_v78_schema_website_data() : array();
$website = apply_filters( ‘rx_theme_v78_schema_website’, $website );
$items = array(
function_exists( ‘rx_theme_v78_schema_organization_data’ ) ? rx_theme_v78_schema_organization_data() : array(),
$website,
);
if ( is_singular() || is_archive() || is_search() ) {
$items[] = function_exists( ‘rx_theme_v78_schema_breadcrumb_data’ ) ? rx_theme_v78_schema_breadcrumb_data() : array();
}
if ( is_singular( ‘post’ ) ) {
$items[] = function_exists( ‘rx_theme_v78_schema_person_data’ ) ? rx_theme_v78_schema_person_data() : array();
$items[] = function_exists( ‘rx_theme_v78_schema_article_data’ ) ? rx_theme_v78_schema_article_data() : array();
$items[] = function_exists( ‘rx_theme_v78_schema_medical_webpage_data’ ) ? rx_theme_v78_schema_medical_webpage_data() : array();
$items[] = function_exists( ‘rx_theme_v78_schema_medical_condition_data’ ) ? rx_theme_v78_schema_medical_condition_data() : array();
$content = get_post_field( ‘post_content’, get_the_ID() );
$faq = function_exists( ‘rx_theme_v78_extract_faq_schema_from_content’ ) ? rx_theme_v78_extract_faq_schema_from_content( apply_filters( ‘the_content’, $content ) ) : array();
if ( ! empty( $faq ) ) {
$items[] = $faq;
}
} elseif ( is_page() ) {
$items[] = function_exists( ‘rx_theme_v78_schema_medical_webpage_data’ ) ? rx_theme_v78_schema_medical_webpage_data() : array();
}
rx_theme_v78_schema_graph_output( $items );
}
add_action( ‘wp_head’, ‘rx_theme_v78_schema_graph’, 20 );
”’)
# Insert schema-output in loader
loader = read(seo_dir / “seo-loader.php”)
if “/inc/seo/schema-output.php” not in loader:
loader = loader.replace(“‘/inc/seo/meta-robots.php’,”, “‘/inc/seo/meta-robots.php’,\n ‘/inc/seo/schema-output.php’,”)
write(seo_dir / “seo-loader.php”, loader)
# Add loader to autoload
autoload = theme_root / “inc/autoload.php”
if autoload.exists():
a = read(autoload)
if “/inc/seo/seo-loader.php” not in a:
idx = a.find(“foreach”)
if idx != -1:
before, after = a[:idx], a[idx:]
pos = before.rfind(“);”)
if pos != -1:
before = before[:pos] + ” ‘/inc/seo/seo-loader.php’,\n” + before[pos:]
a = before + after
else:
a += “\nrequire_once RX_THEME_DIR . ‘/inc/seo/seo-loader.php’;\n”
else:
a += “\nrequire_once RX_THEME_DIR . ‘/inc/seo/seo-loader.php’;\n”
write(autoload, a)
else:
write(autoload, “<?php\nif ( ! defined( ‘ABSPATH’ ) ) { exit; }\nrequire_once get_template_directory() . ‘/inc/seo/seo-loader.php’;\n”)
# PHP syntax check
errors = []
for p in theme_root.rglob(“*.php”):
proc = subprocess.run([“php”, “-l”, str(p)], capture_output=True, text=True)
if proc.returncode != 0:
errors.append(str(p) + “\n” + proc.stdout + proc.stderr)
if errors:
raise RuntimeError(“\n”.join(errors[:10]))
zip_path = Path(“/mnt/data/rx-theme-v7-8-advanced-seo-schema.zip”)
if zip_path.exists():
zip_path.unlink()
with zipfile.ZipFile(zip_path, “w”, zipfile.ZIP_DEFLATED) as z:
for p in theme_root.rglob(“*”):
z.write(p, p.relative_to(work_root))
with zipfile.ZipFile(zip_path, “r”) as z:
bad = z.testzip()
if bad:
raise RuntimeError(“Bad ZIP file member: ” + str(bad))
print(“Created:”, zip_path)
print(“PHP syntax check: Passed”)
print(“ZIP integrity test: Passed”)
Yes dear friend, absolutely possible. We can add your full previous RX Theme structure one by one, safely, without breaking the theme again.
Your latest stable version is:
RX Theme v7.8 Advanced SEO Schema ✅
Already completed:
1. Working theme foundation ✅
2. Full folder structure base ✅
3. Homepage system ✅
4. Medical article system ✅
5. Footer builder ✅
6. Header search/menu system ✅
7. Header mobile polish ✅
8. Social share tools ✅
9. Performance structure ✅
10. Archive/category/tag/search layout ✅
11. Advanced SEO/schema structure ✅
Now we can continue with the remaining structure like this:
v7.9 = Ad slot + Google AdSense manager
v8.0 = Import/export theme settings
v8.1 = Customizer support
v8.2 = Gutenberg medical blocks
v8.3 = Disease A-Z template improvement
v8.4 = Contact + newsletter system
v8.5 = WooCommerce/Elementor compatibility polish
v8.6 = Accessibility advanced tools
v8.7 = Final cleanup + premium theme polish
Best next step
I recommend next:
RX Theme v7.9 = Ad Slot + Google AdSense Manager
Because it is very useful for your medical website and can include:
Header ad slot
Below title ad slot
Middle content ad slot
Before related posts ad slot
Footer ad slot
Sidebar ad slot
Mobile ad slot
AdSense code boxes
Enable/disable ads from theme options
Safe ad output
No ad on admin/login pages
Then after that we add:
RX Theme v8.0 = Import / Export Settings
This will let you backup and restore all RX Theme options.
So yes dear friend — we can complete the whole RX Theme structure step by step.
from pathlib import Path
import zipfile, shutil, re, subprocess
base_zip = Path(“/mnt/data/rx-theme-v7-8-advanced-seo-schema.zip”)
if not base_zip.exists():
base_zip = Path(“/mnt/data/rx-theme-v7-7-advanced-archive-layout.zip”)
if not base_zip.exists():
base_zip = Path(“/mnt/data/rx-theme-v7-6-performance-system.zip”)
work_root = Path(“/mnt/data/rx_v79_ads_build”)
extract_dir = work_root / “extract”
if work_root.exists():
shutil.rmtree(work_root)
work_root.mkdir(parents=True)
extract_dir.mkdir(parents=True)
with zipfile.ZipFile(base_zip, “r”) as z:
z.extractall(extract_dir)
theme_roots = [p.parent for p in extract_dir.rglob(“style.css”) if (p.parent / “functions.php”).exists()]
if not theme_roots:
raise RuntimeError(“Theme root not found.”)
src_root = theme_roots[0]
theme_root = work_root / “rx-theme-v7-9-ad-manager”
shutil.copytree(src_root, theme_root)
def read(path):
return path.read_text(encoding=”utf-8″, errors=”ignore”)
def write(path, text):
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(text, encoding=”utf-8″)
# Update style.css
style_path = theme_root / “style.css”
if style_path.exists():
s = read(style_path)
s = re.sub(r”Theme Name:\s*.*”, “Theme Name: RX Theme v7.9 Ad Manager”, s, count=1) if “Theme Name:” in s else “/*\nTheme Name: RX Theme v7.9 Ad Manager\nVersion: 7.9\n*/\n” + s
s = re.sub(r”Version:\s*.*”, “Version: 7.9”, s, count=1) if “Version:” in s else s.replace(“*/”, “Version: 7.9\n*/”, 1)
write(style_path, s)
# Dirs
inc_ads = theme_root / “inc/ads”
css_dir = theme_root / “assets/css/frontend”
inc_ads.mkdir(parents=True, exist_ok=True)
css_dir.mkdir(parents=True, exist_ok=True)
# Loader
write(inc_ads / “ads-loader.php”, r”'<?php
/**
* RX Theme v7.9 Ad Slot + Google AdSense Manager Loader.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
$rx_theme_ads_files = array(
‘/inc/ads/ad-helpers.php’,
‘/inc/ads/ad-settings.php’,
‘/inc/ads/ad-output.php’,
‘/inc/ads/ad-shortcodes.php’,
);
foreach ( $rx_theme_ads_files as $rx_theme_ads_file ) {
$rx_theme_ads_path = get_template_directory() . $rx_theme_ads_file;
if ( file_exists( $rx_theme_ads_path ) ) {
require_once $rx_theme_ads_path;
}
}
”’)
# Helpers
write(inc_ads / “ad-helpers.php”, r”'<?php
/**
* RX Theme ad helper functions.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
function rx_theme_v79_ads_defaults() {
return array(
‘ads_enabled’ => ‘0’,
‘adsense_client’ => ”,
‘header_ad’ => ”,
‘below_title_ad’ => ”,
‘middle_content_ad’ => ”,
‘before_related_ad’ => ”,
‘footer_ad’ => ”,
‘sidebar_ad’ => ”,
‘mobile_ad’ => ”,
‘show_labels’ => ‘1’,
);
}
function rx_theme_v79_get_ads_options() {
$options = get_option( ‘rx_theme_v79_ads’, array() );
if ( ! is_array( $options ) ) {
$options = array();
}
return wp_parse_args( $options, rx_theme_v79_ads_defaults() );
}
function rx_theme_v79_get_ad_option( $key, $default = ” ) {
$options = rx_theme_v79_get_ads_options();
return isset( $options[ $key ] ) ? $options[ $key ] : $default;
}
function rx_theme_v79_ads_enabled() {
return ‘1’ === rx_theme_v79_get_ad_option( ‘ads_enabled’, ‘0’ );
}
function rx_theme_v79_is_safe_ad_context() {
if ( is_admin() || is_feed() || is_robots() || is_trackback() || wp_doing_ajax() || wp_doing_cron() ) {
return false;
}
if ( is_user_logged_in() && current_user_can( ‘manage_options’ ) && is_customize_preview() ) {
return false;
}
return true;
}
function rx_theme_v79_allowed_ad_html() {
$allowed = wp_kses_allowed_html( ‘post’ );
$allowed[‘script’] = array(
‘async’ => true,
‘src’ => true,
‘crossorigin’ => true,
‘type’ => true,
);
$allowed[‘ins’] = array(
‘class’ => true,
‘style’ => true,
‘data-ad-client’ => true,
‘data-ad-slot’ => true,
‘data-ad-format’ => true,
‘data-full-width-responsive’ => true,
‘data-ad-layout’ => true,
‘data-ad-layout-key’ => true,
);
$allowed[‘iframe’] = array(
‘src’ => true,
‘width’ => true,
‘height’ => true,
‘style’ => true,
‘loading’ => true,
‘referrerpolicy’ => true,
‘sandbox’ => true,
‘allow’ => true,
‘allowfullscreen’ => true,
‘title’ => true,
);
return $allowed;
}
function rx_theme_v79_sanitize_ad_code( $code ) {
$code = (string) $code;
if ( ” === trim( $code ) ) {
return ”;
}
return wp_kses( $code, rx_theme_v79_allowed_ad_html() );
}
function rx_theme_v79_output_ad_slot( $slot, $class = ” ) {
if ( ! rx_theme_v79_ads_enabled() || ! rx_theme_v79_is_safe_ad_context() ) {
return;
}
$slot = sanitize_key( $slot );
$code = rx_theme_v79_get_ad_option( $slot, ” );
if ( ! $code ) {
return;
}
$classes = trim( ‘rx-ad-slot rx-ad-slot–‘ . $slot . ‘ ‘ . sanitize_html_class( $class ) );
echo ‘<div class=”‘ . esc_attr( $classes ) . ‘” data-rx-ad-slot=”‘ . esc_attr( $slot ) . ‘”>’;
if ( ‘1’ === rx_theme_v79_get_ad_option( ‘show_labels’, ‘1’ ) ) {
echo ‘<div class=”rx-ad-slot__label”>’ . esc_html__( ‘Advertisement’, ‘rx-theme’ ) . ‘</div>’;
}
echo ‘<div class=”rx-ad-slot__inner”>’;
echo rx_theme_v79_sanitize_ad_code( $code ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo ‘</div>’;
echo ‘</div>’;
}
”’)
# Settings admin page
write(inc_ads / “ad-settings.php”, r”'<?php
/**
* RX Theme v7.9 Ad Manager settings page.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
function rx_theme_v79_ads_register_settings() {
register_setting(
‘rx_theme_v79_ads_group’,
‘rx_theme_v79_ads’,
array(
‘sanitize_callback’ => ‘rx_theme_v79_ads_sanitize_options’,
‘default’ => rx_theme_v79_ads_defaults(),
)
);
}
add_action( ‘admin_init’, ‘rx_theme_v79_ads_register_settings’ );
function rx_theme_v79_ads_sanitize_options( $input ) {
$defaults = rx_theme_v79_ads_defaults();
$output = array();
$output[‘ads_enabled’] = ! empty( $input[‘ads_enabled’] ) ? ‘1’ : ‘0’;
$output[‘show_labels’] = ! empty( $input[‘show_labels’] ) ? ‘1’ : ‘0’;
$output[‘adsense_client’] = isset( $input[‘adsense_client’] ) ? sanitize_text_field( $input[‘adsense_client’] ) : ”;
$ad_fields = array(
‘header_ad’,
‘below_title_ad’,
‘middle_content_ad’,
‘before_related_ad’,
‘footer_ad’,
‘sidebar_ad’,
‘mobile_ad’,
);
foreach ( $ad_fields as $field ) {
$output[ $field ] = isset( $input[ $field ] ) ? rx_theme_v79_sanitize_ad_code( wp_unslash( $input[ $field ] ) ) : ”;
}
return wp_parse_args( $output, $defaults );
}
function rx_theme_v79_ads_admin_menu() {
add_theme_page(
esc_html__( ‘RX Ad Manager’, ‘rx-theme’ ),
esc_html__( ‘RX Ad Manager’, ‘rx-theme’ ),
‘manage_options’,
‘rx-theme-ad-manager’,
‘rx_theme_v79_ads_settings_page’
);
}
add_action( ‘admin_menu’, ‘rx_theme_v79_ads_admin_menu’, 30 );
function rx_theme_v79_ads_textarea( $key, $label, $description = ” ) {
$options = rx_theme_v79_get_ads_options();
?>
<tr>
<th scope=”row”>
<label for=”rx_theme_v79_<?php echo esc_attr( $key ); ?>”><?php echo esc_html( $label ); ?></label>
</th>
<td>
<textarea
id=”rx_theme_v79_<?php echo esc_attr( $key ); ?>”
name=”rx_theme_v79_ads[<?php echo esc_attr( $key ); ?>]”
rows=”6″
class=”large-text code”
placeholder=”<?php esc_attr_e( ‘Paste Google AdSense or safe ad HTML code here.’, ‘rx-theme’ ); ?>”
><?php echo esc_textarea( $options[ $key ] ?? ” ); ?></textarea>
<?php if ( $description ) : ?>
<p class=”description”><?php echo esc_html( $description ); ?></p>
<?php endif; ?>
</td>
</tr>
<?php
}
function rx_theme_v79_ads_settings_page() {
if ( ! current_user_can( ‘manage_options’ ) ) {
return;
}
$options = rx_theme_v79_get_ads_options();
?>
<div class=”wrap rx-ad-manager-admin”>
<h1><?php esc_html_e( ‘RX Theme Ad Slot + Google AdSense Manager’, ‘rx-theme’ ); ?></h1>
<p><?php esc_html_e( ‘Manage safe ad slots for header, article, sidebar, footer, and mobile areas.’, ‘rx-theme’ ); ?></p>
<form method=”post” action=”options.php”>
<?php settings_fields( ‘rx_theme_v79_ads_group’ ); ?>
<h2><?php esc_html_e( ‘General Ad Controls’, ‘rx-theme’ ); ?></h2>
<table class=”form-table” role=”presentation”>
<tr>
<th scope=”row”><?php esc_html_e( ‘Enable Ads’, ‘rx-theme’ ); ?></th>
<td>
<label>
<input type=”checkbox” name=”rx_theme_v79_ads[ads_enabled]” value=”1″ <?php checked( ‘1’, $options[‘ads_enabled’] ); ?>>
<?php esc_html_e( ‘Enable ad output on the frontend’, ‘rx-theme’ ); ?>
</label>
</td>
</tr>
<tr>
<th scope=”row”><?php esc_html_e( ‘Show Advertisement Label’, ‘rx-theme’ ); ?></th>
<td>
<label>
<input type=”checkbox” name=”rx_theme_v79_ads[show_labels]” value=”1″ <?php checked( ‘1’, $options[‘show_labels’] ); ?>>
<?php esc_html_e( ‘Show small “Advertisement” label above ad slots’, ‘rx-theme’ ); ?>
</label>
</td>
</tr>
<tr>
<th scope=”row”>
<label for=”rx_theme_v79_adsense_client”><?php esc_html_e( ‘Google AdSense Client ID’, ‘rx-theme’ ); ?></label>
</th>
<td>
<input
id=”rx_theme_v79_adsense_client”
type=”text”
name=”rx_theme_v79_ads[adsense_client]”
value=”<?php echo esc_attr( $options[‘adsense_client’] ); ?>”
class=”regular-text”
placeholder=”ca-pub-xxxxxxxxxxxxxxxx”
>
<p class=”description”><?php esc_html_e( ‘Optional note field for your AdSense publisher ID.’, ‘rx-theme’ ); ?></p>
</td>
</tr>
</table>
<h2><?php esc_html_e( ‘Ad Slot Code Boxes’, ‘rx-theme’ ); ?></h2>
<table class=”form-table” role=”presentation”>
<?php
rx_theme_v79_ads_textarea( ‘header_ad’, esc_html__( ‘Header Ad Slot’, ‘rx-theme’ ), esc_html__( ‘Outputs after the site header.’, ‘rx-theme’ ) );
rx_theme_v79_ads_textarea( ‘below_title_ad’, esc_html__( ‘Below Title Ad Slot’, ‘rx-theme’ ), esc_html__( ‘Outputs near the top of single posts/pages.’, ‘rx-theme’ ) );
rx_theme_v79_ads_textarea( ‘middle_content_ad’, esc_html__( ‘Middle Content Ad Slot’, ‘rx-theme’ ), esc_html__( ‘Automatically inserted after a few paragraphs in single post content.’, ‘rx-theme’ ) );
rx_theme_v79_ads_textarea( ‘before_related_ad’, esc_html__( ‘Before Related Posts Ad Slot’, ‘rx-theme’ ), esc_html__( ‘Outputs after article content, before related/share areas.’, ‘rx-theme’ ) );
rx_theme_v79_ads_textarea( ‘footer_ad’, esc_html__( ‘Footer Ad Slot’, ‘rx-theme’ ), esc_html__( ‘Outputs before the footer closes.’, ‘rx-theme’ ) );
rx_theme_v79_ads_textarea( ‘sidebar_ad’, esc_html__( ‘Sidebar Ad Slot’, ‘rx-theme’ ), esc_html__( ‘Outputs at the top of registered sidebars.’, ‘rx-theme’ ) );
rx_theme_v79_ads_textarea( ‘mobile_ad’, esc_html__( ‘Mobile Ad Slot’, ‘rx-theme’ ), esc_html__( ‘Visible on small screens only.’, ‘rx-theme’ ) );
?>
</table>
<?php submit_button( esc_html__( ‘Save Ad Settings’, ‘rx-theme’ ) ); ?>
</form>
<hr>
<h2><?php esc_html_e( ‘Shortcode Usage’, ‘rx-theme’ ); ?></h2>
<p><code>[rx_ad slot=”header_ad”]</code></p>
<p><code>[rx_ad slot=”middle_content_ad”]</code></p>
<p><code>[rx_ad slot=”footer_ad”]</code></p>
</div>
<?php
}
”’)
# Output hooks
write(inc_ads / “ad-output.php”, r”'<?php
/**
* RX Theme v7.9 Ad output hooks.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
function rx_theme_v79_header_ad() {
rx_theme_v79_output_ad_slot( ‘header_ad’ );
}
add_action( ‘wp_body_open’, ‘rx_theme_v79_header_ad’, 30 );
function rx_theme_v79_footer_ad() {
rx_theme_v79_output_ad_slot( ‘footer_ad’ );
rx_theme_v79_output_ad_slot( ‘mobile_ad’, ‘rx-ad-slot–mobile-only’ );
}
add_action( ‘wp_footer’, ‘rx_theme_v79_footer_ad’, 5 );
function rx_theme_v79_insert_ads_into_content( $content ) {
if ( ! is_singular( ‘post’ ) || ! in_the_loop() || ! is_main_query() || ! rx_theme_v79_ads_enabled() || ! rx_theme_v79_is_safe_ad_context() ) {
return $content;
}
ob_start();
rx_theme_v79_output_ad_slot( ‘below_title_ad’ );
$below_title = ob_get_clean();
ob_start();
rx_theme_v79_output_ad_slot( ‘middle_content_ad’ );
$middle = ob_get_clean();
ob_start();
rx_theme_v79_output_ad_slot( ‘before_related_ad’ );
$before_related = ob_get_clean();
$content = $below_title . $content;
if ( $middle ) {
$paragraphs = explode( ‘</p>’, $content );
$insert_at = min( 4, max( 1, count( $paragraphs ) – 1 ) );
if ( count( $paragraphs ) > 3 ) {
$new_content = ”;
foreach ( $paragraphs as $index => $paragraph ) {
if ( trim( $paragraph ) ) {
$new_content .= $paragraph . ‘</p>’;
}
if ( $index + 1 === $insert_at ) {
$new_content .= $middle;
}
}
$content = $new_content;
} else {
$content .= $middle;
}
}
$content .= $before_related;
return $content;
}
add_filter( ‘the_content’, ‘rx_theme_v79_insert_ads_into_content’, 18 );
function rx_theme_v79_sidebar_ad_widget() {
rx_theme_v79_output_ad_slot( ‘sidebar_ad’ );
}
add_action( ‘dynamic_sidebar_before’, ‘rx_theme_v79_sidebar_ad_widget’, 5 );
”’)
# Shortcodes
write(inc_ads / “ad-shortcodes.php”, r”'<?php
/**
* RX Theme v7.9 Ad shortcodes.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
function rx_theme_v79_ad_shortcode( $atts ) {
$atts = shortcode_atts(
array(
‘slot’ => ‘middle_content_ad’,
),
$atts,
‘rx_ad’
);
ob_start();
rx_theme_v79_output_ad_slot( sanitize_key( $atts[‘slot’] ) );
return ob_get_clean();
}
add_shortcode( ‘rx_ad’, ‘rx_theme_v79_ad_shortcode’ );
”’)
# CSS
write(css_dir / “ad-manager.css”, r”’/* RX Theme v7.9 Ad Manager */
.rx-ad-slot{
width:100%;
margin:24px auto;
text-align:center;
clear:both;
}
.rx-ad-slot__label{
display:block;
margin-bottom:8px;
color:#94a3b8;
font-size:11px;
font-weight:800;
letter-spacing:.08em;
text-transform:uppercase;
}
.rx-ad-slot__inner{
display:flex;
align-items:center;
justify-content:center;
min-height:80px;
padding:12px;
border:1px dashed #dbeafe;
border-radius:18px;
background:#f8fafc;
overflow:hidden;
}
.rx-ad-slot__inner:empty{
display:none;
}
.rx-ad-slot–header_ad{
margin:14px auto 20px;
}
.rx-ad-slot–below_title_ad{
margin:20px auto 28px;
}
.rx-ad-slot–middle_content_ad{
margin:32px auto;
}
.rx-ad-slot–before_related_ad{
margin:36px auto 24px;
}
.rx-ad-slot–footer_ad{
margin:28px auto;
}
.rx-ad-slot–sidebar_ad{
margin:0 0 22px;
}
.rx-ad-slot–mobile-only{
display:none;
}
body.rx-dark-mode .rx-ad-slot__inner{
background:#111827;
border-color:#243244;
}
@media(max-width:760px){
.rx-ad-slot{
margin:18px auto;
}
.rx-ad-slot__inner{
min-height:70px;
border-radius:14px;
}
.rx-ad-slot–mobile-only{
display:block;
}
}
@media(min-width:761px){
.rx-ad-slot–mobile-only{
display:none!important;
}
}
@media print{
.rx-ad-slot{
display:none!important;
}
}
”’)
# Enqueue ad CSS via output module – append
ad_output = read(inc_ads / “ad-output.php”)
ad_output += r”’
function rx_theme_v79_ad_assets() {
if ( is_admin() ) {
return;
}
$theme_uri = get_template_directory_uri();
$theme_dir = get_template_directory();
$rel = ‘/assets/css/frontend/ad-manager.css’;
if ( file_exists( $theme_dir . $rel ) ) {
wp_enqueue_style(
‘rx-theme-ad-manager’,
$theme_uri . $rel,
array(),
filemtime( $theme_dir . $rel )
);
}
}
add_action( ‘wp_enqueue_scripts’, ‘rx_theme_v79_ad_assets’, 38 );
”’
write(inc_ads / “ad-output.php”, ad_output)
# Add loader to autoload
autoload = theme_root / “inc/autoload.php”
if autoload.exists():
a = read(autoload)
if “/inc/ads/ads-loader.php” not in a:
idx = a.find(“foreach”)
if idx != -1:
before, after = a[:idx], a[idx:]
pos = before.rfind(“);”)
if pos != -1:
before = before[:pos] + ” ‘/inc/ads/ads-loader.php’,\n” + before[pos:]
a = before + after
else:
a += “\nrequire_once RX_THEME_DIR . ‘/inc/ads/ads-loader.php’;\n”
else:
a += “\nrequire_once RX_THEME_DIR . ‘/inc/ads/ads-loader.php’;\n”
write(autoload, a)
else:
write(autoload, “<?php\nif ( ! defined( ‘ABSPATH’ ) ) { exit; }\nrequire_once get_template_directory() . ‘/inc/ads/ads-loader.php’;\n”)
# PHP syntax check
errors = []
for p in theme_root.rglob(“*.php”):
proc = subprocess.run([“php”, “-l”, str(p)], capture_output=True, text=True)
if proc.returncode != 0:
errors.append(str(p) + “\n” + proc.stdout + proc.stderr)
if errors:
raise RuntimeError(“\n”.join(errors[:10]))
# Zip
zip_path = Path(“/mnt/data/rx-theme-v7-9-ad-manager.zip”)
if zip_path.exists():
zip_path.unlink()
with zipfile.ZipFile(zip_path, “w”, zipfile.ZIP_DEFLATED) as z:
for p in theme_root.rglob(“*”):
z.write(p, p.relative_to(work_root))
with zipfile.ZipFile(zip_path, “r”) as z:
bad = z.testzip()
if bad:
raise RuntimeError(“Bad ZIP file member: ” + str(bad))
print(“Created:”, zip_path)
print(“PHP syntax check: Passed”)
print(“ZIP integrity test: Passed”)