# Past de homepage aan om onderwerpen te tonen op basis van gebruikersinteresses

**URL:** https://meta.discourse.org/t/customizes-the-homepage-to-show-topics-based-on-user-interests/311283
**Category:** Development
**Created:** [9 juni 2024 om 07:28 UTC](https://meta.discourse.org/t/customizes-the-homepage-to-show-topics-based-on-user-interests/311283 "2024-06-09T07:28:35Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![kokoloman001](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/kokoloman001/32/389438_2.png) [@kokoloman001](https://meta.discourse.org/u/kokoloman001)
#### Post date: [9 juni 2024 om 07:28 UTC](https://meta.discourse.org/t/customizes-the-homepage-to-show-topics-based-on-user-interests/311283/1 "2024-06-09T07:28:35Z")

</div>

I want to hear what you think about this plugin. I’m working on a plugin that will let visitors choose a new topic to display on the homepage depending on their interests. I wrote down the idea and drew this step out, but I haven’t played with it yet.

plugin.rb

```plaintext
# 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
  # code to be executed after initialization
end

```

```plaintext
// 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;
          });
        }
      });
    });
  }
};

```

```plaintext
# 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 for settings

```plaintext
<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>

```

```plaintext
# 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

```

Thank you for your feedback and suggestions for improvements.

I am Thai. My English skills may not appear to be particularly good. I attempted to learn it while dev discourse.

---

<div class="post-metadata">

### Author: ![hello-smile6](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/hello-smile6/32/304628_2.png) [@hello-smile6](https://meta.discourse.org/u/hello-smile6)
#### Post date: [9 juni 2024 om 08:12 UTC](https://meta.discourse.org/t/customizes-the-homepage-to-show-topics-based-on-user-interests/311283/2 "2024-06-09T08:12:28Z")

</div>

Where is `/preferences/interests` implemented?

---

<div class="post-metadata">

### Author: ![kokoloman001](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/kokoloman001/32/389438_2.png) [@kokoloman001](https://meta.discourse.org/u/kokoloman001)
#### Post date: [9 juni 2024 om 10:24 UTC](https://meta.discourse.org/t/customizes-the-homepage-to-show-topics-based-on-user-interests/311283/3 "2024-06-09T10:24:00Z")

</div>

> [@hello-smile6](#):
>
> Where is `/preferences/interests` implemented?

I believe that in order to handle user interests and integrate them in user preferences, the required routes, controller actions, and templates must be created.

However, that’s just my viewpoint, and it’s simply designed. I have not yet begun construction on it. It might not go as planned if I attempt.

**Add a Route for User Preferences** :  
- Add a route that will handle requests to `/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
```

````

**Create the Controller Action** :  
- Define a controller to handle the request and fetch the user’s interests.

````
```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
```

````

**Add Interests Field in User Preferences** :  
- Modify the user preferences template to include an input for interests.

````
```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>
```

````

**Extend the Serializer** :  
- Extend the user serializer to include the interests field.

````
```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
```

````

**Modify the JavaScript for Handling Interests** :  
- Use JavaScript to fetch and save the interests to the user profile.

````
```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. **Handle the PUT Request** :

---

<div class="post-metadata">

### Author: ![Heliosurge](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/heliosurge/32/571810_2.png) [@Heliosurge](https://meta.discourse.org/u/Heliosurge)
#### Post date: [9 juni 2024 om 18:33 UTC](https://meta.discourse.org/t/customizes-the-homepage-to-show-topics-based-on-user-interests/311283/4 "2024-06-09T18:33:51Z")

</div>

Looks interesting. You might find some ideas in this plugin as well.

> [@Discourse Saved Searches](https://meta.discourse.org/t/discourse-saved-searches/67901):
>
> discourse2Summary Discourse Saved Searches allows users to save searches and be notified when any new topics or posts match the search criteria.hammer_and_wrenchRepository Link [https://github.com/discourse/discourse-saved-searches](https://github.com/discourse/discourse-saved-searches)open_bookInstall Guide [How to install plugins in Discourse](https://meta.discourse.org/t/install-plugins-in-discourse/19157)Features Following from the new watched words feature that takes action on bad words, here’s a plugin that lets people save a list of searches and get notified if any new topics a…
