Так что я работал над интеграцией OpenCart в UserFrosting (http://www.userfrosting.com/). По сути, я загружаю все страницы панели администратора в панель управления UserFrosting, используя .load
ввести страницы в div
на моих собственных страницах HTML. Я почти закончил, но у меня есть последний кусок работы, который не остался в UF.
Я буду использовать страницу Каталог / Категории в качестве примера, чтобы показать, что я делаю:
Вот мой HTML-файл для категорий, он называется Ката-categories.html
<!DOCTYPE html>
<html lang="en">
{% include 'components/head.html' %}
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<body>
<div id="wrapper">
{% include 'components/nav-account.html' %}
<div id="page-wrapper">
{% include 'components/alerts.html' %}
<ol id="categories"></ol>
<script>
$( "#categories" ).load( "../solutions/admin/index.php?route=catalog/category" );
</script>
<br>
{% include 'components/footer.html' %}
</div>
</div></div>
</body>
</html>
Доступ к нему осуществляется через боковую панель UserFrosting со следующим кодом в sidebar.html:
{% if checkAccess('uri_manage_groups') %}
<li>
<a href="{{site.uri.public}}/cata-categories/"><i class="fa fa-tags fa-fw"></i>Categories</a>
</li>
{% endif %}
Страница отображается с помощью следующего кода в общественности / index.php для UserFrosting:
$app->get('/cata-categories/?', function () use ($app) {
$app->render('cata-categories.html', [
'page' => [
'author' => $app->site->author,
'title' => "Catagories",
'description' => "Catalogue Catagories.",
'alerts' => $app->alerts->getAndClearMessages()
]
]);
});
Чтобы удерживать все ссылки на страницах OpenCart, я помещал следующий скрипт внизу каждой основной .tpl
(так например category_list.tpl
):
<script>
$("#categories").on("click", "a", function (e) {
$("#categories").load($(this).attr("href"));
e.preventDefault();
});
</script>
Затем, чтобы сохранить вещи на той же странице при отправке форм, я изменил перенаправления в контроллерах (например, category.php) быть следующим:
$this->response->redirect('../../portal/cata-categories');
Все отлично работает, теперь единственная проблема — это ошибки при отправке формы или фильтрации результатов. Например, если кто-то пытается добавить новую категорию, но не вводит какую-либо информацию и нажимает кнопку Сохранить, он перенаправляет на /admin/index.php?route=catalog/category/add
но не внутри панели управления UserFrosting.
Я хочу, чтобы он оставался в моей панели инструментов, и мне нужно в правильном направлении указать, что нужно изменить в контроллере, чтобы заставить его это делать, я предполагаю, что это своего рода AJAX, чтобы заставить его не перезагружать страницу и просто показывать ошибки. То же самое и с кнопками фильтров, очевидно, что необходимо добавить фильтры к URL-адресу и, следовательно, не загружать их в панель управления — нужен способ фильтрации без обновления.
Любая помощь от людей с опытом модификации OpenCart будет принята с благодарностью, и если вам нужна дополнительная информация о том, что я делаю, не стесняйтесь спрашивать.
Способ, которым обрабатываются UserFrosting и OpenCart POST
запросы, кажется, в корне противоречат друг другу. Если вы посмотрите на код для catalog/category/add
маршрут (или, по крайней мере, я так думаю, но в коде, похоже, нет документации внутри кода, поэтому трудно быть уверенным), вы увидите это:
public function add() {
$this->language->load('catalog/category');
$this->document->setTitle($this->language->get('heading_title'));
$this->load->model('catalog/category');
if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validateForm()) {
$this->model_catalog_category->addCategory($this->request->post);
$this->session->data['success'] = $this->language->get('text_success');
$url = '';
if (isset($this->request->get['sort'])) {
$url .= '&sort=' . $this->request->get['sort'];
}
if (isset($this->request->get['order'])) {
$url .= '&order=' . $this->request->get['order'];
}
if (isset($this->request->get['page'])) {
$url .= '&page=' . $this->request->get['page'];
}
$this->response->redirect($this->url->link('catalog/category', 'token=' . $this->session->data['token'] . $url, 'SSL'));
}
$this->getForm();
}
Так что здесь происходит? Казалось бы, когда вы отправляете catalog/category/add
, он начинает генерировать документ (я предполагаю, что это то, что делают первые три строки), и затем он обрабатывает ваш запрос POST (я считаю, $this->model_catalog_category->addCategory($this->request->post);
фактически добавляет категорию).
Затем он перестраивает URL-адрес для перечисления всех категорий (я полагаю) и фактически перенаправляет ответ на эту страницу (все еще в коде на стороне сервера, который обрабатывает запрос POST, обратите внимание). Это все нормально, и на самом деле так работает большинство приложений старой школы (до AJAX), но UF работает немного иначе.
В UF запрос POST RESTful, это означает, что только Задача POST-запроса — изменить ресурс. Поэтому, когда вы нажимаете «отправить» в форме UserFrosting, запрос POST отправляется за кулисы, AJAX, где он обрабатывается (либо успешно обновляет ресурс и возвращает HTTP). 200
код успеха или сбой по какой-либо причине и возвращение кода ошибки). Если страница должна быть обновлена или перенаправлена после этого запроса, за это отвечает код на стороне клиента (Javascript).
Мой совет — полностью отказаться от контроллера OpenCart и повторно внедрить его в шаблон RESTful. Таким образом, вместо того, чтобы иметь OpenCart add()
Метод, вы должны иметь такие методы, как:
formCategoryAdd
: генерирует форму для добавления категории. Это может быть так же просто, как обертка вокруг OpenCart getForm
метод. Это в основном тот же тип, что и UserFrosting formUserCreate
делает.addCategory
: это фактически обрабатывает запрос POST для добавления категории. Опять же, вам может потребоваться сделать здесь больше ничего, чем вызвать OpenCart addCategory
а также validateForm
методы. Разница лишь в том, что вы не будете перенаправлять запрос после его завершения. Вместо этого вы добавите сообщение об успешном завершении в поток сообщений (если оно успешно добавит категорию) или добавите сообщение об ошибке, а затем вернете соответствующий код ошибки (если по какой-то причине произошел сбой). Смотрите UserFrosting’s createUser
метод для примера того, как это может работать. Затем на стороне клиента вам понадобится Javascript для обработки отправки формы. Вы можете в основном украсть его с любой из страниц UF. Предполагая, что ваша форма названа add-category
:
<script>
$(document).ready(function() {
// Process form
$("form[name='add-category']").formValidation({
framework: 'bootstrap',
// Feedback icons
icon: {
valid: 'fa fa-check',
invalid: 'fa fa-times',
validating: 'fa fa-refresh'
},
fields: { "" : ""}
}).on('success.form.fv', function(e) {
// Prevent double form submission
e.preventDefault();
// Get the form instance
var form = $(e.target);
// Serialize and post to the backend script in ajax mode
var serializedData = form.serialize();
var url = form.attr('action');
$.ajax({
type: "POST",
url: url,
data: serializedData
}).done(function(data, statusText, jqXHR) {
// Forward to account home page on success
window.location.replace(site.uri.public);
}).fail(function(jqXHR) {
if ((typeof site !== "undefined") && site['debug'] == true) {
document.body.innerHTML = jqXHR.responseText;
} else {
console.log("Error (" + jqXHR.status + "): " + jqXHR.responseText );
// Display errors on failure
$('#userfrosting-alerts').flashAlerts().done(function() {
// Re-enable submit button
form.data('formValidation').disableSubmitButtons(false);
});
}
});
});
});
</script>
Если вы хотите уменьшить количество повторений кода на стороне клиента, я поместил этот Javascript в отдельную функцию в dev
ветка: https://github.com/alexweissman/UserFrosting/blob/dev/public/js/userfrosting.js#L58-L113
Других решений пока нет …