ideasdigger

ideasdigger

hoho)
+328
Репутация
1002
Рейтинг
#1 Голосование в модальном окне 3 июня 2026 в 12:34

@Zau4man да согласен, для поддержки и обновление предложенный вариант удобнее, намного удобнее, но с учётом ситуации если необходимо подключить в нескольких типах списка_list.tpl, я бы вынес логику в templates/modern/assets/ui

у openAjax есть правильная точка callback когда html уже вставлен, обычный ajax-modal, callback не использует и не позволяет передать, но можно обойтись и без setInterval, а через свой класс, да и раз класс всё равно прописывать)

в templates/modern/content/default_list_featured.tpl.php вместо ajax-modal указать класс ajax-modal-content:

  1. <a class="ajax-modal-content" href="<?php echo href_to($ctype['name'], $item['slug'].'.html'); ?>">
  2. <?php html($item[$field['name']]); ?>
  3. </a>

а в конце файла ниже пагинации добавить:

  1. <?php $this->renderAsset('ui/ajax-modal-content'); ?>

сам asset создать в templates/modern/assets/ui/ajax-modal-content.tpl.php

  1. <?php
  2. $this->addTplJSName(['rating', 'jquery-scroll', 'comments']);
  3. ob_start(); ?>
  4. <script>
  5. $(function() {
  6. if (typeof icms === 'undefined' || !icms.modal) {
  7. return;
  8. }
  9.  
  10. function initModalContent() {
  11. if (icms.rating) {
  12. $('#icms_modal .modal-body .rating_widget').each(function() {
  13. icms.rating.bindWidget($(this));
  14. });
  15. }
  16.  
  17. if (icms.comments && $('#icms_modal .modal-body #comments_widget').length) {
  18. icms.comments.onDocumentReady();
  19. }
  20. }
  21.  
  22. $('a.ajax-modal-content').off('click').on('click', function() {
  23. var $link = $(this);
  24. var title = $link.attr('title') || $link.data('original-title');
  25.  
  26. icms.modal.openAjax($link.attr('href'), $link.data('params'), initModalContent, title, $link.data('style'));
  27.  
  28. return false;
  29. });
  30. });
  31. </script>
  32. <?php $this->addBottom(ob_get_clean()); ?>

если комментария не используются, вариант без них:

  1. <?php
  2. $this->addTplJSName('rating');
  3. ob_start(); ?>
  4. <script>
  5. $(function() {
  6. if (typeof icms === 'undefined' || !icms.modal) {
  7. return;
  8. }
  9.  
  10. function initModalContent() {
  11. if (icms.rating) {
  12. $('#icms_modal .modal-body .rating_widget').each(function() {
  13. icms.rating.bindWidget($(this));
  14. });
  15. }
  16.  
  17. }
  18.  
  19. $('a.ajax-modal-content').off('click').on('click', function() {
  20. var $link = $(this);
  21. var title = $link.attr('title') || $link.data('original-title');
  22.  
  23. icms.modal.openAjax($link.attr('href'), $link.data('params'), initModalContent, title, $link.data('style'));
  24.  
  25. return false;
  26. });
  27. });
  28. </script>
  29. <?php $this->addBottom(ob_get_clean()); ?>
  30.  


такой вариант удобнее для внедрения, особенно в случае нескольких списков, не тянет rating.js везде даже там где он не нужен, весь код остаётся на уровне asset что удобнее для поддержки, без лишних правок к modal.js, rating.js, не цепляет глобальный таймер к всем модальным окнам, а рейтинг и комментарии инициализируются только там, где они реально ожидаются

комментария добавляются, редактируются, но явно что то может ещё не хватать, как минимум скроллит тело страницы при добавлении нового

#2 Голосование в модальном окне 3 июня 2026 в 09:00

templates/modern/main.tpl.php, заменить

  1. $this->addMainTplJSName(['core', 'modal']);

на

  1. $this->addMainTplJSName(['core', 'modal', 'rating']);

templates/modern/js/modal.js, после строк в методе showContent

  1. if(title){
  2. $(modal_el).find('.modal-title').show().html(title);
  3. } else {
  4. $(modal_el).find('.modal-title').hide();
  5. }
  6. $(modal_el).addClass('in');

