バックエンド開発者にとってDiscourseの変更/拡張はどれくらい「難しい」か

こんにちは。

バックエンドの経験があるMLEです。フロントエンドのスキルは皆無、またはかなり弱いです。

以下の機能を必要とする小規模フォーラムをホストすることに興味があります。

  • 複数のタグで投稿を簡単にフィルタリングする
  • ユーザーがログインしないと特定のカテゴリが非表示になる
  • サインアップには管理者の承認が必要
  • サイト上部に写真カルーセルを設置する可能性

このようなことは難しいでしょうか?いくつかのプラグインのコードを見てみましたが、実際のコードは非常に短く読みやすいものの、書くのは難しそうに見えます。

「いいね!」 2

私も同じ状況です。バックエンドのnodejsの経験があります。フロントエンドでもhtml/css/javascriptを少しやりましたが、バックエンドの方が圧倒的に経験が多いです。DiscourseやRubyに特化した専門的なコードや、非常に意見の強いコーディングスタイルが多いように見えます。JavaScriptは知っていても、Discourseのコードベースは私には威圧的で複雑に見えます。コードベース全体をローカルAIに読み込ませて、やりたいことについて質問できるようにすることを真剣に考えています。それ以外では、既存のコードやプラグインなどを読んで、できる限り理解を深めることしかできません。知識を共有したり、一緒に学んだりすることに興味があれば、ぜひ :slight_smile:

「いいね!」 1

はい、かなりの学習曲線があります。しかし、あなたが言及したすべてのものはすでに存在しており、コーディングは必要ありません。

はコアのDiscourseにあり、

は既存のテーマコンポーネントで実現できます。

「いいね!」 5

UdemyでDiscourse開発に関するビデオコースがあれば、喜んで購入します。誰にお金を払えばいいか教えてください。:dollar_banknote::dollar_banknote::dollar_banknote:

「いいね!」 2

これはAPIで既にサポートされているため、いじる必要はありません。フロントエンドからも既に可能です!それを実行するためだけに「ウィジェット」(Glimmerコンポーネント!)を作成しました!:

このコンポーネントは、右サイドバーのブロックとレイアウトで動作します。

「いいね!」 1

ネストされた階層を作成するためにこれを使用できますか?

私が検討しているフォーラムは、Discourseのようなフォーラムを初めて利用する高齢者を対象としています。

従来のフォーラムのようなネストされた構造をナビゲートできると、彼らにとって良いでしょう。

「いいね!」 1

ネストにはCategoriesを使用してください。

「いいね!」 2

多くの Discourse インスタンスがこれを選択しています。以下をご覧ください。

「いいね!」 2

話題がそれますが、これはここで非常に役立ちました。AI を使った説明機能が大好きです。

MLE は、与えられた文脈では機械学習エンジニアを指します。これは、データとアルゴリズムを使用して、明示的にプログラムされていなくても機械が特定のタスクを実行できるようにするモデルを構築することを専門とする専門家です。彼らは一般的にコンピューターサイエンス、統計学、プログラミングの強力なバックグラウンドを持っており、その専門知識は、予測モデルやその他の機械学習製品の構築と展開など、テクノロジーのバックエンド側面に焦点を当てる傾向があります。元の投稿者が「MLE」に言及するとき、彼らはバックエンド開発に精通しているが、フロントエンド開発の経験がない機械学習エンジニアであることを示しています。

「いいね!」 5

これについていくつか考えを述べます。

有料Discourse開発コースの作成

UdemyやCourseraのようなプラットフォームでDiscourse開発に関するコースを作成するというアイデアは興味深いです。しかし、Discourseチーム以外でDiscourse開発のコースを作成できる資格を持つ人はそれほど多くなく、コースの潜在的な受講者数もかなり少ないというのが主な問題点だと推測されます。とはいえ、Discourseのテーマやプラグイン開発に関する良いコースであれば、時間をかければ十分な受講者数を集め、コース作成の労力に見合うだけの価値を生み出すことができると確信しています。

また、Discourseのコースに料金を設定することが、このフォーラムの精神に反する可能性があるという問題も考えられます。これはあくまで推測ですが。

Discourse開発チュートリアル

多くのDiscourseプラグイン、テーマ、テーマコンポーネントの実装が非常にシンプルであるという観察は正しいと思います。他のプラットフォームの開発と同様に、問題は、各部分がどのように組み合わさっているのかを理解するという最初の障壁を乗り越えることです。Discourseチーム(または他の資格のある開発者)は、機能的なテーマ、テーマコンポーネント、およびプラグインを作成する全プロセスを案内するチュートリアルをいくつか書くことで、この点について支援できるでしょう。例えば、Discourse Placeholderテーマコンポーネントのようなものを作成するステップバイステップガイドです。

これには多大な時間投資が必要であることは理解しており、Discourseのビジネス目標と一致させる必要があります。

現在利用可能なリソース

少し検索すれば、このフォーラムにはDiscourse開発に関する良い情報がたくさんあります。Discourse GitHubリポジトリのコード例を見ることも、学習の良い方法です。

