Gibt es eine bessere Möglichkeit, eine Ajax-Anfrage von einer Theme-Komponente aus zu stellen?

Ich habe eine Theme-Komponente erstellt, die angezeigt wird, wenn man das Profil eines Benutzers betrachtet. Sie stellt eine AJAX-Anfrage an eine separate Website (die ich kontrolliere), um zu prüfen, ob der Discourse-Benutzer dort ein Konto hat (wobei die Discourse-Benutzer-ID in der URL übermittelt wird). Falls ja, wird ein Link zu deren Konto auf dieser Website angezeigt.

Es funktioniert, aber ich bin mir ziemlich sicher, dass es eine schreckliche Hackerei ist, die einen Discourse-Entwickler krank machen würde! Deshalb wollte ich fragen, ob es einen besseren Weg gibt, dies zu tun? Ich bin JavaScript- und Ruby-Entwickler, habe aber noch nie mit Ember gearbeitet (ich habe Vue, Backbone und React verwendet).

<script type="text/discourse-plugin" version="0.8.7">
    const {ajax} = require('discourse/lib/ajax')

    api.registerConnectorClass('user-profile-primary', 'custom-profile-link', {
      setupComponent(args, component) {
        args.model.get('fetchPersonnelMember')
      }
    })
    
    api.modifyClass('model:user', {
      fetchPersonnelMember: function () {
        console.log('running!', ajax)
        const urlTemplate = settings.personnel_lookup_url // z. B. "https://api.29th.org/members?discourse_id=%s"

        const url = urlTemplate.replace(/%s/, this.id)
        return ajax(url).then((result) => {
            if (result.status == true && result.member.id) {
              this.setProperties({personnelMember: result.member})
            }
          })
      }.property('id'),
      
      personnelLinkUrl: function () {
        if (this.personnelMember) {
          const viewUrlTemplate = settings.personnel_view_url // z. B. "https://personnel.29th.org/#members/%s"
          return viewUrlTemplate.replace(/%s/, this.personnelMember.id)
        }
      }.property('personnelMember'),
      
      personnelLinkName: function () {
        return this.personnelMember ? this.personnelMember.short_name : ''
      }.property('personnelMember')
    })
</script>

<script type='text/x-handlebars' data-template-name='/connectors/user-profile-primary/custom-profile-link'>
  {{#if model.personnelLinkUrl}}
    <div class="public-user-fields">
      <div class="public-user-field">
        <span class="user-field-name">
          {{theme-setting 'personnel_label'}}
        </span>
        <span class="user-field-value">
          <a href="{{{model.personnelLinkUrl}}}">{{model.personnelLinkName}}</a>
        </span>
      </div>
    </div>
  {{/if}}
</script>

Ich habe dies größtenteils von (Retired) Use an ID in a custom user field to link to a user's external profile - #24 by LeoMcA abgeleitet. Meine Vermutung ist, dass das Hauptproblem darin besteht, dass ich eine berechnete Eigenschaft verwende, um eine asynchrone Funktion auszuführen, was ein No-Go ist. Stattdessen sollte ich diese asynchrone Anfrage in irgendeiner Art von “on load”-Hook ausführen (aber nur, wenn ich mich auf der Benutzerprofilseite befinde).

Ich habe auch das Gefühl, dass ich das Rad ein wenig neu erfinde, was das Template-Format der Variablen angeht. Idealerweise würde ich dies als konfigurierbares Plugin erstellen, das ich teilen könnte, sodass die Einstellungen eher wie ein Handlebars-Template aussehen würden, z. B. https://mysite.com/members/{{id}}, aber ich habe keine Hilfsprogramme oder Helfer dafür im Discourse-Codebase gefunden.

Ich würde mich über Ihr Feedback freuen! Vielen Dank für Ihre Zeit.

2 „Gefällt mir“

Ich hoffe, ein ‘Bump’ ist in Ordnung, denn ich könnte hier wirklich eine Hilfestellung gebrauchen :slight_smile:

1 „Gefällt mir“

Wenn du stattdessen ein Plugin verwenden kannst, würde ich die Anfrage serverseitig stellen (und die Daten speichern, falls sie stabil sind) und den Link zum Serializer hinzufügen.

Ich glaube, es gibt eine Theme-Komponente, die weitere Themenlisten wie bei Feverbee ganz oben auf der Seite hinzufügt. Vielleicht enthält sie das Beispiel, das du brauchst.