добавить

  1. icms.events.run('icms_modal_content');

templates/modern/js/rating.js, заменить

  1. this.onDocumentReady = function(){
  2. $('.rating_widget').each(function(){
  3. self.bindWidget($(this));
  4. });
  5. };
  6.  
  7. this.bindWidget = function(widget){

на

  1. this.onDocumentReady = function(){
  2. $('.rating_widget').each(function(){
  3. self.bindWidget($(this));
  4. });
  5. icms.events.on('icms_modal_content', function(){
  6. self.onModalContent();
  7. });
  8. };
  9.  
  10. this.onModalContent = function(){
  11. if (!self.options.url) {
  12. let $first = $('#icms_modal .modal-body .rating_widget').first();
  13. if ($first.data('vote-url')) {
  14. self.setOptions({url: $first.data('vote-url')});
  15. }
  16. }
  17. $('#icms_modal .modal-body .rating_widget').each(function(){
  18. self.bindWidget($(this));
  19. });
  20. };
  21.  
  22. this.bindWidget = function(widget){

templates/modern/js/rating.js, заменить

  1. $('a.vote-up', widget).on('click', function(){
  2. return self.vote('up', controller, subject, id);
  3. });
  4.  
  5. $('a.vote-down', widget).on('click', function(){
  6. return self.vote('down', controller, subject, id);
  7. });
  8.  
  9. $('.vote-clear', widget).on('click', function(){
  10. return self.vote('clear', controller, subject, id);
  11. });

на

  1. $('a.vote-up', widget).off('click').on('click', function(){
  2. return self.vote('up', controller, subject, id, widget);
  3. });
  4.  
  5. $('a.vote-down', widget).off('click').on('click', function(){
  6. return self.vote('down', controller, subject, id, widget);
  7. });
  8.  
  9. $('.vote-clear', widget).off('click').on('click', function(){
  10. return self.vote('clear', controller, subject, id, widget);
  11. });

templates/modern/js/rating.js, заменить

  1. this.vote = function(direction, controller, subject, id){
  2.  
  3. let widget_id = 'rating-' + subject + '-' + id;
  4. let widget = $('#'+widget_id);

на

  1. this.vote = function(direction, controller, subject, id, widget){
  2.  
  3. if (!widget || !widget.length) {
  4. widget = $('#icms_modal .modal-body .rating_widget[data-target-subject="' + subject + '"][data-target-id="' + id + '"]');
  5. if (!widget.length) {
  6. widget = $('#rating-' + subject + '-' + id).last();
  7. }
  8. }

templates/modern/controllers/rating/widget.tpl.php, заменить

  1. data-target-id="<?php echo $target_id; ?>"
  2. data-info-url="<?php echo $this->href_to('info'); ?>"
  3. <?php } ?>

на

  1. data-target-id="<?php echo $target_id; ?>"
  2. data-info-url="<?php echo $this->href_to('info'); ?>"
  3. data-vote-url="<?php echo $this->href_to('vote'); ?>"
  4. <?php } ?>

templates/modern/controllers/rating/widget.tpl.php, заменить

  1. icms.rating.setOptions({
  2. url: '<?php echo $this->href_to('vote'); ?>'
  3. });

на

  1. if (typeof icms.rating !== 'undefined') {
  2. icms.rating.setOptions({
  3. url: '<?php echo $this->href_to('vote'); ?>'
  4. });
  5. }
#3 Можно ли добавить новые поля к фотографиям? 10 февраля 2026 в 09:16

Если можно скинуть — скиньте, переживаю что при редактировании боюсь где-то сделать ошибку.

RUSLEGIONER

sql из поста выше не забудьте, в архиве как изменённые файлы с учётом структуры (бекап старых на всякий случай) так и патч

Прикрепленный файл
photos-address-fields.zip 23 Кб
#4 Можно ли добавить новые поля к фотографиям? 29 января 2026 в 22:15

Подскажите пожалуйста, как здесь можно добавить поле — например, для строковое для описания адреса или поле для вставки ссылки

RUSLEGIONER

всё это актуально для instantcns 2.18, в других версиях может отличаться но смысл, будет понятен, обновление затрёт
sql в бд

  1. ALTER TABLE `cms_photos`
  2. ADD COLUMN `address` VARCHAR(500) DEFAULT NULL COMMENT 'Адрес/местоположение съемки' AFTER `camera`,
  3. ADD COLUMN `address_url` VARCHAR(1000) DEFAULT NULL COMMENT 'URL ссылка на карту/адрес' AFTER `address`,
  4. ADD KEY `address` (`address`(255));


в файле system/controllers/photos/actions/edit.php после

  1. $photo_types = $this->request->get('type', []);

вставить

  1. $photo_addresses = $this->request->get('address', []);
  2. $photo_address_urls = $this->request->get('address_url', []);

далее, в этом же файле

  1. $_photo = [
  2. 'title' => strip_tags(...),
  3. 'content_source' => (...),
  4. 'content' => (...),
  5. 'is_private' => (isset($photo_is_privates[$photo_id]) ? ... : 0),
  6. 'type' => (isset($photo_types[$photo_id]) ? (int) $photo_types[$photo_id] : null),
  7. тут
  8. ];
  9.  

вместо «тут» добавить

  1. 'address' => (isset($photo_addresses[$photo_id]) ? trim($photo_addresses[$photo_id]) : null),
  2. 'address_url' => (isset($photo_address_urls[$photo_id]) ? trim($photo_address_urls[$photo_id]) : null)


в файле system/controllers/photos/actions/upload.php
после

  1. if (!empty($this->options['types'])) {
  2. $photo_types = $this->request->get('type', []);
  3. }

вставить

  1. $photo_addresses = $this->request->get('address', []);
  2. $photo_address_urls = $this->request->get('address_url', []);


и ниже 

  1. $_photo = [
  2. 'date_pub' => null,
  3. 'album_id' => $this->album['id'],
  4. 'title' => strip_tags($photo_titles[$photo_id] ? $photo_titles[$photo_id] : sprintf(LANG_PHOTOS_PHOTO_UNTITLED, $photo_id)),
  5. 'content_source' => ($photo_contents[$photo_id] ? cmsEventsManager::hook('html_filter', [
  6. 'text' => $photo_contents[$photo_id],
  7. 'is_process_callback' => false,
  8. 'typograph_id' => $this->options['typograph_id'],
  9. 'is_auto_br' => false
  10. ]) : null),
  11. 'content' => ($photo_contents[$photo_id] ? cmsEventsManager::hook('html_filter', [
  12. 'text' => $photo_contents[$photo_id],
  13. 'typograph_id' => $this->options['typograph_id'],
  14. 'is_auto_br' => !$editor_params['editor'] ? true : null
  15. ]) : null),
  16. 'is_private' => (isset($photo_is_privates[$photo_id]) ? (int) $photo_is_privates[$photo_id] : 0),
  17. 'type' => (isset($photo_types[$photo_id]) ? (int) $photo_types[$photo_id] : null),
  18. тут
  19. 'ordering' => $last_order
  20. ];


вместо «тут» вставить

  1. 'address' => (isset($photo_addresses[$photo_id]) ? trim($photo_addresses[$photo_id]) : null),
  2. 'address_url' => (isset($photo_address_urls[$photo_id]) ? trim($photo_address_urls[$photo_id]) : null),

после строк

  1. $result['id'] = $this->model->addPhoto([
  2. 'album_id' => $this->album['id'],
  3. 'user_id' => $this->cms_user->id,
  4. 'image' => $result['paths'],
  5. 'date_photo' => $date_photo,
  6. 'camera' => $camera,

добавить:

  1. 'address' => null,
  2. 'address_url' => null,


в файле templates/default/controllers/photos/widget.tpl.php
после блока

  1. <?php if($types){ ?>
  2. <div class="photo_type">
  3. <?php echo html_select('type['.$photo['id'].']', $types, $photo['type']); ?>
  4. </div>
  5. <?php } ?>

вставить

  1. <div class="photo_address">
  2. <?php echo html_input('text', 'address['.$photo['id'].']', (isset($photo['address']) ? $photo['address'] : ''), array('placeholder' => LANG_PHOTOS_ADDRESS, 'maxlength' => 500)); ?>
  3. </div>
  4. <div class="photo_address_url">
  5. <?php echo html_input('text', 'address_url['.$photo['id'].']', (isset($photo['address_url']) ? $photo['address_url'] : ''), array('placeholder' => LANG_PHOTOS_VIEW_ON_MAP, 'maxlength' => 1000)); ?>
  6. </div>


и для modern в templates/modern/controllers/photos/widget.tpl.php

  1. <?php if($types){ ?>
  2. <div class="photo_type form-group">
  3. <?php echo html_select('type['.$photo['id'].']', $types, $photo['type']); ?>
  4. </div>
  5. <?php } ?>


вставить

  1. <div class="photo_address form-group">
  2. <?php echo html_input('text', 'address['.$photo['id'].']', (isset($photo['address']) ? $photo['address'] : ''), array('placeholder' => LANG_PHOTOS_ADDRESS, 'maxlength' => 500, 'class' => 'form-control')); ?>
  3. </div>
  4. <div class="photo_address_url form-group">
  5. <?php echo html_input('text', 'address_url['.$photo['id'].']', (isset($photo['address_url']) ? $photo['address_url'] : ''), array('placeholder' => LANG_PHOTOS_VIEW_ON_MAP, 'maxlength' => 1000, 'class' => 'form-control')); ?>
  6. </div>

после, в блоке <div class=«preview_template block row» style=«display:none»>

  1. <div class="form-group photo_content">
  2. <textarea id="" class="textarea form-control" name=""></textarea>
  3. </div>
  4. <div class="form-group photo_privacy">
  5. <?php echo html_select('', array(LANG_PRIVACY_PUBLIC, LANG_PRIVACY_PRIVATE, LANG_PHOTOS_ACCESS_BY_LINK), (isset($album['is_private']) ? $album['is_private'] : 0)); ?>
  6. </div>
  7. <?php if($types){ ?>
  8. <div class="form-group photo_type">
  9. <?php echo html_select('', $types); ?>
  10. </div>
  11. <?php } ?>

добавить

  1. <div class="form-group photo_address">
  2. <?php echo html_input('text', '', '', array('placeholder' => LANG_PHOTOS_ADDRESS, 'maxlength' => 500, 'class' => 'form-control')); ?>
  3. </div>
  4. <div class="form-group photo_address_url">
  5. <?php echo html_input('text', '', '', array('placeholder' => LANG_PHOTOS_VIEW_ON_MAP, 'maxlength' => 1000, 'class' => 'form-control')); ?>
  6. </div>


в файл templates/default/controllers/photos/view.tpl.php после

  1. <dl class="photo_details">

вставить

  1. <?php if (!empty($photo['address']) || !empty($photo['address_url'])) { ?>
  2. <div class="photo-address">
  3. <h3><?php echo LANG_PHOTOS_ADDRESS; ?></h3>
  4. <?php if (!empty($photo['address'])) { ?>
  5. <p><?php echo html($photo['address']); ?></p>
  6. <?php } ?>
  7. <?php if (!empty($photo['address_url'])) { ?>
  8. <p><a href="<?php echo html($photo['address_url']); ?>" target="_blank" rel="noopener"><?php echo LANG_PHOTOS_VIEW_ON_MAP; ?></a></p>
  9. <?php } ?>
  10. </div>
  11. <?php } ?>


в файл templates/modern/controllers/photos/view.tpl.php, после

  1. <dl class="photo_details bg-light border-top px-3 pb-3">

вставить

  1. <?php if (!empty($photo['address']) || !empty($photo['address_url'])) { ?>
  2. <div class="photo-address bg-light px-3 pt-3 pb-2">
  3. <h5><?php echo LANG_PHOTOS_ADDRESS; ?></h5>
  4. <?php if (!empty($photo['address'])) { ?>
  5. <p class="mb-1"><?php echo html($photo['address']); ?></p>
  6. <?php } ?>
  7. <?php if (!empty($photo['address_url'])) { ?>
  8. <p class="mb-0"><a href="<?php echo html($photo['address_url']); ?>" target="_blank" rel="noopener"><?php echo LANG_PHOTOS_VIEW_ON_MAP; ?></a></p>
  9. <?php } ?>
  10. </div>
  11. <?php } ?>


в файл system/languages/ru/controllers/photos/photos.php

  1. define('LANG_PHOTOS_SORT_ORDERTO', 'Направление сортировки');

вставить

  1. define('LANG_PHOTOS_ADDRESS', 'Местоположение');
  2. define('LANG_PHOTOS_VIEW_ON_MAP', 'Посмотреть на карте');


в файлы templates/default/js/photos.js и templates/modern/js/photos.js

после 

  1. $('.photo_type select', preview_block).attr('name', 'type['+result.id+']');

вставить

  1. $('.photo_address input', preview_block).attr('name', 'address['+result.id+']');
  2. $('.photo_address_url input', preview_block).attr('name', 'address_url['+result.id+']');


могу скинуть патчем если гит на проекте есть)

#5 Категории и Списки 20 января 2024 в 01:55

Уважаемые подскажите.

Как сделать что бы Категории выводились во всех вкладках и разделах?

Вот дапустим главная категория Новости:

Изображение

Здесь есть категории, а переходя в разделы их НЕТ:

Изображение

Как сделать так что бы категории были во всех разделах??

Это относится и к Статьям и Блогам… Подскажите такое вообще возможно? И по подробнее если есть такая возможность..

R161Net

github.com/instantsoft/icms2/blob/a452062aa61ecaeea95b1263de30171144692519/system/controllers/content/actions/category_view.php#L279C13-L280C71

не увидел тут хука что бы перехватить это, варианта не много, делать виджет, который будет выводить (что более гибко), внести правку в тпл, (ну такое), внести правку в код (тоже такое, придётся помнить иначе пропадёт при обновлениях, ниже вариант с кодом)), после этого кода в файле по ссылке выше:

  1. $subcats = $this->model->filterIsNull('is_hidden')->
  2. getSubCategories($ctype['name'], $current_cat_id);

добавить

  1. If(!$subcats) {
  2. $subcats = !$subcats && $category['parent_id'] ? $this->model->filterIsNull('is_hidden')->getSubCategories($ctype['name'], $category['parent_id']) : false;
  3. }


должно работать, не тестил

#6 Не ходят письма на Gmail 20 января 2024 в 01:23

возможно dkim не был прописан? если да пропишите в dns обязательно
а так с яндекс почтой ходит в gmail всё без проблем пример \system\config\config.php

  1. 'mail_transport' => 'smtp',
  2. 'mail_from' => 'полный@емайл.адрес',
  3. 'mail_from_name' => 'Имя отправителя',
  4. 'mail_smtp_server' => 'smtp.yandex.ru',
  5. 'mail_smtp_port' => '465', //ssl
  6. 'mail_smtp_auth' => 1,
  7. 'mail_smtp_user' => 'полный@емайл.адрес',
  8. 'mail_smtp_pass' => 'пароль приложения',
#7 [ЗАКРЫТО] Доработка сайта по ТЗ. Ищу исполнителя 23 апреля 2023 в 17:09

бюджет?

#8 [ЕСТЬ РЕШЕНИЕ] IP запроса на отдельной странице 30 октября 2022 в 20:01

Подкиньте пожалуйста ещё решение как сделать чтобы:

1) когда заходят на страницу с параметрами в запросе, например — example.com/page?param1=value1 & param2=value2 & param...

2) откусить все возможные параметры — param1=value1 & param2=value2 & par… ...& paramN=valueN