最近無視できないツールとしてGitHub Copilotがあります。開発環境を適切に構成すれば、Discourseのテーマやプラグインの開発方法を理解するのに役立ちます。Discourseテーマの開発については、私が発見した最良の方法は、ローカルのDiscourseインストールのルートディレクトリでテーマを開発することです(Discourse Theme CLIを使用)。このように構成することで、CopilotはDiscourseのコードベースに簡単にアクセスできます。(プラグイン開発については、pluginsフォルダはすでにルート/discourseディレクトリにあります。)(また、CopilotがIDEにロードしたDiscourseコードベースに実際にアクセスしているかどうかは、間違っている可能性もあります。いずれにしても、コアDiscourseコードを自身の参照用に利用できることは役立ちます。)

気を散らさないように、またCopilotを学習ツールとして活用することに集中するために、IDE(VS Code)のCopilotの補完機能をオフにし、チャット経由でのみCopilotと対話します。以下は、それが提供できる支援の例です。(shopify.jsは、Theme CLIによって私のテーマの/javascripts/discourse/api-initializers/ディレクトリに作成されたファイルです。)

Copilotとの会話

\u003escossar: shopify.jsのデフォルトエクスポートが何をしているのか説明してもらえますか?これは基本的に、discourse_theme gemでテーマが作成されたときにDiscourseによって提供される定型コードです。定型コードを変更して、ページ変更ごとにログを記録するようにしました。api.onPageChangeの呼び出しは理解していますが、apiオブジェクトがどのように私のコードに注入されているのか、明確には理解できていません。

\u003e GitHub Copilot: apiオブジェクトは、apiInitializerから返されるオブジェクトのinitializeメソッド内で呼び出されるwithPluginApi関数を通じてコードに注入されます。

\u003e 以下は、何が起こっているのかを簡略化したバージョンです。

\u003e 1. Discourseが起動すると、すべてのイニシャライザを実行します。

\u003e 2. apiInitializer関数は、"inject-objects"イニシャライザの後に実行されるイニシャライザを作成します。

\u003e 3. このイニシャライザが実行されると、versioncboptsパラメータを渡してwithPluginApi関数を呼び出します。

\u003e 4. withPluginApi関数は、現在のDiscourseのバージョンが指定されたバージョンと互換性があるかどうかを確認します。互換性がある場合、コールバック関数(cb)を呼び出し、PluginApiインスタンスを引数として渡します。このPluginApiインスタンスが、コードで見られるapiオブジェクトです。

\u003e したがって、apiオブジェクトはPluginApiのインスタンスであり、withPluginApi関数によってコードに渡されています。このオブジェクトは、onPageChangeのように、Discourseと対話できる多くのメソッドを提供しています。

\u003escossar: では、shopify.jsのデフォルトエクスポートの2番目の引数である関数は、apiInitializerが受け入れるコールバック関数ということですか?

\u003eGitHub Copilot: はい、その通りです。apiInitializerの2番目の引数はコールバック関数です。この関数は、イニシャライザが実行されるときに(現在のDiscourseバージョンが指定されたバージョンと互換性がある場合)、PluginApiインスタンスを引数として呼び出されます。これが、apiオブジェクトがshopify.jsファイルで利用可能になる方法です。

それを理解した後…

\u003escossar: …もう一つ、api.decorateCookedを使って、外部アプリケーションでホストされているレーティングiframe(例えば、私が開発しているShopifyアプリでホストされているもの)を挿入できますか?

\u003e GitHub Copilot: はい、api.decorateCookedを使用して、投稿にiframeを挿入できます。以下にその方法の簡単な例を示します。

\u003e javascript \u003e api.decorateCooked($elem =\u003e { \u003e const postId = $elem.data('post-id'); \u003e const iframe = document.createElement('iframe'); \u003e iframe.src = `https://your-app.com/ratings?post_id=${postId}`; \u003e iframe.width = '100%'; \u003e iframe.height = '200'; // 必要に応じて調整 \u003e $elem.append(iframe); \u003e }, { id: 'rating-iframe' }); \u003e

\u003e この例では、api.decorateCookedを使用して、各投稿にiframeを追加しています。iframeのソースは、投稿IDをクエリパラメータとして含めて、外部アプリケーションのURLに設定されています。'https://your-app.com/ratings'をレーティングページの実際のURLに置き換える必要があります。

\u003e これは単純化された例であることに注意してください。必要に応じて調整する必要がある場合があり、正しく安全に機能するように、エラー処理やその他の必要な予防措置を追加する必要があるでしょう。

現時点では、Copilotにすべてのコードを実際に書くことを期待するのは合理的ではありませんが、Discourseコードの書き方を学ぶための優れたツールです。

高齢者にとっては、カテゴリを少なくし、階層を減らす方が簡単だと思います。

ごく一部の人にしか関心のないトラフィックが大量にない限り、多くのカテゴリを必要としないでしょう。