Посты со стены в ленту

InstantCMS 2.X
#1 4 сентября 2025 в 12:52

Всем привет! Подскажите, можно ли сделать, чтобы посты со стены были в ленте постов? У меня несколько типов контента на сайте: посты (на главной сайта), фото, статьи, объявления и они все на разных страницах. У каждого типа своя страница. Стену у пользователей отключил. Вот думаю включить ее, но хотелось бы, чтобы посты со стены появлялись в ленте постов на главной странице сайта. Можно ли такое сделать?

#2 8 сентября 2025 в 09:18
Всем привет! Подскажите, можно ли сделать, чтобы посты со стены были в ленте постов?
ivan

виджет лента активности

#3 8 сентября 2025 в 11:29

виджет лента активности

TOPg

Нет, не то. Нужно, чтобы в определенную ленту контента посты со стены шли. У меня отдельные ленты — фото, посты, статьи и т.д. И вот надо, чтобы в ленту с постами шли посты со стены

#4 8 сентября 2025 в 11:59

Заказывать виджет с выводом списка типов контента (чтобы можно было выбирать) и ставить его на главную 

#5 8 сентября 2025 в 15:10
виджет лента активности TOPg Нет, не то. Нужно, чтобы в определенную ленту контента посты со стены шли. У меня отдельные ленты — фото, посты, статьи и т.д.
ivan

1. Сделайте бекап
2. замените содержимое файла шаблона ленты активности list.php

  1. <?php
  2. $last_date = '';
  3. $today_date = date('j F Y');
  4. $yesterday_date = date('j F Y', time()-3600*24);
  5. $widget_id = $widget_id ?? 'activity';
  6. $unique_prefix = 'activity_widget_' . $widget_id;
  7. $js_class = 'js-activity-widget-' . $widget_id;
  8. ?>
  9.  
  10. <div class="icms-activity__list_wd <?php echo $js_class; ?>" id="<?php echo $unique_prefix; ?>">
  11. <?php foreach($items as $item) { ?>
  12. <?php if ($show_date_groups) { ?>
  13. <?php $item_date = date('j F Y', strtotime($item['date_pub'])); ?>
  14. <?php if ($item_date != $last_date) { ?>
  15. <?php
  16. switch($item_date) {
  17. case $today_date: $date = LANG_TODAY; break;
  18. case $yesterday_date: $date = LANG_YESTERDAY; break;
  19. default: $date = lang_date($item_date);
  20. }
  21. ?>
  22. <h4 class="icms-activity__list-day"><?php echo $date; ?></h4>
  23. <?php $last_date = $item_date; ?>
  24. <?php } ?>
  25. <?php } ?>
  26.  
  27. <?php $url = href_to_profile($item['user']); ?>
  28. <div class="icms-activity__list-item media mb-3" id="<?php echo $unique_prefix; ?>_item_<?php echo $item['id']; ?>">
  29. <?php if ($show_avatars) { ?>
  30. <a href="<?php echo $url; ?>" class="icms-user-avatar mr-2 mr-md-3 small <?php echo !empty($item['user']['is_online']) ? 'peer_online' : 'peer_no_online'; ?>">
  31. <?php if($item['user']['avatar']) { ?>
  32. <?php echo html_avatar_image($item['user']['avatar'], 'micro', $item['user']['nickname']); ?>
  33. <?php } else { ?>
  34. <?php echo html_avatar_image_empty($item['user']['nickname'], 'avatar__mini'); ?>
  35. <?php } ?>
  36. </a>
  37. <?php } ?>
  38. <div class="media-body">
  39. <h6 class="my-0">
  40. <a class="author" href="<?php echo $url; ?>"><?php html($item['user']['nickname']); ?></a>
  41. <?php echo $item['description']; ?>
  42. <?php if ($item['is_private']) { ?>
  43. <span class="is_private" title="<?php html(LANG_PRIVACY_PRIVATE); ?>">
  44. <?php html_svg_icon('solid', 'lock'); ?>
  45. </span>
  46. <?php } ?>
  47. </h6>
  48. <div class="details">
  49. <span class="date small text-muted<?php echo !empty($item['is_new']) ? ' highlight_new' : ''; ?>">
  50. <?php echo $item['date_diff']; ?>
  51. </span>
  52. <?php if (!empty($item['reply_url']) && cmsUser::isLogged()) { ?>
  53. <a href="<?php echo $item['reply_url']; ?>" class="btn btn-sm">
  54. <?php html_svg_icon('solid', 'reply'); ?>
  55. <?php echo LANG_REPLY; ?>
  56. </a>
  57. <?php } ?>
  58. </div>
  59. <?php if (!empty($item['images'])) { ?>
  60. <div class="d-flex justify-content-start flex-wrap">
  61. <?php foreach($item['images'] as $image) { ?>
  62. <a href="<?php echo $image['url']; ?>" class="mr-1 mt-1" data-fancybox="<?php echo $unique_prefix; ?>_gallery_<?php echo $item['id']; ?>">
  63. <img src="<?php echo $image['src']; ?>" class="img-fluid" alt="<?php html(!empty($image['title']) ? $image['title'] : $item['subject_title']); ?>">
  64. </a>
  65. <?php } ?>
  66. </div>
  67. <?php } ?>
  68. </div>
  69. </div>
  70. <?php } ?>
  71. </div>
  72.  
  73. <script>
  74. if (typeof window.ActivityWidgetManager === 'undefined') {
  75. window.ActivityWidgetManager = {
  76. initializedWidgets: new Set(),
  77.  
  78. initWidget: function(widgetId) {
  79. if (this.initializedWidgets.has(widgetId)) return;
  80. this.initializedWidgets.add(widgetId);
  81. this.initFancybox(widgetId);
  82. },
  83.  
  84. initFancybox: function(widgetId) {
  85. if (typeof $.fancybox === 'undefined') return;
  86.  
  87. const galleryGroups = {};
  88. document.querySelectorAll(`#${widgetId} [data-fancybox]`).forEach(element => {
  89. const galleryName = element.getAttribute('data-fancybox');
  90. if (!galleryGroups[galleryName]) galleryGroups[galleryName] = [];
  91. galleryGroups[galleryName].push({
  92. src: element.getAttribute('href'),
  93. opts: { caption: element.querySelector('img')?.alt || '' }
  94. });
  95. });
  96.  
  97. for (const [galleryName, items] of Object.entries(galleryGroups)) {
  98. document.querySelectorAll(`#${widgetId} [data-fancybox="${galleryName}"]`).forEach(element => {
  99. element.addEventListener('click', function(e) {
  100. e.preventDefault();
  101. $.fancybox.open(items, {}, 0);
  102. });
  103. });
  104. }
  105. },
  106.  
  107. initAllWidgets: function() {
  108. document.querySelectorAll('.icms-activity__list_wd').forEach(container => {
  109. this.initWidget(container.id);
  110. });
  111. }
  112. };
  113.  
  114. document.addEventListener('DOMContentLoaded', () => window.ActivityWidgetManager.initAllWidgets());
  115. window.addEventListener('load', () => window.ActivityWidgetManager.initAllWidgets());
  116. } else {
  117. document.addEventListener('DOMContentLoaded', () => window.ActivityWidgetManager.initAllWidgets());
  118. }
  119. </script>
