사용자 관심사에 따라 홈 화면의 주제를 맞춤 설정합니다

이 플러그인에 대한 여러분의 생각을 듣고 싶습니다. 저는 방문자의 관심사에 따라 홈페이지에 표시할 새 주제를 선택할 수 있게 해주는 플러그인을 개발 중입니다. 아이디어를 적어두고 이 단계를 설계해 보았지만, 아직 직접 테스트해 보지는 않았습니다.

plugin.rb

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

# name: custom-homepage
# about: Customizes the homepage to show topics based on user interests
# 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: "Enable Custom Homepage"

  user:
    preferences:
      interests: "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

피드백과 개선 제안에 감사드립니다.

저는 태국 사람입니다. 영어 실력이 그렇게 뛰어나지 않아 보일 수 있습니다. 디스코urses 개발을 하면서 영어를 배우려고 노력했습니다.

/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('Your preferences have been saved.');
            });
          });
        }
      });
    });
  }
};
```
  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: 'User not found' }, 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
    

흥미로워요. 이 플러그인에서도 몇 가지 아이디어를 얻을 수 있을 거예요.