关于此事的几点思考。
开发付费 Discourse 课程
在 Udemy 或 Coursera 等平台上开设与 Discourse 开发相关的课程的想法很有趣。我怀疑主要问题在于,除了 Discourse 团队之外,没有多少人有资格创建 Discourse 开发课程,而且课程的潜在学生数量相当少。话虽如此,我相信一门与开发 Discourse 主题或插件相关的优秀课程,随着时间的推移,可以获得足够多的学生,使其值得投入精力来创建。
另外一个可能的问题是,对 Discourse 课程收费可能违背本论坛的精神。不过我只是在猜测。
Discourse 开发教程
我认为关于许多 Discourse 插件、主题和主题组件的实际实现相当简单的观察是正确的。与其他平台的开发一样,问题在于如何克服不理解各部分如何协同工作的初始障碍。Discourse 团队(或其他合格的开发人员)可以通过编写一些教程来帮助解决这个问题,这些教程将引导你完成创建功能性主题、主题组件和插件的整个过程。例如,一个关于创建 Discourse 占位符主题组件的分步指南。
我意识到这需要大量的时间投入,因此需要与 Discourse 的业务目标保持一致。
当前可用资源
通过一点搜索,可以在本论坛上找到大量关于 Discourse 开发的优质信息。查看 Discourse GitHub 仓库中的代码示例也是一种很好的学习方式。
最近一个不应被忽视的工具是 GitHub Copilot。如果你以正确的方式构建开发环境,它可以帮助你了解如何开发 Discourse 主题和插件。对于开发 Discourse 主题,我发现的最佳方法是在本地 Discourse 安装的根目录中开发主题(使用 Discourse 主题 CLI)。这样构建可以使 Copilot 轻松访问 Discourse 代码库。(请注意,对于插件开发,plugins 文件夹已在根目录 /discourse 中。)(另外请注意,我可能错了,Copilot 实际上并没有访问我在 IDE 中加载的 Discourse 代码库。无论如何,核心 Discourse 代码可供我自己参考是有帮助的。)
为了避免分心,并专注于将 Copilot 用作学习工具,我在我的 IDE(VS Code)中关闭了 Copilot 的自动补全功能,只通过聊天与 Copilot 进行交互。以下是一个示例,说明它可以提供什么样的帮助。(shopify.js 是 Theme CLI 在我的主题的 /javascripts/discourse/api-initializers/ 目录中创建的文件。)
与 Copilot 的对话
scossar: 你能解释一下 shopify.js 中的默认导出在做什么吗?它基本上是使用 discourse_theme gem 创建主题时 Discourse 提供的样板代码。我已经修改了样板代码,以便它会记录每次页面更改。我理解 api.onPageChange 的调用,但我并不清楚 api 对象是如何被注入到我的代码中的。
GitHub Copilot:
api对象通过apiInitializer返回的对象中的initialize方法被注入到你的代码中。以下是简化版的操作:
当 Discourse 启动时,它会运行所有初始化器。
apiInitializer函数创建一个在"inject-objects"初始化器之后运行的初始化器。当此初始化器运行时,它会调用
withPluginApi函数,并将version、cb和opts参数传递进去。
withPluginApi函数会检查当前的 Discourse 版本是否与指定的版本兼容。如果兼容,它会调用回调函数 (cb) 并将PluginApi实例作为参数传递。这个PluginApi实例就是你在代码中看到的api对象。因此,
api对象是PluginApi的一个实例,它通过withPluginApi函数传递到你的代码中。这个对象提供了许多允许你与 Discourse 交互的方法,例如你已经在使用的onPageChange。
scossar: 那么 shopify.js 中默认导出的第二个参数函数就是 apiInitializer 接受的回调函数吗?
GitHub Copilot: 是的,没错。
apiInitializer的第二个参数是一个回调函数。当初始化器运行时(假设当前的 Discourse 版本与指定的版本兼容),这个函数会以PluginApi实例作为参数被调用。这就是api对象在你的shopify.js文件中可用的方式。
在我弄清楚之后……
scossar: ……还有另一个想法,api.decorateCooked 是否可以用来注入一个托管在外部应用程序上的评分 iframe(例如,由我正在开发的 Shopify 应用托管)?
GitHub Copilot: 是的,你可以使用
api.decorateCooked将 iframe 注入到帖子中。以下是一个大致的示例,说明你如何做到这一点:api.decorateCooked($elem => { const postId = $elem.data('post-id'); const iframe = document.createElement('iframe'); iframe.src = `https://your-app.com/ratings?post_id=${postId}`; iframe.width = '100%'; iframe.height = '200'; // 根据需要调整 $elem.append(iframe); }, { id: 'rating-iframe' });在这个示例中,
api.decorateCooked用于将一个 iframe 追加到每个帖子。iframe 的源被设置为你的外部应用程序上的一个 URL,并将帖子 ID 作为查询参数包含在内。你需要将'https://your-app.com/ratings'替换为你评分页面的实际 URL。请注意,这是一个简化的示例。你可能需要根据你的需求进行调整,并且绝对应该添加错误处理和其他必要的预防措施,以确保它能够正确且安全地工作。
目前还不能指望 Copilot 能够写出你所有的代码,但它是一个学习如何编写 Discourse 代码的绝佳工具。