Настройка главной страницы для отображения тем на основе интересов пользователя

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

plugin.rb

# plugins/custom_homepage/plugin.rb
# frozen_string_literal: true

# name: custom-homepage
# about: Настраивает главную страницу для отображения тем на основе интересов пользователя
# version: 0.1
# authors: MHAT
# url: https://domain.com

enabled_site_setting :custom_homepage_enabled

after_initialize do
  # код, который будет выполнен после инициализации
end
// plugins/custom_homepage/assets/javascripts/discourse/initializers/custom-homepage.js.es6

import { withPluginApi } from 'discourse/lib/plugin-api';

export default {
  name: 'custom-homepage',
  initialize(container) {
    withPluginApi('0.8', api => {
      api.modifyClass('component:topic-list', {
        didInsertElement() {
          this._super(...arguments);

          if (this.currentUser) {
            this.loadUserInterests();
          }
        },

        loadUserInterests() {
          const userId = this.currentUser.id;

          fetch(`/u/${userId}/preferences/interests`)
            .then(response => response.json())
            .then(data => {
              this.set('topics', this.sortTopicsByInterests(this.topics, data.interests));
            });
        },

        sortTopicsByInterests(topics, interests) {
          return topics.sort((a, b) => {
            const aScore = interests.includes(a.category_id) ? 1 : 0;
            const bScore = interests.includes(b.category_id) ? 1 : 0;

            return bScore - aScore;
          });
        }
      });
    });
  }
};
# plugins/custom_homepage/config/locales/server.en.yml
en:
  site_settings:
    custom_homepage_enabled: "Включить пользовательскую главную страницу"

  user:
    preferences:
      interests: "Интересы"

# plugins/custom_homepage/config/discourse_plugin.yml
enabled_site_setting: custom_homepage_enabled

HTML для настроек

<script type="text/x-handlebars" data-template-name="/connectors/user-preferences/interests">
  <div class="control-group">
    <label class="control-label">{{i18n 'user.preferences.interests'}}</label>
    <div class="controls">
      {{input value=currentUser.custom_fields.interests class="form-control"}}
    </div>
  </div>
</script>
# plugins/custom_homepage/plugin.rb

after_initialize do
  User.register_custom_field_type('interests', :string)
  
  add_to_serializer(:current_user, :interests) do
    object.custom_fields['interests']
  end
end

Спасибо за ваши отзывы и предложения по улучшению.

Я из Таиланда. Мой английский может показаться не очень хорошим. Я пытался изучать его, разрабатывая плагин для Discourse.

Где реализован /preferences/interests?

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

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

Добавить маршрут для настроек пользователя:
- Добавить маршрут, который будет обрабатывать запросы к /u/:username/preferences/interests.

```ruby
# plugins/custom_homepage/config/routes.rb
Discourse::Application.routes.append do
  get '/u/:username/preferences/interests' => 'custom_homepage#interests', constraints: { username: /[^\/]+/ }
end
```

Создать действие контроллера:
- Определить контроллер для обработки запроса и получения интересов пользователя.

```ruby
# plugins/custom_homepage/app/controllers/custom_homepage_controller.rb
class CustomHomepageController < ApplicationController
  requires_login
  
  def interests
    username = params[:username]
    user = User.find_by(username: username)
    
    if user
      render json: {
        interests: user.custom_fields['interests']
      }
    else
      render json: { error: 'User not found' }, status: 404
    end
  end
end
```

Добавить поле интересов в настройки пользователя:
- Изменить шаблон настроек пользователя, чтобы включить поле для ввода интересов.

```html
<!-- plugins/custom_homepage/assets/javascripts/discourse/connectors/user-preferences/interests.hbs -->
<div class="control-group">
  <label class="control-label">{{i18n 'user.preferences.interests'}}</label>
  <div class="controls">
    {{input value=model.custom_fields.interests class="form-control"}}
  </div>
</div>
```

Расширить сериализатор:
- Расширить сериализатор пользователя, чтобы включить поле интересов.

```ruby
# plugins/custom_homepage/plugin.rb

after_initialize do
  User.register_custom_field_type('interests', :string)
  
  add_to_serializer(:current_user, :interests) do
    object.custom_fields['interests']
  end

  add_to_serializer(:admin_detailed_user, :interests) do
    object.custom_fields['interests']
  end
end
```

Изменить JavaScript для обработки интересов:
- Использовать JavaScript для получения и сохранения интересов в профиле пользователя.

```javascript
// plugins/custom_homepage/assets/javascripts/discourse/initializers/custom-homepage.js.es6

import { withPluginApi } from 'discourse/lib/plugin-api';

export default {
  name: 'custom-homepage',
  initialize(container) {
    withPluginApi('0.8', api => {
      api.modifyClass('controller:preferences/account', {
        save() {
          const interests = this.model.custom_fields.interests;
          this.model.save().then(() => {
            fetch(`/u/${this.model.username}/preferences/interests`, {
              method: 'PUT',
              headers: {
                'Content-Type': 'application/json',
                'X-CSRF-Token': Discourse.CSRFToken
              },
              body: JSON.stringify({ interests })
            }).then(response => response.json()).then(() => {
              this.flash('Ваши настройки сохранены.');
            });
          });
        }
      });
    });
  }
};
```
  1. Обработка PUT-запроса:

    • Реализовать логику для обработки PUT-запроса и сохранения интересов в контроллере.
    # plugins/custom_homepage/app/controllers/custom_homepage_controller.rb
    class CustomHomepageController < ApplicationController
      requires_login
    
      def interests
        if request.get?
          username = params[:username]
          user = User.find_by(username: username)
          
          if user
            render json: {
              interests: user.custom_fields['interests']
            }
          else
            render json: { error: 'Пользователь не найден' }, status: 404
          end
        elsif request.put?
          user = current_user
          interests = params[:interests]
          user.custom_fields['interests'] = interests
          user.save_custom_fields
          render json: success_json
        end
      end
    end
    

Выглядит интересно. Возможно, вы найдёте здесь идеи и в этом плагине.