Добавлено спустя Только что

3. по адресу system/controllers/activity/widgets/list/ заменить содержимое файла widget.php

<?php

class widgetActivityList extends cmsWidget {

    public function run() {
        $show_avatars = $this->getOption('show_avatars');
        $show_date_groups = $this->getOption('date_group');
        $offset = $this->getOption('offset', 0);
        $limit = $this->getOption('limit', 10);
        $only_wall = $this->getOption('only_wall', false);

        $items = $only_wall? $this->getWallEntries($offset, $limit): $this->getActivityEntries($offset, $limit);

        if (!$items) {
            return false;
        }

        return [
            'widget_id' => $this->id,
            'show_avatars' => $show_avatars,
            'show_date_groups' => $show_date_groups,
            'items' => $items
        ];
    }

    private function getActivityEntries($offset, $limit) {
        $activity = cmsCore::getController('activity');
        $activity->model->orderBy('date_pub', 'desc');
        $activity->model->filterPrivacy()->enableHiddenParentsFilter()->filterEqual('is_pub', 1);
        cmsEventsManager::hook('activity_list_filter', $activity->model);
        $items = $activity->model->limit($offset, $limit)->getEntries();
        return $items? cmsEventsManager::hook('activity_before_list', $items): [];
    }

    private function getWallEntries($offset, $limit) {
        $model = new cmsModel();
        $entries = $model->filterEqual('controller', 'users')
                         ->filterEqual('profile_type', 'user')
                         ->orderBy('date_pub', 'desc')
                         ->limit($offset, $limit)
                         ->get('wall_entries');

        if (!$entries) {
            return [];
        }

        $user_ids = array_unique(array_column($entries, 'user_id'));
        $users = $user_ids? array_column($model->filterIn('id', $user_ids)->get('users'), null, 'id'): [];

        $formatted_items = [];
        foreach ($entries as $entry) {
            if (empty($users[$entry['user_id']])) continue;
            
            $user = $users[$entry['user_id']];
            $description = strip_tags($entry['content']);
            $description = mb_strlen($description) > 100? mb_substr($description, 0, 100). '...': $description;
            
            $formatted_items[] = [
                'id' => $entry['id'],
                'user_id' => $entry['user_id'],
                'user' => [
                    'id' => $user['id'],
                    'nickname' => $user['nickname'],
                    'avatar' => $this->getAvatarUrl($user),
                    'slug' => $user['slug'],
                    'is_online' => !empty($user['is_online'])
                ],
                'date_pub' => $entry['date_pub'],
                'date_diff' => $this->getDateDiff($entry['date_pub']),
                'description' => $description,
                'subject_title' => $description,
                'subject_url' => $this->getWallEntryUrl($entry),
                'reply_url' => $this->getWallEntryUrl($entry). '?reply=1',
                'is_private' => 0,
                'images' => $this->getWallEntryImages($entry),
                'images_count' => 0
            ];
        }

        return $formatted_items;
    }

