OpenCart创建独立特色商品页面:SQL查询与模块复用问题
I get it, you’re trying to create a dedicated page for all featured products but hit a wall because there’s no featured column in the product table. That’s because OpenCart manages featured products through featured module settings, not a direct flag on individual products. Let’s walk through how to build this page properly using the module’s logic as a starting point.
Step 1: Create the Controller
First, make a new controller file at catalog/controller/product/featured_all.php with this code:
<?php class ControllerProductFeaturedAll extends Controller { public function index() { // Reuse the featured module's language file for consistency $this->load->language('extension/module/featured'); // Set page title $this->document->setTitle($this->language->get('heading_title')); // Build breadcrumbs $data['breadcrumbs'] = array(); $data['breadcrumbs'][] = array( 'text' => $this->language->get('text_home'), 'href' => $this->url->link('common/home') ); $data['breadcrumbs'][] = array( 'text' => $this->language->get('heading_title'), 'href' => $this->url->link('product/featured_all') ); // Load necessary models $this->load->model('catalog/product'); $this->load->model('tool/image'); $this->load->model('setting/setting'); // Fetch all product IDs from active featured modules $featured_product_ids = array(); $modules = $this->model_setting_setting->getSettings('module_featured'); foreach ($modules as $module) { if (!empty($module['product'])) { foreach ($module['product'] as $product_id) { $featured_product_ids[] = (int)$product_id; } } } // Remove duplicate product entries $featured_product_ids = array_unique($featured_product_ids); $data['products'] = array(); // Populate product data for the view if ($featured_product_ids) { foreach ($featured_product_ids as $product_id) { $product_info = $this->model_catalog_product->getProduct($product_id); if ($product_info) { // Handle product image $image = $product_info['image'] ? $this->model_tool_image->resize($product_info['image'], $this->config->get('theme_' . $this->config->get('config_theme') . '_image_product_width'), $this->config->get('theme_' . $this->config->get('config_theme') . '_image_product_height')) : $this->model_tool_image->resize('placeholder.png', $this->config->get('theme_' . $this->config->get('config_theme') . '_image_product_width'), $this->config->get('theme_' . $this->config->get('config_theme') . '_image_product_height')); // Handle pricing (account for customer login status) $price = $this->customer->isLogged() || !$this->config->get('config_customer_price') ? $this->currency->format($this->tax->calculate($product_info['price'], $product_info['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']) : false; $special = (float)$product_info['special'] ? $this->currency->format($this->tax->calculate($product_info['special'], $product_info['tax_class_id'], $this->config->get('config_tax')), $this->session->data['currency']) : false; // Handle ratings $rating = $this->config->get('config_review_status') ? (int)$product_info['rating'] : false; $data['products'][] = array( 'product_id' => $product_info['product_id'], 'thumb' => $image, 'name' => $product_info['name'], 'description' => utf8_substr(strip_tags(html_entity_decode($product_info['description'], ENT_QUOTES, 'UTF-8')), 0, $this->config->get('theme_' . $this->config->get('config_theme') . '_product_description_length')) . '...', 'price' => $price, 'special' => $special, 'rating' => $rating, 'href' => $this->url->link('product/product', 'product_id=' . $product_info['product_id']) ); } } } // Load common page components $data['column_left'] = $this->load->controller('common/column_left'); $data['column_right'] = $this->load->controller('common/column_right'); $data['content_top'] = $this->load->controller('common/content_top'); $data['content_bottom'] = $this->load->controller('common/content_bottom'); $data['footer'] = $this->load->controller('common/footer'); $data['header'] = $this->load->controller('common/header'); // Render the page $this->response->setOutput($this->load->view('product/featured_all', $data)); } } ?>
Step 2: Create the View File
Next, make a view file at catalog/view/theme/your_theme/template/product/featured_all.twig (replace your_theme with your actual theme name, e.g., default):
{{ header }} <div id="product-category" class="container"> {{ column_left }} <div id="content" class="{{ content_column_class }}"> {{ content_top }} <h1>{{ heading_title }}</h1> {% if products %} <div class="row products"> {% for product in products %} <div class="col-lg-3 col-md-4 col-sm-6 col-xs-12"> <div class="product-thumb transition"> <div class="image"><a href="{{ product.href }}"><img src="{{ product.thumb }}" alt="{{ product.name }}" title="{{ product.name }}" class="img-responsive" /></a></div> <div class="caption"> <h4><a href="{{ product.href }}">{{ product.name }}</a></h4> <p>{{ product.description }}</p> {% if product.price %} <p class="price"> {% if not product.special %} {{ product.price }} {% else %} <span class="price-old">{{ product.price }}</span> <span class="price-new">{{ product.special }}</span> {% endif %} </p> {% endif %} {% if product.rating %} <div class="rating"> {% for i in 1..5 %} {% if product.rating >= i %} <span class="fa fa-stack"><i class="fa fa-star-o fa-stack-2x"></i><i class="fa fa-star fa-stack-2x"></i></span> {% else %} <span class="fa fa-stack"><i class="fa fa-star-o fa-stack-2x"></i></span> {% endif %} {% endfor %} </div> {% endif %} <div class="button-group"> <button type="button" onclick="cart.add('{{ product.product_id }}');"><i class="fa fa-shopping-cart"></i> <span class="hidden-xs hidden-sm hidden-md">{{ button_cart }}</span></button> <button type="button" data-toggle="tooltip" title="{{ button_wishlist }}" onclick="wishlist.add('{{ product.product_id }}');"><i class="fa fa-heart"></i></button> <button type="button" data-toggle="tooltip" title="{{ button_compare }}" onclick="compare.add('{{ product.product_id }}');"><i class="fa fa-exchange"></i></button> </div> </div> </div> </div> {% endfor %} </div> {% else %} <p>{{ text_no_products }}</p> {% endif %} {{ content_bottom }} </div> {{ column_right }} </div> {{ footer }}
Step 3: Add a Clean SEO Route (Optional)
To make your URL user-friendly (e.g., yourstore.com/featured-products instead of index.php?route=product/featured_all), add a route in Admin > System > SEO URL:
- Query:
product/featured_all - Keyword:
featured-products(use any keyword you prefer)
Key Notes:
- This code pulls all products assigned to any active featured module in your store. If you want a dedicated set of products for this page, you could add a custom setting instead, but this approach reuses your existing featured assignments.
- We reused the featured module’s language file so you don’t have to duplicate translations for buttons and labels.
- The view matches the default product listing style to keep consistency with your theme. Adjust the Twig code if you need a different layout.
- Don’t forget to clear your OpenCart cache (Admin > System > Maintenance > Cache) after adding these files to see the changes.
If products aren’t showing up, double-check that your featured modules have products assigned and are enabled. Also, verify that file paths match your theme’s structure.
内容的提问来源于stack exchange,提问作者LiveEn




