Sergey
По плагинам буду делать
Evgenii_Web
как я понял это все на официальном сайте америкосов только есть)
Dmitry
Evgenii_Web
создают ли плагины нагрузку, не проще все переопределить просто?
Sergey
Dmitry
Тут хороший пример
https://github.com/joomla/joomla-cms/blob/3.10-dev/plugins/user/profile/profile.php
Dmitry
И поля добавляет, и данные
Evgenii_Web
Evgenii_Web
думаю с переопределениями намного проще
Evgenii_Web
)
Evgenii_Web
их надо учить
Vladislav
Тут для начала нужно событийную систему понять.
Joomla 4?
Evgenii_Web
Evgenii_Web
дело в том что в России нет ничего толкового по джумла, по ее устройству
Evgenii_Web
только если самому ковырять смотреть гуглить
Dmitry
https://wedal.ru/uroki-joomla/plaginy-joomla-podrobnyj-razbor-prostym-yazykom.html
Dmitry
Dmitry
https://jpath.ru/docs/output/printsipy-vyvoda-dannykh-v-joomla
Evgenii_Web
ок буду читать эксперементировать
Vladislav
Самый простой путь в данном случае, но он не совсем правильный:
1. Через переопределения добавить поле (не переопределять global.php (он не только в com_content используется, а создать новый).
2. Создать плагин типа behaviour (за пример можно посмотреть taggable - самый простой варик, он перехватывает отправленную форму и позволяет обработать). В нем брать данные из поля и записывать в свою таблицу.
Для единичного сайта - может сгодиться, но путь не правильный для joomla. По хорошему тут пакет может потребоваться, на сколько я понимаю, чтобы при установке/обновлении создавать и удалять таблицы и несколько плагинов. Один чтобы в админке перехватывать и писать в БД, другой для пользовательской части чтобы данные выводить.
Но задача неполноценно описана - правильный путь сложно подсказать, потому как не особо понимаю, что потом с этим полем планируется делать
Sergey
Кстати, Дим. На мой взгляд не очень удобно на главной разделы созданы. Я опытный, знаю что хочу найти (допустим ту же статью Общие принципе действия джумла), но сам не соображаю как её найти ))
Dmitry
Dmitry
@progreccor тоже писал, что неудобно
Dmitry
Дайте свои варианты :)
Dmitry
Dmitry
Невозможно все варианты перекрыть, имхо 😏
Vladislav
Я бы сказал как на официальной доке было бы удобнее:
Корневые разделы и сразу подразделы отображать на одной странице, где они визуально разделены на блоки.
Dmitry
Dmitry
Можно даже нарисовать
Vladislav
Если найдется время и не забуду
Dmitry
Все так говорят 😁👍
Dmitry
И в итоге имеем, то что есть 😃
Dmitry
Без обид
Vladislav
Да какие тут обиды
Dmitry
Vladimir
Хотя с точки зрения структуры - ок
Vladislav
Сделать бы открытую платформу, где каждый мог бы публиковать материалы по темам. Да не уверен, что найдется достаточно заинтересованных в публикации и обслуживании.
Dmitry
Ну вот каждый подумает и что-то придумаем
Dmitry
Dmitry
Могу любого автором сделать
Vladislav
Тригеры есть почти на все. Можно пример, какого тригера не нашлось?
Sergey
Алексей
<?php
/
* Joomla! Content Management System
*
* @copyright (C) 2007 Open Source Matters, Inc. <https://www.joomla.org>
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\CMS\Cache\Controller;
\defined('JPATH_PLATFORM') or die;
use Joomla\CMS\Cache\Cache;
use Joomla\CMS\Cache\CacheController;
use Joomla\CMS\Factory;
/
* Joomla! Cache page type object
*
* @since 1.7.0
*/
class PageController extends CacheController
{
/
* ID property for the cache page object.
*
* @var integer
* @since 1.7.0
*/
protected $_id;
/
* Cache group
*
* @var string
* @since 1.7.0
*/
protected $_group;
/
* Cache lock test
*
* @var \stdClass
* @since 1.7.0
*/
protected $_locktest = null;
/
* Get the cached page data
*
* @param boolean $id The cache data ID
* @param string $group The cache data group
*
* @return mixed Boolean false on no result, cached object otherwise
*
* @since 1.7.0
*/
protected function lastModified($id, $group)
{
$app = Factory::getApplication();
$filename = 'administrator/cache/' . $group. '/' .md5($app->get('secret')) . '-cache-' . $group . '-' . md5(md5(JPATH_CONFIGURATION) . '-' . $id . '-' . $app->getLanguage()->get('tag')). '.php';
if (file_exists($filename)) {
date_default_timezone_set('Europe/Moscow');
return date("F d Y H:i:s", filemtime($filename));
} else {
return 'file_not_exists';
}
}
public function get($id = false, $group = 'page')
{
// If an id is not given, generate it from the request
if (!$id)
{
$id = $this->_makeId();
}
$lastModified = md5($this->lastModified($id, $group));
$lastModifiedGzip = $lastModified.'-gzip';
//var_dump($lastModifiedGzip);
// If the etag matches the page id ... set a no change header and exit : utilize browser cache
if (!headers_sent() && isset($_SERVER['HTTP_IF_NONE_MATCH']))
{
$etag = stripslashes($_SERVER['HTTP_IF_NONE_MATCH']);
$etag = str_replace('"', '', $etag);
//var_dump($etag);
if ($etag == $lastModifiedGzip)
{
/*$browserCache = $this->options['browsercache'] ?? false;
if ($browserCache)
{*/
$this->_noChange();
/* }*/
}
}
// We got a cache hit... set the etag header and echo the page data
$data = $this->cache->get($id, $group);
$this->_locktest = (object) array('locked' => null, 'locklooped' => null);
if ($data === false)
{
$this->_locktest = $this->cache->lock($id, $group);
// If locklooped is true try to get the cached data again; it could exist now.
if ($this->_locktest->locked === true && $this->_locktest->locklooped === true)
{
$data = $this->cache->get($id, $group);
}
}
if ($data !== false)
{
/*if ($this->_locktest->locked === true)
{*/
$this->cache->unlock($id, $group);
/*}*/
$data = unserialize(trim($data));
$data = Cache::getWorkarounds($data);
$this->_setEtag($lastModified);
return $data;
}
// Set ID and group placeholders
$this->_id = $id;
$this->_group = $group;
return false;
}
Алексей
/
* Stop the cache buffer and store the cached data
*
* @param mixed $data The data to store
* @param string $id The cache data ID
* @param string $group The cache data group
* @param boolean $wrkarounds True to use workarounds
*
* @return boolean
*
* @since 1.7.0
*/
public function store($data, $id, $group = null, $wrkarounds = true)
{
if ($this->_locktest->locked === false && $this->_locktest->locklooped === true)
{
// We can not store data because another process is in the middle of saving
return false;
}
// Get page data from the application object
if (!$data)
{
$data = Factory::getApplication()->getBody();
// Only attempt to store if page data exists.
if (!$data)
{
return false;
}
}
// Get id and group and reset the placeholders
if (!$id)
{
$id = $this->_id;
}
if (!$group)
{
$group = $this->_group;
}
if ($wrkarounds)
{
$data = Cache::setWorkarounds(
$data,
array(
'nopathway' => 1,
'nohead' => 1,
'nomodules' => 1,
'headers' => true,
)
);
}
$result = $this->cache->store(serialize($data), $id, $group);
if ($this->_locktest->locked === true)
{
$this->cache->unlock($id, $group);
}
return $result;
}
/
* Generate a page cache id
*
* @return string MD5 Hash
*
* @since 1.7.0
* @todo Discuss whether this should be coupled to a data hash or a request hash ... perhaps hashed with a serialized request
*/
protected function _makeId()
{
return Cache::makeId();
}
/
* There is no change in page data so send an unmodified header and die gracefully
*
* @return void
*
* @since 1.7.0
*/
protected function _noChange()
{
$app = Factory::getApplication();
// Send not modified header and exit gracefully
$app->setHeader('Status', 304, true);
$app->sendHeaders();
$app->close();
}
/
* Set the ETag header in the response
*
* @param string $etag The entity tag (etag) to set
*
* @return void
*
* @since 1.7.0
*/
protected function _setEtag($etag)
{
Factory::getApplication()->setHeader('ETag', '"' . $etag . '"', true);
}
}
Алексей
Ну т.е. подкинуть в класс один метод, а в другой метод внести изменения в файле PageController.php
Sergey
@Septdir @tsymbalmitia
Алексей
Смысл всех телодвижений в теге ETag для кэшированных страниц, чтобы 304 нормально отрабатывал, код работает четко, но тригера я не нашел под то, чтобы хак в плагин превратить
Sergey
Алексей
Сергей
Vladimir
Vladimir
Igor
Алексей
Ссылку на гит
https://github.com/joomla/joomla-cms/issues/39707
Алексей
Алексей
Субъективно, у джумлы хитровымудренная философия и архитектура, на хромом коне не подъедешь...
Дмитрий
Алексей
Дмитрий
Дмитрий
мне доки не нужны никакие
Дмитрий
у меня есть сорцы дужмлы и мне все ясно что там
Дмитрий
код и есть документация
Vladimir
Алексей
Dmitry
https://www.dionysopoulos.me/book.html
Vladimir
Vladimir
Что касается использования значения, которое меняется при изменении содержимого страницы, то для этого необходимо изменить способ создания ключа кэша, и он должен быть доступен в системном событии onAfterInitialise (то есть еще до того, как запрос был направлен). Мы не можем основывать ключ кэша на хэше отрисованного содержимого, потому что нам придется отрисовать содержимое, чтобы достать элемент из кэша, а в этот момент кэш страницы будет уже слишком поздно, чтобы быть полезным.
Алексей