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
Done dear friend — I created the surprise version:
Checked before giving:
PHP syntax check: Passed
ZIP integrity test: Passed
Added in RX Theme v9.1
GitHub-inspired compact header
RX medical brand style
Logo left aligned
Menu organized horizontally
Dropdown menu support
Search box aligned like large professional websites
Sign in link
Sign up button
Dark mode button
Mobile hamburger menu
Mobile dropdown layout
Sticky header
Accessibility toolbar moved away from header
Better spacing and header height
New files added
inc/header/header-loader.php
inc/header/github-inspired-header.php
assets/css/frontend/github-inspired-header.css
assets/js/frontend/github-inspired-header.js
Install
Dashboard → Appearance → Themes → Add New → Upload Theme
Upload:
rx-theme-v9-1-github-inspired-header.zip
After installing, hard refresh:
Ctrl + F5
Keep your working v9.0 backup before activating this one, dear friend.
=========================================
Yes dear friend — the header is now excellent, and the logo can be made to fit perfectly. I’ll create a small safe update: RX Theme v9.1.1 Logo Fit Fix, so your logo stays clean in header on desktop and mobile.
from pathlib import Path
import zipfile, shutil, re, subprocess
base_zip = Path(“/mnt/data/rx-theme-v9-1-github-inspired-header.zip”)
fallbacks = [
Path(“/mnt/data/rx-theme-v9-0-unified-app-plugin-loader.zip”),
Path(“/mnt/data/rx-theme-v8-9-dist-assets-manager.zip”),
]
if not base_zip.exists():
for f in fallbacks:
if f.exists():
base_zip = f
break
work_root = Path(“/mnt/data/rx_v911_logo_fit_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-v9-1-1-logo-fit-fix”
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 v9.1.1 Logo Fit Fix”, s, count=1) if “Theme Name:” in s else “/*\nTheme Name: RX Theme v9.1.1 Logo Fit Fix\nVersion: 9.1.1\n*/\n” + s
s = re.sub(r”Version:\s*.*”, “Version: 9.1.1”, s, count=1) if “Version:” in s else s.replace(“*/”, “Version: 9.1.1\n*/”, 1)
write(style_path, s)
css_path = theme_root / “assets/css/frontend/github-inspired-header.css”
if not css_path.exists():
css_path.parent.mkdir(parents=True, exist_ok=True)
css = “”
else:
css = read(css_path)
logo_fix_css = r”’
/* RX Theme v9.1.1 – Perfect logo fit fix */
.rx-v91-brand{
width:200px;
min-width:200px;
max-width:200px;
height:68px;
overflow:hidden;
}
.rx-v91-brand .custom-logo-link,
.rx-v91-brand .rx-custom-logo-link{
width:100%;
height:100%;
display:flex;
align-items:center;
justify-content:flex-start;
overflow:hidden;
}
.rx-v91-brand img,
.rx-v91-brand .custom-logo,
.rx-v91-brand .rx-custom-logo{
display:block;
width:100%;
max-width:190px;
height:56px;
max-height:56px;
object-fit:contain;
object-position:left center;
margin:0;
padding:0;
}
/* If logo image has extra transparent area, this keeps it inside header */
.rx-v91-header .custom-logo-link img{
object-fit:contain!important;
}
/* Prevent menu from pushing logo or wrapping badly */
.rx-v91-header__inner{
overflow:visible;
}
.rx-v91-nav{
min-width:0;
}
.rx-v91-nav > ul{
min-width:0;
}
@media(max-width:1220px){
.rx-v91-brand{
width:180px;
min-width:180px;
max-width:180px;
height:64px;
}
.rx-v91-brand img,
.rx-v91-brand .custom-logo,
.rx-v91-brand .rx-custom-logo{
max-width:172px;
height:52px;
max-height:52px;
}
}
@media(max-width:700px){
.rx-v91-brand{
width:170px;
min-width:0;
max-width:calc(100% – 56px);
height:58px;
}
.rx-v91-brand img,
.rx-v91-brand .custom-logo,
.rx-v91-brand .rx-custom-logo{
max-width:165px;
height:48px;
max-height:48px;
}
}
@media(max-width:420px){
.rx-v91-brand{
width:150px;
max-width:150px;
height:54px;
}
.rx-v91-brand img,
.rx-v91-brand .custom-logo,
.rx-v91-brand .rx-custom-logo{
max-width:145px;
height:44px;
max-height:44px;
}
}
”’
if “RX Theme v9.1.1 – Perfect logo fit fix” not in css:
css += logo_fix_css
write(css_path, css)
# Create logo guide file
guide = “””# RX Theme Logo Guide
Best logo format:
– SVG is best
– Transparent PNG is second best
Best size:
– Desktop logo canvas: 600 x 180 px
– Ratio: around 10:3 or 3.3:1
– Keep transparent padding small
– Keep the visible logo centered vertically
Recommended export:
– SVG: rx-logo.svg
– PNG: rx-logo-600×180.png
WordPress:
Appearance → Customize → Site Identity → Logo
The theme CSS will fit the logo inside:
– Desktop: 200px wide area, 56px image height
– Tablet: 180px wide area, 52px image height
– Mobile: 150–170px wide area, 44–48px image height
“””
write(theme_root / “assets/images/logo/LOGO-GUIDE.txt”, guide)
# 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-v9-1-1-logo-fit-fix.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”)
print(“Added: logo fit CSS + logo guide”)
=============================================
Yes dear friend — now I understand perfectly. You do not want to change the logo image. You want the whole header background color changed from deep black to a silver / milky white GitHub-like light header. I’ll make a safe update now.
from pathlib import Path
import zipfile, shutil, re, subprocess
base_zip = Path(“/mnt/data/rx-theme-v9-1-1-logo-fit-fix.zip”)
fallbacks = [
Path(“/mnt/data/rx-theme-v9-1-github-inspired-header.zip”),
Path(“/mnt/data/rx-theme-v9-0-unified-app-plugin-loader.zip”),
]
if not base_zip.exists():
for f in fallbacks:
if f.exists():
base_zip = f
break
work_root = Path(“/mnt/data/rx_v912_light_header_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-v9-1-2-silver-milky-header”
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 v9.1.2 Silver Milky Header”, s, count=1) if “Theme Name:” in s else “/*\nTheme Name: RX Theme v9.1.2 Silver Milky Header\nVersion: 9.1.2\n*/\n” + s
s = re.sub(r”Version:\s*.*”, “Version: 9.1.2”, s, count=1) if “Version:” in s else s.replace(“*/”, “Version: 9.1.2\n*/”, 1)
write(style_path, s)
css_path = theme_root / “assets/css/frontend/github-inspired-header.css”
css = read(css_path) if css_path.exists() else “”
light_header_css = r”’
/* RX Theme v9.1.2 – Silver / milky white professional header background */
:root{
–rx-v91-header-bg:#f6f8fa;
–rx-v91-header-text:#1f2937;
–rx-v91-header-muted:#57606a;
–rx-v91-header-border:#d0d7de;
–rx-v91-header-hover:#ffffff;
}
.rx-v91-header{
background:
linear-gradient(180deg,#ffffff 0%,#f6f8fa 52%,#eef2f6 100%) !important;
color:#1f2937 !important;
border-top:4px solid var(–rx-primary-color,#0066cc);
border-bottom:1px solid #d0d7de !important;
box-shadow:0 8px 24px rgba(15,23,42,.08) !important;
}
.rx-v91-nav a,
.rx-v91-action-link,
.rx-v91-login{
color:#111827 !important;
}
.rx-v91-nav a:hover,
.rx-v91-nav a:focus{
background:#ffffff !important;
color:var(–rx-primary-color,#0066cc) !important;
}
.rx-v91-caret{
color:#57606a !important;
}
.rx-v91-dropdown{
background:#ffffff !important;
border-color:#d0d7de !important;
box-shadow:0 18px 48px rgba(15,23,42,.14) !important;
}
.rx-v91-dropdown::before{
background:#ffffff !important;
border-color:#d0d7de !important;
}
.rx-v91-dropdown a{
color:#111827 !important;
}
.rx-v91-dropdown a:hover,
.rx-v91-dropdown a:focus{
background:#f6f8fa !important;
color:var(–rx-primary-color,#0066cc) !important;
}
.rx-v91-search{
background:#ffffff !important;
border:1px solid #b8c2cc !important;
box-shadow:inset 0 1px 0 rgba(255,255,255,.8);
}
.rx-v91-search:focus-within{
border-color:var(–rx-primary-color,#0066cc) !important;
box-shadow:0 0 0 3px rgba(0,102,204,.12) !important;
}
.rx-v91-search input{
color:#111827 !important;
}
.rx-v91-search input::placeholder{
color:#57606a !important;
}
.rx-v91-search__icon{
color:#57606a !important;
}
.rx-v91-search button{
background:#f6f8fa !important;
color:#111827 !important;
border-color:#c9d1d9 !important;
}
.rx-v91-search button:hover,
.rx-v91-search button:focus{
background:#eaeef2 !important;
}
.rx-v91-signup{
color:#111827 !important;
border-color:#8c959f !important;
background:#ffffff !important;
}
.rx-v91-signup:hover,
.rx-v91-signup:focus{
color:#ffffff !important;
background:var(–rx-primary-color,#0066cc) !important;
border-color:var(–rx-primary-color,#0066cc) !important;
}
.rx-v91-theme-toggle,
.rx-v91-menu-toggle{
color:#111827 !important;
background:#ffffff !important;
border-color:#c9d1d9 !important;
}
.rx-v91-theme-toggle:hover,
.rx-v91-menu-toggle:hover{
background:#eef2f6 !important;
}
.rx-v91-menu-toggle__bars,
.rx-v91-menu-toggle__bars::before,
.rx-v91-menu-toggle__bars::after{
background:#111827 !important;
}
.rx-v91-menu-toggle[aria-expanded=”true”] .rx-v91-menu-toggle__bars{
background:transparent !important;
}
/* logo visibility on light header */
.rx-v91-brand img,
.rx-v91-brand .custom-logo,
.rx-v91-brand .rx-custom-logo{
filter:none !important;
}
/* Mobile panel also light */
@media(max-width:1020px){
.rx-v91-nav{
background:#ffffff !important;
border-color:#d0d7de !important;
box-shadow:0 18px 50px rgba(15,23,42,.13);
}
.rx-v91-dropdown{
background:transparent !important;
box-shadow:none !important;
}
.rx-v91-dropdown a{
color:#374151 !important;
}
}
/* Keep real dark mode possible only when body has rx-dark-mode */
body.rx-dark-mode .rx-v91-header{
background:#0d1117 !important;
color:#f0f6fc !important;
border-top-color:var(–rx-primary-color,#0066cc);
border-bottom-color:#30363d !important;
}
body.rx-dark-mode .rx-v91-nav a,
body.rx-dark-mode .rx-v91-action-link,
body.rx-dark-mode .rx-v91-login{
color:#f0f6fc !important;
}
body.rx-dark-mode .rx-v91-nav a:hover,
body.rx-dark-mode .rx-v91-nav a:focus{
background:#161b22 !important;
color:#ffffff !important;
}
body.rx-dark-mode .rx-v91-search{
background:#0d1117 !important;
border-color:#57606a !important;
}
body.rx-dark-mode .rx-v91-search input{
color:#f0f6fc !important;
}
body.rx-dark-mode .rx-v91-search button{
background:#161b22 !important;
color:#c9d1d9 !important;
border-color:#57606a !important;
}
body.rx-dark-mode .rx-v91-dropdown{
background:#161b22 !important;
border-color:#30363d !important;
}
body.rx-dark-mode .rx-v91-dropdown::before{
background:#161b22 !important;
border-color:#30363d !important;
}
body.rx-dark-mode .rx-v91-dropdown a{
color:#f0f6fc !important;
}
body.rx-dark-mode .rx-v91-signup{
color:#f0f6fc !important;
background:transparent !important;
border-color:#8b949e !important;
}
body.rx-dark-mode .rx-v91-theme-toggle,
body.rx-dark-mode .rx-v91-menu-toggle{
color:#f0f6fc !important;
background:transparent !important;
border-color:#57606a !important;
}
body.rx-dark-mode .rx-v91-menu-toggle__bars,
body.rx-dark-mode .rx-v91-menu-toggle__bars::before,
body.rx-dark-mode .rx-v91-menu-toggle__bars::after{
background:#f0f6fc !important;
}
”’
if “RX Theme v9.1.2 – Silver / milky white professional header background” not in css:
css += light_header_css
write(css_path, css)
# 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-v9-1-2-silver-milky-header.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”)
print(“Added: whole header silver/milky white background CSS”)
Yes dear friend — I will create a safe version with visitor Sign in / Sign up pages, while keeping the normal WordPress login/register for administrator and author. Then I’ll link the header buttons to these new visitor pages.
from pathlib import Path
import zipfile, shutil, re, subprocess
base_zip = Path(“/mnt/data/rx-theme-v9-1-2-silver-milky-header.zip”)
fallbacks = [
Path(“/mnt/data/rx-theme-v9-1-1-logo-fit-fix.zip”),
Path(“/mnt/data/rx-theme-v9-1-github-inspired-header.zip”),
Path(“/mnt/data/rx-theme-v9-0-unified-app-plugin-loader.zip”),
]
if not base_zip.exists():
for f in fallbacks:
if f.exists():
base_zip = f
break
work_root = Path(“/mnt/data/rx_v913_visitor_auth_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-v9-1-3-visitor-auth-pages”
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 v9.1.3 Visitor Auth Pages”, s, count=1) if “Theme Name:” in s else “/*\nTheme Name: RX Theme v9.1.3 Visitor Auth Pages\nVersion: 9.1.3\n*/\n” + s
s = re.sub(r”Version:\s*.*”, “Version: 9.1.3”, s, count=1) if “Version:” in s else s.replace(“*/”, “Version: 9.1.3\n*/”, 1)
write(style_path, s)
# Directories
for d in [“inc/auth”, “templates”, “assets/css/frontend”, “assets/js/frontend”]:
(theme_root / d).mkdir(parents=True, exist_ok=True)
# Auth PHP
auth_php = r”'<?php
/**
* RX Theme v9.1.3 Visitor Sign in / Sign up Pages.
* Keeps WordPress default wp-login.php for administrators/authors.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
function rx_theme_v913_auth_assets() {
$theme_uri = get_template_directory_uri();
$theme_dir = get_template_directory();
$css_rel = ‘/assets/css/frontend/visitor-auth.css’;
$js_rel = ‘/assets/js/frontend/visitor-auth.js’;
if ( file_exists( $theme_dir . $css_rel ) ) {
wp_enqueue_style(
‘rx-theme-visitor-auth’,
$theme_uri . $css_rel,
array(),
filemtime( $theme_dir . $css_rel )
);
}
if ( file_exists( $theme_dir . $js_rel ) ) {
wp_enqueue_script(
‘rx-theme-visitor-auth’,
$theme_uri . $js_rel,
array(),
filemtime( $theme_dir . $js_rel ),
true
);
}
}
add_action( ‘wp_enqueue_scripts’, ‘rx_theme_v913_auth_assets’, 260 );
function rx_theme_v913_signin_url() {
$page = get_page_by_path( ‘rx-signin’ );
return $page ? get_permalink( $page ) : home_url( ‘/rx-signin/’ );
}
function rx_theme_v913_signup_url() {
$page = get_page_by_path( ‘rx-signup’ );
return $page ? get_permalink( $page ) : home_url( ‘/rx-signup/’ );
}
function rx_theme_v913_account_url() {
$page = get_page_by_path( ‘rx-account’ );
return $page ? get_permalink( $page ) : admin_url( ‘profile.php’ );
}
function rx_theme_v913_create_auth_pages() {
$pages = array(
‘rx-signin’ => array(
‘title’ => ‘Visitor Sign in’,
‘content’ => ‘[rx_visitor_signin]’,
),
‘rx-signup’ => array(
‘title’ => ‘Visitor Sign up’,
‘content’ => ‘[rx_visitor_signup]’,
),
‘rx-account’ => array(
‘title’ => ‘My RX Account’,
‘content’ => ‘[rx_visitor_account]’,
),
);
foreach ( $pages as $slug => $data ) {
$existing = get_page_by_path( $slug );
if ( $existing ) {
continue;
}
wp_insert_post(
array(
‘post_title’ => $data[‘title’],
‘post_name’ => $slug,
‘post_content’ => $data[‘content’],
‘post_status’ => ‘publish’,
‘post_type’ => ‘page’,
)
);
}
}
add_action( ‘after_switch_theme’, ‘rx_theme_v913_create_auth_pages’ );
function rx_theme_v913_auth_notice() {
$key = ”;
foreach ( array( ‘rx_login’, ‘rx_register’, ‘rx_account’ ) as $query_key ) {
if ( isset( $_GET[ $query_key ] ) ) {
$key = sanitize_key( wp_unslash( $_GET[ $query_key ] ) );
break;
}
}
if ( ! $key ) {
return ”;
}
$messages = array(
’empty’ => __( ‘Please fill in all required fields.’, ‘rx-theme’ ),
‘invalid’ => __( ‘Invalid email, username, or password. Please try again.’, ‘rx-theme’ ),
‘exists’ => __( ‘This username or email already exists.’, ‘rx-theme’ ),
‘registered’ => __( ‘Registration successful. Please sign in.’, ‘rx-theme’ ),
‘loggedout’ => __( ‘You have been signed out.’, ‘rx-theme’ ),
‘security’ => __( ‘Security check failed. Please refresh and try again.’, ‘rx-theme’ ),
‘weak’ => __( ‘Please choose a stronger password.’, ‘rx-theme’ ),
‘success’ => __( ‘Success.’, ‘rx-theme’ ),
);
$type = in_array( $key, array( ‘registered’, ‘loggedout’, ‘success’ ), true ) ? ‘success’ : ‘error’;
return ‘<div class=”rx-auth-notice rx-auth-notice–‘ . esc_attr( $type ) . ‘”>’ . esc_html( $messages[ $key ] ?? __( ‘Please try again.’, ‘rx-theme’ ) ) . ‘</div>’;
}
function rx_theme_v913_handle_signin() {
if ( empty( $_POST[‘rx_visitor_auth_action’] ) || ‘signin’ !== sanitize_key( wp_unslash( $_POST[‘rx_visitor_auth_action’] ) ) ) {
return;
}
if ( empty( $_POST[‘rx_visitor_signin_nonce’] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST[‘rx_visitor_signin_nonce’] ) ), ‘rx_visitor_signin’ ) ) {
wp_safe_redirect( add_query_arg( ‘rx_login’, ‘security’, rx_theme_v913_signin_url() ) );
exit;
}
$login = isset( $_POST[‘rx_login’] ) ? sanitize_text_field( wp_unslash( $_POST[‘rx_login’] ) ) : ”;
$password = isset( $_POST[‘rx_password’] ) ? (string) wp_unslash( $_POST[‘rx_password’] ) : ”;
$remember = ! empty( $_POST[‘rx_remember’] );
if ( ! $login || ! $password ) {
wp_safe_redirect( add_query_arg( ‘rx_login’, ’empty’, rx_theme_v913_signin_url() ) );
exit;
}
$creds = array(
‘user_login’ => $login,
‘user_password’ => $password,
‘remember’ => $remember,
);
$user = wp_signon( $creds, is_ssl() );
if ( is_wp_error( $user ) ) {
wp_safe_redirect( add_query_arg( ‘rx_login’, ‘invalid’, rx_theme_v913_signin_url() ) );
exit;
}
wp_safe_redirect( rx_theme_v913_account_url() );
exit;
}
add_action( ‘init’, ‘rx_theme_v913_handle_signin’ );
function rx_theme_v913_handle_signup() {
if ( empty( $_POST[‘rx_visitor_auth_action’] ) || ‘signup’ !== sanitize_key( wp_unslash( $_POST[‘rx_visitor_auth_action’] ) ) ) {
return;
}
if ( empty( $_POST[‘rx_visitor_signup_nonce’] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST[‘rx_visitor_signup_nonce’] ) ), ‘rx_visitor_signup’ ) ) {
wp_safe_redirect( add_query_arg( ‘rx_register’, ‘security’, rx_theme_v913_signup_url() ) );
exit;
}
$username = isset( $_POST[‘rx_username’] ) ? sanitize_user( wp_unslash( $_POST[‘rx_username’] ) ) : ”;
$email = isset( $_POST[‘rx_email’] ) ? sanitize_email( wp_unslash( $_POST[‘rx_email’] ) ) : ”;
$password = isset( $_POST[‘rx_password’] ) ? (string) wp_unslash( $_POST[‘rx_password’] ) : ”;
if ( ! $username || ! is_email( $email ) || ! $password ) {
wp_safe_redirect( add_query_arg( ‘rx_register’, ’empty’, rx_theme_v913_signup_url() ) );
exit;
}
if ( username_exists( $username ) || email_exists( $email ) ) {
wp_safe_redirect( add_query_arg( ‘rx_register’, ‘exists’, rx_theme_v913_signup_url() ) );
exit;
}
if ( strlen( $password ) < 8 ) {
wp_safe_redirect( add_query_arg( ‘rx_register’, ‘weak’, rx_theme_v913_signup_url() ) );
exit;
}
$user_id = wp_create_user( $username, $password, $email );
if ( is_wp_error( $user_id ) ) {
wp_safe_redirect( add_query_arg( ‘rx_register’, ‘invalid’, rx_theme_v913_signup_url() ) );
exit;
}
$user = new WP_User( $user_id );
$user->set_role( get_option( ‘default_role’, ‘subscriber’ ) );
wp_safe_redirect( add_query_arg( ‘rx_login’, ‘registered’, rx_theme_v913_signin_url() ) );
exit;
}
add_action( ‘init’, ‘rx_theme_v913_handle_signup’ );
function rx_theme_v913_visitor_signin_shortcode() {
if ( is_user_logged_in() ) {
return rx_theme_v913_account_box();
}
ob_start();
?>
<section class=”rx-auth-page rx-auth-page–signin”>
<div class=”rx-auth-card”>
<div class=”rx-auth-brand”>
<span><?php esc_html_e( ‘RXHARUN.COM’, ‘rx-theme’ ); ?></span>
<h1><?php esc_html_e( ‘Visitor Sign in’, ‘rx-theme’ ); ?></h1>
<p><?php esc_html_e( ‘Access your visitor account, saved health guides, and RX community features.’, ‘rx-theme’ ); ?></p>
</div>
<?php echo wp_kses_post( rx_theme_v913_auth_notice() ); ?>
<form class=”rx-auth-form” method=”post”>
<input type=”hidden” name=”rx_visitor_auth_action” value=”signin”>
<?php wp_nonce_field( ‘rx_visitor_signin’, ‘rx_visitor_signin_nonce’ ); ?>
<p>
<label for=”rx-login”><?php esc_html_e( ‘Username or Email’, ‘rx-theme’ ); ?></label>
<input id=”rx-login” type=”text” name=”rx_login” required autocomplete=”username”>
</p>
<p>
<label for=”rx-password”><?php esc_html_e( ‘Password’, ‘rx-theme’ ); ?></label>
<input id=”rx-password” type=”password” name=”rx_password” required autocomplete=”current-password”>
</p>
<p class=”rx-auth-row”>
<label class=”rx-auth-check”>
<input type=”checkbox” name=”rx_remember” value=”1″>
<?php esc_html_e( ‘Remember me’, ‘rx-theme’ ); ?>
</label>
<a href=”<?php echo esc_url( wp_lostpassword_url() ); ?>”><?php esc_html_e( ‘Forgot password?’, ‘rx-theme’ ); ?></a>
</p>
<button type=”submit”><?php esc_html_e( ‘Sign in’, ‘rx-theme’ ); ?></button>
</form>
<div class=”rx-auth-footer”>
<?php esc_html_e( ‘New visitor?’, ‘rx-theme’ ); ?>
<a href=”<?php echo esc_url( rx_theme_v913_signup_url() ); ?>”><?php esc_html_e( ‘Create visitor account’, ‘rx-theme’ ); ?></a>
</div>
<div class=”rx-auth-admin-link”>
<a href=”<?php echo esc_url( wp_login_url() ); ?>”><?php esc_html_e( ‘Administrator / Author WordPress Login’, ‘rx-theme’ ); ?></a>
</div>
</div>
</section>
<?php
return ob_get_clean();
}
add_shortcode( ‘rx_visitor_signin’, ‘rx_theme_v913_visitor_signin_shortcode’ );
function rx_theme_v913_visitor_signup_shortcode() {
if ( is_user_logged_in() ) {
return rx_theme_v913_account_box();
}
ob_start();
?>
<section class=”rx-auth-page rx-auth-page–signup”>
<div class=”rx-auth-card”>
<div class=”rx-auth-brand”>
<span><?php esc_html_e( ‘RXHARUN.COM’, ‘rx-theme’ ); ?></span>
<h1><?php esc_html_e( ‘Create Visitor Account’, ‘rx-theme’ ); ?></h1>
<p><?php esc_html_e( ‘Join RXHarun as a visitor. Your account will use the safe WordPress subscriber role by default.’, ‘rx-theme’ ); ?></p>
</div>
<?php echo wp_kses_post( rx_theme_v913_auth_notice() ); ?>
<form class=”rx-auth-form” method=”post”>
<input type=”hidden” name=”rx_visitor_auth_action” value=”signup”>
<?php wp_nonce_field( ‘rx_visitor_signup’, ‘rx_visitor_signup_nonce’ ); ?>
<p>
<label for=”rx-username”><?php esc_html_e( ‘Username’, ‘rx-theme’ ); ?></label>
<input id=”rx-username” type=”text” name=”rx_username” required autocomplete=”username”>
</p>
<p>
<label for=”rx-email”><?php esc_html_e( ‘Email’, ‘rx-theme’ ); ?></label>
<input id=”rx-email” type=”email” name=”rx_email” required autocomplete=”email”>
</p>
<p>
<label for=”rx-new-password”><?php esc_html_e( ‘Password’, ‘rx-theme’ ); ?></label>
<input id=”rx-new-password” type=”password” name=”rx_password” required autocomplete=”new-password” minlength=”8″>
<small><?php esc_html_e( ‘Minimum 8 characters.’, ‘rx-theme’ ); ?></small>
</p>
<button type=”submit”><?php esc_html_e( ‘Create Account’, ‘rx-theme’ ); ?></button>
</form>
<div class=”rx-auth-footer”>
<?php esc_html_e( ‘Already have an account?’, ‘rx-theme’ ); ?>
<a href=”<?php echo esc_url( rx_theme_v913_signin_url() ); ?>”><?php esc_html_e( ‘Sign in’, ‘rx-theme’ ); ?></a>
</div>
<div class=”rx-auth-admin-link”>
<a href=”<?php echo esc_url( wp_login_url() ); ?>”><?php esc_html_e( ‘Administrator / Author WordPress Login’, ‘rx-theme’ ); ?></a>
</div>
</div>
</section>
<?php
return ob_get_clean();
}
add_shortcode( ‘rx_visitor_signup’, ‘rx_theme_v913_visitor_signup_shortcode’ );
function rx_theme_v913_account_box() {
$user = wp_get_current_user();
ob_start();
?>
<section class=”rx-auth-page rx-auth-page–account”>
<div class=”rx-auth-card”>
<div class=”rx-auth-brand”>
<span><?php esc_html_e( ‘RXHARUN.COM’, ‘rx-theme’ ); ?></span>
<h1><?php esc_html_e( ‘My RX Account’, ‘rx-theme’ ); ?></h1>
<p><?php echo esc_html( sprintf( __( ‘Welcome, %s.’, ‘rx-theme’ ), $user->display_name ? $user->display_name : $user->user_login ) ); ?></p>
</div>
<div class=”rx-account-actions”>
<a class=”rx-account-button” href=”<?php echo esc_url( admin_url( ‘profile.php’ ) ); ?>”><?php esc_html_e( ‘Edit Profile’, ‘rx-theme’ ); ?></a>
<a class=”rx-account-button rx-account-button–logout” href=”<?php echo esc_url( wp_logout_url( add_query_arg( ‘rx_login’, ‘loggedout’, rx_theme_v913_signin_url() ) ) ); ?>”><?php esc_html_e( ‘Sign out’, ‘rx-theme’ ); ?></a>
</div>
</div>
</section>
<?php
return ob_get_clean();
}
function rx_theme_v913_account_shortcode() {
if ( ! is_user_logged_in() ) {
wp_safe_redirect( rx_theme_v913_signin_url() );
exit;
}
return rx_theme_v913_account_box();
}
add_shortcode( ‘rx_visitor_account’, ‘rx_theme_v913_account_shortcode’ );
”’
write(theme_root / “inc/auth/visitor-auth.php”, auth_php)
# Templates
signin_template = r”'<?php
/**
* Template Name: RX Visitor Sign in
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
get_header();
echo ‘<main id=”primary” class=”rx-main”><div class=”rx-container”>’;
echo do_shortcode( ‘[rx_visitor_signin]’ );
echo ‘</div></main>’;
get_footer();
”’
signup_template = signin_template.replace(“Template Name: RX Visitor Sign in”, “Template Name: RX Visitor Sign up”).replace(“[rx_visitor_signin]”, “[rx_visitor_signup]”)
account_template = signin_template.replace(“Template Name: RX Visitor Sign in”, “Template Name: RX Visitor Account”).replace(“[rx_visitor_signin]”, “[rx_visitor_account]”)
write(theme_root / “templates/template-visitor-signin.php”, signin_template)
write(theme_root / “templates/template-visitor-signup.php”, signup_template)
write(theme_root / “templates/template-visitor-account.php”, account_template)
# CSS
auth_css = r”’/* RX Theme v9.1.3 Visitor Auth Pages */
.rx-auth-page{
min-height:calc(100vh – 160px);
display:flex;
align-items:center;
justify-content:center;
padding:46px 0;
}
.rx-auth-card{
width:min(100%,560px);
padding:34px;
border:1px solid #e5e7eb;
border-radius:30px;
background:
radial-gradient(circle at top right, rgba(0,102,204,.12), transparent 38%),
linear-gradient(135deg,#ffffff,#f8fbff);
box-shadow:0 24px 70px rgba(15,23,42,.12);
}
.rx-auth-brand span{
display:inline-flex;
padding:7px 12px;
border-radius:999px;
background:#eff6ff;
color:var(–rx-primary-color,#0066cc);
font-weight:900;
letter-spacing:.06em;
font-size:12px;
}
.rx-auth-brand h1{
margin:14px 0 10px;
color:var(–rx-heading-color,#111827);
font-size:clamp(30px,4vw,46px);
line-height:1.05;
}
.rx-auth-brand p{
margin:0 0 24px;
color:#64748b;
line-height:1.7;
}
.rx-auth-form p{
margin:0 0 16px;
}
.rx-auth-form label{
display:block;
margin-bottom:7px;
color:#111827;
font-weight:900;
}
.rx-auth-form input[type=”text”],
.rx-auth-form input[type=”email”],
.rx-auth-form input[type=”password”]{
width:100%;
min-height:48px;
border:1px solid #cbd5e1;
border-radius:16px;
padding:0 15px;
background:#fff;
color:#111827;
outline:none;
}
.rx-auth-form input:focus{
border-color:var(–rx-primary-color,#0066cc);
box-shadow:0 0 0 4px rgba(0,102,204,.12);
}
.rx-auth-form small{
display:block;
margin-top:6px;
color:#64748b;
}
.rx-auth-row{
display:flex;
align-items:center;
justify-content:space-between;
gap:12px;
}
.rx-auth-check{
display:flex!important;
align-items:center;
gap:8px;
margin:0!important;
font-weight:700!important;
}
.rx-auth-check input{
width:auto;
}
.rx-auth-form button{
width:100%;
min-height:48px;
border:0;
border-radius:999px;
background:linear-gradient(135deg,var(–rx-primary-color,#0066cc),var(–rx-secondary-color,#00a884));
color:#fff;
font-weight:1000;
cursor:pointer;
box-shadow:0 14px 34px rgba(0,102,204,.22);
}
.rx-auth-footer,
.rx-auth-admin-link{
margin-top:18px;
text-align:center;
color:#64748b;
}
.rx-auth-footer a,
.rx-auth-admin-link a,
.rx-auth-row a{
color:var(–rx-primary-color,#0066cc);
font-weight:900;
text-decoration:none;
}
.rx-auth-admin-link{
padding-top:16px;
border-top:1px solid #e5e7eb;
font-size:14px;
}
.rx-auth-notice{
margin:0 0 18px;
padding:13px 15px;
border-radius:16px;
font-weight:800;
}
.rx-auth-notice–success{
background:#ecfdf5;
border:1px solid #bbf7d0;
color:#047857;
}
.rx-auth-notice–error{
background:#fef2f2;
border:1px solid #fecaca;
color:#b91c1c;
}
.rx-account-actions{
display:flex;
flex-wrap:wrap;
gap:12px;
}
.rx-account-button{
display:inline-flex;
align-items:center;
justify-content:center;
min-height:44px;
padding:0 18px;
border-radius:999px;
background:var(–rx-primary-color,#0066cc);
color:#fff;
font-weight:900;
text-decoration:none;
}
.rx-account-button–logout{
background:#b91c1c;
}
body.rx-dark-mode .rx-auth-card{
background:#111827;
border-color:#243244;
}
body.rx-dark-mode .rx-auth-brand h1,
body.rx-dark-mode .rx-auth-form label{
color:#fff;
}
body.rx-dark-mode .rx-auth-brand p,
body.rx-dark-mode .rx-auth-footer,
body.rx-dark-mode .rx-auth-admin-link{
color:#cbd5e1;
}
body.rx-dark-mode .rx-auth-form input{
background:#0f172a;
border-color:#243244;
color:#fff;
}
body.rx-dark-mode .rx-auth-admin-link{
border-top-color:#243244;
}
@media(max-width:640px){
.rx-auth-page{
padding:28px 0;
}
.rx-auth-card{
padding:24px;
border-radius:24px;
}
.rx-auth-row{
display:block;
}
.rx-auth-row a{
display:inline-block;
margin-top:10px;
}
}
”’
write(theme_root / “assets/css/frontend/visitor-auth.css”, auth_css)
# JS small
write(theme_root / “assets/js/frontend/visitor-auth.js”, r”’/* RX Theme v9.1.3 Visitor Auth */
(function(){
‘use strict’;
document.querySelectorAll(‘.rx-auth-form’).forEach(function(form){
form.addEventListener(‘submit’, function(){
const button = form.querySelector(‘button[type=”submit”]’);
if (button) {
button.disabled = true;
button.dataset.originalText = button.textContent;
button.textContent = ‘Please wait…’;
}
});
});
})();
”’)
# Update header links in github-inspired-header.php
header_file = theme_root / “inc/header/github-inspired-header.php”
if header_file.exists():
h = read(header_file)
h = h.replace(“href=\”<?php echo esc_url( wp_login_url() ); ?>\””, “href=\”<?php echo esc_url( function_exists( ‘rx_theme_v913_signin_url’ ) ? rx_theme_v913_signin_url() : wp_login_url() ); ?>\””)
h = h.replace(“href=\”<?php echo esc_url( wp_registration_url() ); ?>\””, “href=\”<?php echo esc_url( function_exists( ‘rx_theme_v913_signup_url’ ) ? rx_theme_v913_signup_url() : wp_registration_url() ); ?>\””)
# If logged in, show account/sign out via more robust replacement around actions links
h = h.replace(“””<a class=”rx-v91-action-link rx-v91-login” href=”<?php echo esc_url( function_exists( ‘rx_theme_v913_signin_url’ ) ? rx_theme_v913_signin_url() : wp_login_url() ); ?>”>
<?php esc_html_e( ‘Sign in’, ‘rx-theme’ ); ?>
</a>
<a class=”rx-v91-signup” href=”<?php echo esc_url( function_exists( ‘rx_theme_v913_signup_url’ ) ? rx_theme_v913_signup_url() : wp_registration_url() ); ?>”>
<?php esc_html_e( ‘Sign up’, ‘rx-theme’ ); ?>
</a>”””,
“””<?php if ( is_user_logged_in() ) : ?>
<a class=”rx-v91-action-link rx-v91-login” href=”<?php echo esc_url( function_exists( ‘rx_theme_v913_account_url’ ) ? rx_theme_v913_account_url() : admin_url( ‘profile.php’ ) ); ?>”>
<?php esc_html_e( ‘Account’, ‘rx-theme’ ); ?>
</a>
<a class=”rx-v91-signup” href=”<?php echo esc_url( wp_logout_url( function_exists( ‘rx_theme_v913_signin_url’ ) ? add_query_arg( ‘rx_login’, ‘loggedout’, rx_theme_v913_signin_url() ) : home_url( ‘/’ ) ) ); ?>”>
<?php esc_html_e( ‘Sign out’, ‘rx-theme’ ); ?>
</a>
<?php else : ?>
<a class=”rx-v91-action-link rx-v91-login” href=”<?php echo esc_url( function_exists( ‘rx_theme_v913_signin_url’ ) ? rx_theme_v913_signin_url() : wp_login_url() ); ?>”>
<?php esc_html_e( ‘Sign in’, ‘rx-theme’ ); ?>
</a>
<a class=”rx-v91-signup” href=”<?php echo esc_url( function_exists( ‘rx_theme_v913_signup_url’ ) ? rx_theme_v913_signup_url() : wp_registration_url() ); ?>”>
<?php esc_html_e( ‘Sign up’, ‘rx-theme’ ); ?>
</a>
<?php endif; ?>”””)
write(header_file, h)
# Loader
write(theme_root / “inc/auth/auth-loader.php”, r”'<?php
/**
* RX Theme v9.1.3 visitor auth loader.
*/
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
$rx_theme_v913_auth_file = get_template_directory() . ‘/inc/auth/visitor-auth.php’;
if ( file_exists( $rx_theme_v913_auth_file ) ) {
require_once $rx_theme_v913_auth_file;
}
”’)
# Add to autoload
autoload = theme_root / “inc/autoload.php”
if autoload.exists():
a = read(autoload)
if “/inc/auth/auth-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/auth/auth-loader.php’,\n” + before[pos:]
a = before + after
else:
a += “\nrequire_once RX_THEME_DIR . ‘/inc/auth/auth-loader.php’;\n”
else:
a += “\nrequire_once RX_THEME_DIR . ‘/inc/auth/auth-loader.php’;\n”
write(autoload, a)
else:
write(autoload, “<?php\nif ( ! defined( ‘ABSPATH’ ) ) { exit; }\nrequire_once get_template_directory() . ‘/inc/auth/auth-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-v9-1-3-visitor-auth-pages.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”)
print(“Added: visitor signin/signup/account pages + header links”)
Yes dear friend — you are 100% right. Visitor accounts must not get WordPress dashboard power. I’ll make a safer version now:
Visitors can only browse, comment, share, subscribe, and use their visitor account page. Admin/author WordPress login will be hidden from the visitor pages. Google/Facebook/ChatGPT sign-in buttons can be added as design placeholders, but real social login needs OAuth app credentials or a trusted social-login plugin/API setup.
from pathlib import Path
import zipfile, shutil, re, subprocess
base_zip = Path(“/mnt/data/rx-theme-v9-1-3-visitor-auth-pages.zip”)
fallbacks = [
Path(“/mnt/data/rx-theme-v9-1-2-silver-milky-header.zip”),
Path(“/mnt/data/rx-theme-v9-1-1-logo-fit-fix.zip”),
]
if not base_zip.exists():
for f in fallbacks:
if f.exists():
base_zip = f
break
work_root = Path(“/mnt/data/rx_v914_visitor_auth_safety_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-v9-1-4-visitor-auth-safety”
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 v9.1.4 Visitor Auth Safety”, s, count=1) if “Theme Name:” in s else “/*\nTheme Name: RX Theme v9.1.4 Visitor Auth Safety\nVersion: 9.1.4\n*/\n” + s
s = re.sub(r”Version:\s*.*”, “Version: 9.1.4”, s, count=1) if “Version:” in s else s.replace(“*/”, “Version: 9.1.4\n*/”, 1)
write(style_path, s)
auth_file = theme_root / “inc/auth/visitor-auth.php”
auth = read(auth_file)
# Remove admin author link blocks from login/signup pages by replacing exact block if present
auth = re.sub(
r’\s*<div class=”rx-auth-admin-link”>\s*<a href=”<\?php echo esc_url\( wp_login_url\(\) \); \?>”><\?php esc_html_e\( \’Administrator / Author WordPress Login\’, \’rx-theme\’ \); \?></a>\s*</div>’,
”,
auth
)
# Ensure subscriber role and no elevated role
auth = auth.replace(
“$user->set_role( get_option( ‘default_role’, ‘subscriber’ ) );”,
“$user->set_role( ‘subscriber’ );”
)
# Add safe helpers before closing or after shortcode section
safety_code = r”’
/**
* v9.1.4 Visitor safety controls.
* Visitors/subscribers can browse, comment, share, subscribe, and manage only their simple visitor page.
* Administrators, editors, authors, and other real staff roles keep normal WordPress dashboard access.
*/
function rx_theme_v914_is_limited_visitor_user( $user = null ) {
if ( ! $user ) {
$user = wp_get_current_user();
}
if ( ! $user || empty( $user->ID ) || empty( $user->roles ) ) {
return false;
}
$roles = (array) $user->roles;
if ( in_array( ‘administrator’, $roles, true ) || in_array( ‘editor’, $roles, true ) || in_array( ‘author’, $roles, true ) || in_array( ‘contributor’, $roles, true ) || in_array( ‘shop_manager’, $roles, true ) ) {
return false;
}
return in_array( ‘subscriber’, $roles, true );
}
function rx_theme_v914_limit_visitor_dashboard_access() {
if ( ! is_admin() || wp_doing_ajax() ) {
return;
}
if ( rx_theme_v914_is_limited_visitor_user() ) {
wp_safe_redirect( function_exists( ‘rx_theme_v913_account_url’ ) ? rx_theme_v913_account_url() : home_url( ‘/’ ) );
exit;
}
}
add_action( ‘admin_init’, ‘rx_theme_v914_limit_visitor_dashboard_access’ );
function rx_theme_v914_hide_admin_bar_for_visitors( $show ) {
if ( rx_theme_v914_is_limited_visitor_user() ) {
return false;
}
return $show;
}
add_filter( ‘show_admin_bar’, ‘rx_theme_v914_hide_admin_bar_for_visitors’ );
function rx_theme_v914_restrict_visitor_capabilities( $allcaps, $caps, $args, $user ) {
if ( ! rx_theme_v914_is_limited_visitor_user( $user ) ) {
return $allcaps;
}
$blocked_caps = array(
‘read_private_posts’,
‘edit_posts’,
‘edit_published_posts’,
‘edit_others_posts’,
‘publish_posts’,
‘delete_posts’,
‘delete_published_posts’,
‘delete_others_posts’,
‘upload_files’,
‘edit_pages’,
‘publish_pages’,
‘delete_pages’,
‘edit_theme_options’,
‘switch_themes’,
‘install_themes’,
‘update_themes’,
‘delete_themes’,
‘activate_plugins’,
‘install_plugins’,
‘update_plugins’,
‘delete_plugins’,
‘manage_options’,
‘manage_categories’,
‘moderate_comments’,
‘edit_users’,
‘list_users’,
‘promote_users’,
‘create_users’,
‘delete_users’,
);
foreach ( $blocked_caps as $cap ) {
$allcaps[ $cap ] = false;
}
$allcaps[‘read’] = true;
return $allcaps;
}
add_filter( ‘user_has_cap’, ‘rx_theme_v914_restrict_visitor_capabilities’, 10, 4 );
function rx_theme_v914_social_login_buttons() {
ob_start();
?>
<div class=”rx-social-login-box”>
<div class=”rx-social-login-divider”><span><?php esc_html_e( ‘or continue with’, ‘rx-theme’ ); ?></span></div>
<div class=”rx-social-login-buttons”>
<button type=”button” class=”rx-social-login-button rx-social-login-button–google” data-rx-social-login=”google”>
<?php esc_html_e( ‘Google’, ‘rx-theme’ ); ?>
</button>
<button type=”button” class=”rx-social-login-button rx-social-login-button–facebook” data-rx-social-login=”facebook”>
<?php esc_html_e( ‘Facebook’, ‘rx-theme’ ); ?>
</button>
<button type=”button” class=”rx-social-login-button rx-social-login-button–chatgpt” data-rx-social-login=”chatgpt”>
<?php esc_html_e( ‘ChatGPT’, ‘rx-theme’ ); ?>
</button>
</div>
<p class=”rx-social-login-note”>
<?php esc_html_e( ‘Social login buttons are ready for future OAuth connection. For live use, connect Google/Facebook OAuth credentials or a trusted social-login plugin.’, ‘rx-theme’ ); ?>
</p>
</div>
<?php
return ob_get_clean();
}
”’
if “v9.1.4 Visitor safety controls” not in auth:
auth += safety_code
# Insert social login buttons after notices in signin/signup if not exists
auth = auth.replace(
“<?php echo wp_kses_post( rx_theme_v913_auth_notice() ); ?>\n\n <form class=\”rx-auth-form\” method=\”post\”>”,
“<?php echo wp_kses_post( rx_theme_v913_auth_notice() ); ?>\n\n <?php echo wp_kses_post( function_exists( ‘rx_theme_v914_social_login_buttons’ ) ? rx_theme_v914_social_login_buttons() : ” ); ?>\n\n <form class=\”rx-auth-form\” method=\”post\”>”
)
# Change account edit profile to front message/no dashboard for subscribers; keep dashboard profile for staff maybe inside account_box
auth = auth.replace(
“””<a class=”rx-account-button” href=”<?php echo esc_url( admin_url( ‘profile.php’ ) ); ?>”><?php esc_html_e( ‘Edit Profile’, ‘rx-theme’ ); ?></a>”””,
“””<?php if ( function_exists( ‘rx_theme_v914_is_limited_visitor_user’ ) && rx_theme_v914_is_limited_visitor_user() ) : ?>
<span class=”rx-account-button rx-account-button–disabled”><?php esc_html_e( ‘Visitor browsing mode’, ‘rx-theme’ ); ?></span>
<?php else : ?>
<a class=”rx-account-button” href=”<?php echo esc_url( admin_url( ‘profile.php’ ) ); ?>”><?php esc_html_e( ‘Edit Profile’, ‘rx-theme’ ); ?></a>
<?php endif; ?>”””
)
write(auth_file, auth)
# Update CSS
css_file = theme_root / “assets/css/frontend/visitor-auth.css”
css = read(css_file) if css_file.exists() else “”
css_add = r”’
/* RX Theme v9.1.4 Visitor auth safety + social login UI */
.rx-social-login-box{
margin:0 0 20px;
}
.rx-social-login-divider{
display:flex;
align-items:center;
gap:12px;
margin:16px 0;
color:#64748b;
font-size:13px;
font-weight:800;
}
.rx-social-login-divider::before,
.rx-social-login-divider::after{
content:”;
flex:1;
height:1px;
background:#e5e7eb;
}
.rx-social-login-buttons{
display:grid;
grid-template-columns:repeat(3,minmax(0,1fr));
gap:10px;
}
.rx-social-login-button{
min-height:42px;
border:1px solid #cbd5e1;
border-radius:999px;
background:#fff;
color:#111827;
font-weight:900;
cursor:pointer;
}
.rx-social-login-button–google{
border-color:#d1d5db;
}
.rx-social-login-button–facebook{
border-color:#bfdbfe;
color:#1d4ed8;
}
.rx-social-login-button–chatgpt{
border-color:#bbf7d0;
color:#047857;
}
.rx-social-login-button:hover,
.rx-social-login-button:focus{
box-shadow:0 10px 24px rgba(15,23,42,.1);
transform:translateY(-1px);
}
.rx-social-login-note{
margin:10px 0 0!important;
color:#64748b!important;
font-size:12px;
line-height:1.5!important;
}
.rx-account-button–disabled{
background:#e5e7eb!important;
color:#475569!important;
cursor:default;
}
body.rx-dark-mode .rx-social-login-divider::before,
body.rx-dark-mode .rx-social-login-divider::after{
background:#243244;
}
body.rx-dark-mode .rx-social-login-button{
background:#0f172a;
border-color:#243244;
color:#e5e7eb;
}
@media(max-width:520px){
.rx-social-login-buttons{
grid-template-columns:1fr;
}
}
”’
if “RX Theme v9.1.4 Visitor auth safety” not in css:
css += css_add
write(css_file, css)
# Update JS social placeholder message
js_file = theme_root / “assets/js/frontend/visitor-auth.js”
js = read(js_file) if js_file.exists() else “”
js_add = r”’
document.addEventListener(‘click’, function(event){
const button = event.target.closest(‘[data-rx-social-login]’);
if (!button) return;
event.preventDefault();
let notice = document.querySelector(‘.rx-auth-notice’);
if (!notice) {
notice = document.createElement(‘div’);
notice.className = ‘rx-auth-notice rx-auth-notice–error’;
const card = document.querySelector(‘.rx-auth-card’);
const brand = document.querySelector(‘.rx-auth-brand’);
if (card && brand) {
brand.insertAdjacentElement(‘afterend’, notice);
}
}
if (notice) {
notice.className = ‘rx-auth-notice rx-auth-notice–error’;
notice.textContent = ‘Social login needs OAuth setup before live use. Normal visitor sign in/sign up is ready now.’;
}
});
”’
if “Social login needs OAuth setup” not in js:
js += js_add
write(js_file, js)
# Maybe update header? no change needed.
# Add readme guide
guide_path = theme_root / “inc/auth/VISITOR-AUTH-SAFETY-GUIDE.txt”
write(guide_path, “””RX Theme Visitor Auth Safety Guide
Visitor account role:
– Always subscriber.
Allowed:
– Browse website
– Comment if WordPress comment settings allow it
– Share pages/articles
– Subscribe/newsletter
– View visitor account page
– Sign out
Blocked for visitor/subscriber:
– WordPress dashboard access
– Edit articles
– Delete articles
– Upload files
– Change theme
– Change plugins
– Manage options
– Manage users
– Moderate comments
– Admin bar
Admin/Author:
– Can still use /wp-login.php directly.
– Visitor pages do not show the admin login link.
Social login:
– Google/Facebook/ChatGPT buttons are UI placeholders.
– Real live social login requires OAuth app credentials or a trusted plugin/provider.
“””)
# 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-v9-1-4-visitor-auth-safety.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”)
print(“Added: visitor dashboard restriction, subscriber-only role, hidden admin login link, social login UI placeholders”)