    private function getProfileUrl($user) {
        return href_to_profile([
            'id' => $user['id'],
            'slug' => $user['slug'],
            'nickname' => $user['nickname']
        ]);
    }

    private function getWallEntryUrl($entry) {
        return href_to('users', $entry['profile_id'], ['wall', $entry['id']]);
    }

    private function getAvatarUrl($user) {
        return $user['avatar']? '/uploads/users/'. $user['id']. '/avatar/'. $user['avatar']: '/templates/default/images/avatar.png';
    }

    private function getDateDiff($date) {
        $time = strtotime($date);
        $now = time();
        $diff = $now — $time;
        
        if ($diff < 60) return $diff. ' сек. назад';
        if ($diff < 3600) return floor($diff / 60). ' мин. назад';
        if ($diff < 86400) return floor($diff / 3600). ' час. назад';
        
        return lang_date($date, 'j F Y');
    }

    private function getWallEntryImages($entry) {
        $images = [];
        $content = $entry['content_html'] ?: $entry['content'];
        
        if (preg_match_all('/<img[^>]+src="([^">]+)"/i', $content, $matches)) {
            foreach ($matches[1] as $src) {
                $clean_src = $this->getAbsoluteUrl($src);
                $images[] = ['src' => $clean_src, 'url' => $clean_src, 'title' => ''];
            }
        }
        
        return $images;
    }

    private function getAbsoluteUrl($url) {
        if (strpos($url, 'http') === 0) return $url;
        $base_url = 'https://'. $_SERVER['HTTP_HOST'];
        return $base_url. (strpos($url, '/') === 0? $url: '/'. $url);
    }

}
 

и options.form.php на 

<?php

class formWidgetActivityListOptions extends cmsForm {

    public function init() {
        cmsCore::loadControllerLanguage('activity');

        return [
            [
                'type' => 'fieldset',
                'title' => LANG_OPTIONS,
                'childs' => [
                    new fieldList('options:dataset', [
                        'title' => LANG_WD_ACTIVITY_LIST_DATASET,
                        'items' => [
                            'all' => LANG_ACTIVITY_DS_ALL,
                            'friends' => LANG_ACTIVITY_DS_FRIENDS,
                            'my' => LANG_ACTIVITY_DS_MY,
                        ],
                        'visible' => "!options.only_wall"
                    ]),
                    new fieldCheckbox('options:show_avatars', [
                        'title' => LANG_WD_ACTIVITY_LIST_SHOW_AVATARS
                    ]),
                    new fieldCheckbox('options:date_group', [
                        'title' => LANG_WD_ACTIVITY_LIST_DATE_GROUP
                    ]),
                    new fieldCheckbox('options:only_wall', [
                        'title' => 'Выводить только записи со стены',
                        'hint' => 'Если включено — будут показаны ТОЛЬКО записи, добавленные через стену пользователей',
                        'onchange' => "$('#dataset_field').toggle(!this.checked);"
                    ]),
                    new fieldNumber('options:offset', [
                        'title' => LANG_LIST_OFFSET,
                        'hint' => LANG_LIST_OFFSET_HINT,
                        'default' => 0
                    ]),
                    new fieldNumber('options:limit', [
                        'title' => LANG_LIST_LIMIT,
                        'default' => 10,
                        'rules' => [['required'], ['min', 1]]
                    ])
                ]
            ]
        ];
    }

}

#6 10 сентября 2025 в 09:44

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

#7 11 сентября 2025 в 11:34
хоть бы отписались по результатам, пол дня просидел с вашими хотелками
TOPg

Здравствуйте. Извините, пока не попробовал. Отпишусь обязательно)))

Добавлено спустя 18 минут

замените содержимое файла шаблона ленты активности list.php

TOPg

Возникла проблема. Что это за файл? Что-то не могу его найти

Изображение

Изображение

Изображение

по адресу system/controllers/activity/widgets/list/ заменить содержимое файла widget.php

TOPg

С этим проблем, это нашел.

И подскажите, как это будет выглядеть? В определенную ленту контента посты будут идти?

#8 11 сентября 2025 в 11:41

перечитайте еще раз моё сообщение, там изменения касаются 3х файлов, подробно везде пошагово написано. Используется стандартный виджет ленты активности

#9 11 сентября 2025 в 14:47

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

TOPg

Отписываюсь. То ли у меня руки кривые, то ли в другом проблема, но у меня просто перестал открываться сайт

Вы не можете отвечать в этой теме.
Войдите или зарегистрируйтесь, чтобы писать на форуме.

Похожие темы

Похожее в блогах

🍪Мы используем файлы cookie для работы сайта. Читать подробнее.