3) сделать перенаправление на целевой домен с точно такими же параметрами — target.com?param1=value1 & param2=value2 & par… ...& paramN=valueN

Во. Сам накалякал, на основе решения выше. Было бы желание )

  1. <?php
  2. class redir extends cmsFrontend {
  3. public function actionIndex() {
  4. header('Location: http://example.com' . $_SERVER['REQUEST_URI']);
  5. exit();
  6. }
  7. }
Dmitry

можно так

  1. $params = count($this->cms_core->uri_query) ? '?' . http_build_query($this->cms_core->uri_query) : '';
  2. $host = $this->cms_config->host;
  3. //$host = 'https://example.ru';
  4. return $this->redirect($host . $params);
#9 Текст из записей на стене пользователя не участвует в поиске 30 октября 2022 в 19:37

Здравствуйте!

Можно ли сделать как-то, чтобы поиск по сайту искал текст во всех записях профиля пользователя?

И вообще возможно ли это?

bratok191

добавить индекс в таблицу базы, используя допустим phpmyadmin sql запросом:

  1. ALTER TABLE `cms_wall_entries` ADD FULLTEXT( `content`);
  2.  

в /system/controllers/wall/hooks/fulltext_search.php создать файл fulltext_search.php с содержимым:

  1. <?php
  2.  
  3. class onWallFulltextSearch extends cmsAction {
  4.  
  5. public function run($search_controller) {
  6.  
  7. $name = 'wall';
  8. $sources[$name] = 'Запись на стене';
  9. $match_fields[$name] = array('content');
  10. $select_fields[$name] = array('id', 'content', 'user_id', 'date_pub');
  11. $filters[$name] = array();
  12. $table_names[$name] = 'wall_entries';
  13.  
  14. return [
  15. 'name' => $name,
  16. 'sources' => $sources,
  17. 'table_names' => $table_names,
  18. 'match_fields' => $match_fields,
  19. 'select_fields' => $select_fields,
  20. 'filters' => $filters,
  21. 'item_callback' => function ($item, $model, $sources_name, $match_fields, $select_fields) {
  22.  
  23. $fields = [];
  24.  
  25. foreach ($match_fields as $match_field) {
  26. if ($match_field === 'title') {
  27. continue;
  28. }
  29. $fields[$match_field] = $item[$match_field];
  30. }
  31.  
  32. return array_merge($item, [
  33. 'url' => href_to('users', $item['user_id']).'?wid='.$item['id'],
  34. 'title' => 'Запись со стены',
  35. 'fields' => $fields,
  36. 'date_pub' => $item['date_pub'],
  37. 'image' => ''
  38. ]);
  39. }
  40. ];
  41.  
  42. }
  43.  
  44. }

