Доброго дня!
Останнiм часом раз-пораз з'являються дискусії на тему застаріння CMS OpenCart. Порушимо і тут цю тему, але не розкритикувати, чи похвалити, а пропонуючи!
Як розгорнути проект з сучасним FrontEnd ми писали ранiше...
Зараз-же розглянемо посібник з прикладами, де спробуємо подружити Element Plus та OpenCart модуль для адмiн панелi
Створемо додаток "Управління категоріями OpenCart"
1) Клієнтська частина
../upload/admin/view/template/extension/module/multi_categories.twig
{{ header }} {{ column_left }}
<div id="content">
<div class="page-header">
<div class="container-fluid">
<div class="pull-right">
<a href="{{ cancel }}" data-toggle="tooltip" title="{{ button_cancel }}" class="btn btn-default"><i class="fa fa-reply"></i></a>
</div>
<h1>{{ heading_title }}</h1>
<ul class="breadcrumb">
{% for breadcrumb in breadcrumbs %}
<li><a href="{{ breadcrumb.href }}">{{ breadcrumb.text }}</a></li>
{% endfor %}
</ul>
</div>
</div>
<div class="container-fluid">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-pencil"></i> {{ breadcrumb_last }}</h3>
</div>
<div class="panel-body">
<div id="app"></div>
</div>
</div>
</div>
</div>
<script type="module" crossorigin src="{{ base }}view/javascript/product_list.js"></script>
<link rel="stylesheet" crossorigin href="{{ base }}view/javascript/product_list.css">
<style>
html {
height: auto
}
</style>
{{ footer }}
2) Клієнтська частина source for Vue Element-plus
../src/App.vue
<template>
<el-tree
style="max-width: 600px"
:data="products"
node-key="category_id"
>
<template #default="{ node, data }">
<span class="custom-tree-node">
<span>{{ data.sort_order }}) {{ node.label }}</span>
<span>
<a :href="openCategory(data)" target="_blank">_<i class="fa fa-pencil"></i></a>
</span>
</span>
</template>
</el-tree>
</template>
<script setup>
import { onMounted, ref } from 'vue';
let productPath = '';
const products = ref({});
const openCategory = (data) => {
return data.href.replaceAll('&', '&');
}
const appInit = (list = []) => {
products.value = list;
}
const getProducts = async () => {
if (!productPath) {
console.debug('The error for determining the path to get data!');
} else {
let response = await fetch(
productPath
);
appInit(
await response.json()
);
}
}
const appUrl = (route) => {
// Sanitize the call
route = route?.replace(/[^a-zA-Z0-9_\/]/i, '')
|| '';
if (!route)
return '';
// production or development (variable set: in root on .env.development file)
const inputUrl = new URL(
import.meta.env.PROD
? document?.location?.href
: import.meta.env.VITE_APP_HOME_PATH
);
inputUrl?.searchParams?.set('route', route);
return inputUrl?.href
|| '';
}
onMounted(() => {
productPath = appUrl(
'extension/module/multi_categories/get_categories'
);
getProducts();
})
</script>
<style>
.custom-tree-node {
align-items: center;
column-gap: 9px;
display: flex;
flex: 1;
justify-content: space-between
}
</style>
3) Контроллер
../upload/admin/controller/extension/module/multi_categories.php
<?php
// Read more: https://opencartforum.com/files/developer/678008-sha
class ControllerExtensionModuleMultiCategories extends Controller {
private $error = [];
private $edit_link = '';
public function index() {
$this->load->language('extension/module/multi_categories');
$this->document->setTitle(
$this->language->get('heading_title')
);
$this->getForm();
}
protected function getForm() {
$data = [];
$data['header'] = $this->load->controller('common/header');
$data['column_left'] = $this->load->controller('common/column_left');
$data['footer'] = $this->load->controller('common/footer');
$this->response->setOutput($this->load->view('extension/module/multi_categories', $data));
}
public function get_categories()
{
$this->response->addHeader('Content-Type: application/json');
if (!$this->validate())
$this->response->setOutput([]);
$this->load->model('extension/module/multi_categories');
$categories = $this->model_extension_module_multi_categories->get_categories();
$this->edit_link = $this->url->link(
'catalog/category/edit',
'user_token=' . $this->session->data['user_token'],
true
);
$this->response->setOutput(json_encode(
$this->tree(
$categories
)
));
}
private function tree($list, $parent_id = 0)
{
$children_list = [];
foreach ($list as $item) {
if ((int)$parent_id !== (int)$item['parent_id'])
continue;
$item['children'] = $this->tree(
$list,
$item['category_id']
);
$children_list[] = $this->itemBuild(
$item
);
}
return $children_list;
}
private function itemBuild($data = [])
{
$data['label'] = strip_tags(html_entity_decode(
$data['name'],
ENT_QUOTES, 'UTF-8'
));
$data['href'] = $this->edit_link . '&category_id=' . $data['category_id'];
return $data;
}
private function validate()
{
if (!$this->user->hasPermission('access', 'extension/module/multi_categories')) {
$this->error['warning'] = $this->language->get('error_permission');
}
return !$this->error;
}
}
4) Модель
../upload/admin/model/extension/module/multi_categories.php
<?php
// Read more: https://opencartforum.com/files/developer/678008-sha
class ModelExtensionModuleMultiCategories extends Model {
public function get_categories()
{
$query = $this->db->query("SELECT cd.name, c.category_id, c.parent_id, c.sort_order FROM " . DB_PREFIX . "category c LEFT JOIN " . DB_PREFIX . "category_description cd ON (c.category_id = cd.category_id) WHERE cd.language_id = '" . (int)$this->config->get('config_language_id') . "' ORDER BY c.parent_id, c.sort_order, cd.name;");
return isset($query->num_rows)
? $query->rows
: [];
}
}
5) Мова
../upload/admin/language/en-gb/extension/module/multi_categories.php
<?php
// Heading
$_['heading_title'] = 'Categories';
Сучасні бібліотеки та фреймворки пропонують широкий вибір готового функціоналу, наприклад, ви легко можете додати можливість перетягування елементів
<el-tree
...
draggable
...
>
//...
</el-tree>
та події
<el-tree
@node-drag-start="dragStart"
@node-drag-enter="dragEnter"
@node-drag-leave="dragLeave"
@node-drag-over="dragOver"
@node-drag-end="dragEnd"
@node-drop="drop"
>
// ...
</el-tree>
та з легкістю створити модуль зручного сортування дерева категорій перетягуванням OpenCart методом "Drag and Drop".
А з нашими прикладами ще й безкоштовно!!!
Дякуємо, за прочитання!
Тут ви зможете знайти наші модулі, та щє-й зі знижкою!)
якщо використаєте купон 678008-30
Ось що вийшло
Скачати готовий модуль!
пропозиції та оцiнка вітаються!)