Anura Lens Selector
Adds a "Select Lens" workflow on WooCommerce single product pages for eyewear products, with admin management for lens types and packages.
by Anura Dev · github.com/thelllmike/optical-shop_wordpress_plugin · website
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/thelllmike/optical-shop_wordpress_plugin/archive/refs/heads/main.zipA WooCommerce plugin that adds a "Select Lens" workflow on single product pages for eyewear products — similar to Lenskart's lens selection experience.
Version: 1.0.0 Requires: WordPress 5.8+, WooCommerce 6.0+, PHP 7.4+ License: GPL v2 or later
Features
- Full-screen, mobile-first modal for lens selection (Lenskart-style UI)
- Two-step workflow: Select Lens Type → Choose Lens Package → Add to Cart
- 5 default lens types: Single Vision, Bifocal/Progressive, Zero Power, Frame Only, With Power
- Admin panel under WooCommerce → Lens Selector with full CRUD for types and packages
- Custom database tables for scalability
- Dynamic pricing: Frame + Lens total pricing with automatic addon calculation
- Lens selections saved to cart item meta and order item meta
- Media library integration for package images
- Category-based product filtering (enable for all or specific categories)
- Accessible markup (ARIA labels, ESC to close)
- HPOS (High-Performance Order Storage) compatible
- No external CDN dependencies
Installation
Option 1: Upload via WordPress Admin
- Download or zip the
anura-lens-selectorfolder - Go to Plugins → Add New → Upload Plugin
- Select the
.zipfile and click Install Now - Click Activate Plugin
Option 2: Manual Upload
- Copy the
anura-lens-selector/folder towp-content/plugins/ - Go to Plugins in WordPress admin
- Find "Anura Lens Selector" and click Activate
On activation, the plugin will:
- Create two database tables (
wp_als_lens_types,wp_als_lens_packages) - Seed 5 default lens types and sample packages with placeholder SVG images
Configuration
Navigate to WooCommerce → Lens Selector in the admin sidebar.
Settings Tab
| Setting | Description |
|---|---|
| Help Phone Number | Displayed in the modal footer as "Not sure what to select? Call XXXXXXX" |
| Enable for | Choose "All products" or "Selected categories only" |
| Product Categories | Multi-select categories (only shown when "Selected categories only" is chosen) |
Lens Types Tab
Edit the 5 built-in lens types:
| Field | Description |
|---|---|
| Title | Display name shown in the modal |
| Description | Subtitle text below the title |
| Sort Order | Controls display order (ascending) |
| Active | Toggle visibility on the frontend |
Note: Lens type slugs cannot be changed as they are used internally.
Lens Packages Tab
Full CRUD for lens packages. Each package belongs to a lens type.
| Field | Description |
|---|---|
| Lens Type | Which lens type this package belongs to |
| Slug | Unique identifier (auto-generated from title) |
| Title | Package name displayed on the card |
| Description | One feature per line (rendered as bullet list) |
| Image | Upload via WordPress media library |
| Total Price | The "Frame + Lens" total price shown to the customer |
| Sort Order | Controls display order within the type |
| Active | Toggle visibility |
How It Works
Customer Flow
- Customer visits a WooCommerce product page (for an enabled category)
- A "Select Lens" button appears next to Add to Cart
- Clicking opens a full-screen modal with Step 1: Select Lens Type
- Frame Only → immediately adds the frame to cart and redirects to cart page
- Any other type → proceeds to Step 2
- Step 2: Choose Lens Package shows selectable cards with image, title, features, and price
- Selecting a package reveals the "Confirm & Add to Cart" button
- On confirm → product is added to cart with lens meta → redirects to cart
Pricing Logic
The plugin uses Total Price mode:
addon_price = max(0, package_total_price - product_price)
cart_item_price = product_price + addon_price
- If the package total is higher than the frame price → customer pays the package total
- If the package total is lower than the frame price → customer pays only the frame price (addon = 0)
Cart & Order Meta
The following meta is saved to cart line items and order items:
| Meta Key | Value |
|---|---|
| Lens Type | e.g., "Single Vision" |
| Lens Package | e.g., "BLU+ Thin" |
| Frame + Lens Total | e.g., "Rs 3,200" |
These are visible in:
- Cart page (below product name)
- Checkout page
- Order confirmation email
- Admin order details
Folder Structure
anura-lens-selector/
├── anura-lens-selector.php # Main plugin file
├── uninstall.php # Cleanup on plugin deletion
├── README.md # This file
├── includes/
│ ├── class-als-db.php # DB schema, CRUD, seed data
│ ├── class-als-helpers.php # Settings, pricing, utilities
│ ├── class-als-admin.php # Admin menu page, AJAX handlers
│ ├── class-als-frontend.php # Frontend button, modal, AJAX
│ └── class-als-cart.php # Cart pricing, line item meta, order meta
├── templates/
│ └── admin-page.php # Admin settings/types/packages UI
└── assets/
├── css/
│ ├── als-admin.css # Admin panel styles
│ └── als-frontend.css # Lenskart-style modal CSS
├── js/
│ ├── als-admin.js # Admin tab/form/AJAX logic
│ └── als-frontend.js # Modal workflow JS
└── images/
├── frame.svg # Lens type icon: Frame Only
├── non_prescription.svg # Lens type icon: Zero Power
├── progressive.svg # Lens type icon: Bifocal/Progressive
├── single_vision.svg # Lens type icon: Single Vision
├── with_power.svg # Lens type icon: With Power
├── single_vision/ # Package images for Single Vision
├── bifocal_progressive/ # Package images for Bifocal/Progressive
├── zero_power/ # Package images for Zero Power
└── with_power/ # Package images for With Power
Replacing Placeholder Images
The plugin ships with SVG placeholder images. To use your own:
Lens Type Icons (Step 1)
- Supported formats:
.apng,.webp,.png,.svg - Go to WooCommerce → Lens Selector → Lens Types
- Edit each type and update the icon URL (or upload via media library in the Packages tab)
Package Images (Step 2)
- Supported formats:
.webp,.png,.jpg,.svg - Go to WooCommerce → Lens Selector → Lens Packages
- Click Edit on any package → Select Image → upload from media library
- Recommended size: 200x200px
File-Based Replacement
You can also drop your images directly into the folder structure:
assets/images/
├── frame.apng # Replace frame.svg
├── single_vision.apng # Replace single_vision.svg
├── progressive.apng # Replace progressive.svg
├── non_prescription.apng # Replace non_prescription.svg
├── single_vision/
│ ├── Anti-Glare_Premium.webp # Replace .svg with .webp
│ └── ...
├── bifocal_progressive/
│ └── ...
├── zero_power/
│ └── ...
└── with_power/
└── ...
Then update the image URLs in the admin panel to point to the new files.
Database Tables
wp_als_lens_types
| Column | Type | Description |
|---|---|---|
| id | BIGINT | Primary key |
| slug | VARCHAR(100) | Unique identifier |
| title | VARCHAR(255) | Display name |
| description | VARCHAR(500) | Subtitle text |
| icon | VARCHAR(500) | Icon image URL |
| sort_order | INT | Display order |
| is_active | TINYINT(1) | Active toggle |
| requires_package | TINYINT(1) | Whether a package selection is required |
| created_at | DATETIME | Creation timestamp |
wp_als_lens_packages
| Column | Type | Description |
|---|---|---|
| id | BIGINT | Primary key |
| lens_type_id | BIGINT | Foreign key to lens types |
| slug | VARCHAR(100) | Unique identifier |
| title | VARCHAR(255) | Display name |
| description | TEXT | Newline-separated feature bullets |
| image_url | VARCHAR(500) | Package image URL |
| total_price | DECIMAL(10,2) | Frame + Lens total price |
| is_active | TINYINT(1) | Active toggle |
| sort_order | INT | Display order within type |
| created_at | DATETIME | Creation timestamp |
Uninstall Behavior
When the plugin is deleted (not just deactivated):
- By default, all custom tables and options are removed
- To keep data after deletion, add this to
wp-config.phpbefore deleting:
define( 'ALS_DELETE_DATA_ON_UNINSTALL', false );
Deactivating the plugin does not delete any data.
Security
- All AJAX requests are protected with WordPress nonces
- Admin endpoints require
manage_woocommercecapability - All user inputs are sanitized (
sanitize_text_field,sanitize_textarea_field,esc_url_raw) - All outputs are escaped (
esc_html,esc_attr,esc_url,wp_kses_post) - SQL queries use
$wpdb->prepare()for parameterized queries
Hooks & Filters
The plugin uses standard WooCommerce hooks:
| Hook | Purpose |
|---|---|
woocommerce_after_add_to_cart_button |
Renders the "Select Lens" button |
woocommerce_before_calculate_totals |
Adjusts cart item prices with lens addon |
woocommerce_get_item_data |
Displays lens meta in cart |
woocommerce_checkout_create_order_line_item |
Saves lens meta to order items |
woocommerce_cart_item_key |
Generates unique keys for different lens configs |
Troubleshooting
Plugin not showing on product pages
- Verify WooCommerce is active
- Check WooCommerce → Lens Selector → Settings — ensure "Enable for all" is selected or the product belongs to an enabled category
- Clear any page cache
Images not loading
- Verify image URLs in the admin panel point to valid files
- If using file-based replacement, ensure file extensions match the URLs in the database
"Frame Only" not redirecting to cart
- Ensure WooCommerce cart page is set up correctly under WooCommerce → Settings → Advanced
Changelog
1.0.0
- Initial release
- 5 lens types with full admin CRUD
- Lens package management with media library integration
- Full-screen mobile-first modal
- Cart and order meta integration
- Custom database tables
- Placeholder SVG images for all types and packages
Credits
Developed by Anura Dev
License
This plugin is licensed under the GPL v2 or later.