в панели обновить список событий компонентов:

админка > компоненты > события ( /admin/controllers/events) 

#10 Сколько стоит 10 июля 2022 в 21:09

Ну генератор реферальных ссылок я не нашел.

Look-out

посмотрите возможности:

Биллинг пользователей 2.x
Компонент

Биллинг пользователей 2.x

от r2
Купить 3500 руб.

RSN

Да, классное дополнение. Обязательно прикуплю как-то при возможности для своих хотелок.
Жаль код зашит и на локальном сервере не поиграешь пока доменное имя не выбрал))
Спасибо.

Look-out

на локалке тоже можно поиграть, необходимо только будет поднять локалку на субдомене купленного домена)

#11 Работа фильтра 2 декабря 2020 в 16:56
для формы, на js добавить отслеживание изменений select, checkbox и при изменении делать submit форм
#1 Свободные трёхсимвольные ru 27 ноября 2020 в 12:09
Может кому пригодиться, список 24.11.2020 чекал для теста 9605 позиций, есть небольшой % ошибочной проверки, или уже выкупленных

/users/files/download7770.html
#13 sms подтверждение регистрации имеется? 17 августа 2020 в 17:33



Не плохой вариант
mobileid.megafon.ru/

@alexandr22
спасибо за ссылку

ideasdigger
дополню для интересующихся для подключение этого сервиса от мегафона необходимо быть корпоративным клиентом с ооо или ип
#14 sms подтверждение регистрации имеется? 17 августа 2020 в 16:03


Не плохой вариант
mobileid.megafon.ru/

@alexandr22
спасибо за ссылку
#15 Как создавать типы полей? 7 июля 2020 в 15:06


Добрый день!
Мне необходимо для каждой записи определенного типа контента в начале контента вставить статичный HTML.
Для того, чтобы вставлять в конец есть настройка в типе контента, но мне нужно именно в начало.
Я думаю, что лучше создать новый тип поля. В нём будет прописан необходимый HTML. Далее просто создать поле в этом типе контента и поставить его в самое начало перечня полей.
Вопрос: как правильно и грамотно это сделать?
Возможно, есть какая-то готовая инструкция, но я её не нашёл

De.Ground
html код статический? единый для всех? или для каждой записи уникальный?
🍪Мы используем файлы cookie для работы сайта. Читать подробнее.