skeleton
Some checks failed
CI / Test (push) Failing after 33s

This commit is contained in:
2026-03-25 12:42:19 +01:00
commit 647d5537ff
18 changed files with 701 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
defmodule MyPlugin.Application do
@moduledoc """
OTP Application for this plugin.
Uncomment the `mod:` entry in mix.exs to activate this supervision tree.
Add plugin-specific GenServers, workers, or supervisors as children here.
"""
use Application
@impl true
def start(_type, _args) do
children = [
# Add your supervised processes here, e.g.:
# {MyPlugin.Worker, []}
]
opts = [strategy: :one_for_one, name: MyPlugin.Supervisor]
Supervisor.start_link(children, opts)
end
end

81
lib/my_plugin/plugin.ex Normal file
View File

@@ -0,0 +1,81 @@
defmodule MyPlugin.Plugin do
@moduledoc """
Tribes plugin entry point.
Implements the `Tribes.Plugin` behaviour. This module is referenced by
`entry_module` in manifest.json and is called by the host's PluginManager
during startup.
"""
# Once Tribes.Plugin.Base is available, replace the manual implementation
# with:
#
# use Tribes.Plugin.Base, otp_app: :my_plugin
#
# and override only register/1.
# @behaviour Tribes.Plugin
def register(_context) do
manifest = read_manifest()
%{
name: manifest["name"],
version: manifest["version"],
provides: manifest["provides"] || [],
requires: manifest["requires"] || [],
enhances_with: manifest["enhances_with"] || [],
nav_items: [
%{
label: "My Plugin",
path: "/plugins/my_plugin",
icon: nil,
requires: [],
order: 50
}
],
pages: [
%{
path: "/plugins/my_plugin",
live_view: MyPluginWeb.HomeLive,
layout: nil
}
],
api_routes: [],
plugs: [],
children: [],
global_js: get_in(manifest, ["assets", "global_js"]) || [],
global_css: get_in(manifest, ["assets", "global_css"]) || [],
migrations_path: migrations_path(manifest),
hooks: %{}
}
end
defp read_manifest do
manifest_path()
|> File.read!()
|> Jason.decode!()
end
defp manifest_path do
# In a release, manifest.json sits alongside ebin/ in the plugin directory.
# In dev mode (path dep), it's at the project root.
case :code.priv_dir(:my_plugin) do
{:error, :bad_name} ->
# Dev mode fallback: relative to project root
Path.join(__DIR__, "../../../manifest.json") |> Path.expand()
priv_dir ->
priv_dir |> to_string() |> Path.join("../manifest.json") |> Path.expand()
end
end
defp migrations_path(manifest) do
if manifest["migrations"] do
case :code.priv_dir(:my_plugin) do
{:error, :bad_name} -> nil
priv_dir -> priv_dir |> to_string() |> Path.join("repo/migrations")
end
end
end
end

View File

@@ -0,0 +1,30 @@
defmodule MyPluginWeb.HomeLive do
@moduledoc """
Example LiveView page for the plugin.
This page is registered in the plugin spec and mounted by the host
at /plugins/my_plugin.
"""
# In dev mode (plugin loaded as path dep), you can use host macros:
# use TribesWeb, :live_view
#
# For release builds (standalone OTP app), use Phoenix.LiveView directly:
use Phoenix.LiveView
def mount(_params, _session, socket) do
{:ok, assign(socket, :page_title, "My Plugin")}
end
def render(assigns) do
~H"""
<div class="p-6">
<h1 class="text-2xl font-bold">My Plugin</h1>
<p class="mt-2 text-base-content/70">
This is a Tribes plugin. Edit this page in
<code>lib/my_plugin_web/live/home_live.ex</code>.
</p>
</div>
"""
end
end