Packages
phoenix_kit
1.7.21
1.7.208
1.7.207
1.7.206
1.7.205
1.7.204
1.7.203
1.7.202
1.7.201
1.7.200
1.7.199
1.7.198
1.7.197
1.7.196
1.7.194
1.7.193
1.7.192
1.7.191
1.7.190
1.7.189
1.7.187
1.7.186
1.7.185
1.7.184
1.7.183
1.7.182
1.7.181
1.7.180
1.7.179
1.7.178
1.7.177
1.7.176
1.7.175
1.7.174
1.7.173
1.7.172
1.7.171
1.7.170
1.7.169
1.7.168
1.7.167
1.7.166
1.7.165
1.7.164
1.7.162
1.7.161
1.7.160
1.7.159
1.7.157
1.7.156
1.7.155
1.7.154
1.7.153
1.7.152
1.7.151
1.7.150
1.7.149
1.7.146
1.7.145
1.7.144
1.7.143
1.7.138
1.7.133
1.7.132
1.7.131
1.7.130
1.7.128
1.7.126
1.7.125
1.7.121
1.7.120
1.7.119
1.7.118
1.7.117
1.7.116
1.7.115
1.7.114
1.7.113
1.7.112
1.7.111
1.7.110
1.7.109
1.7.108
1.7.107
1.7.106
1.7.105
1.7.104
1.7.103
1.7.102
1.7.101
1.7.100
1.7.99
1.7.98
1.7.97
1.7.96
1.7.95
1.7.94
1.7.93
1.7.92
1.7.91
1.7.90
1.7.89
1.7.88
1.7.87
1.7.86
1.7.85
1.7.84
1.7.83
1.7.82
1.7.81
1.7.80
1.7.79
1.7.78
1.7.77
1.7.76
1.7.75
1.7.74
1.7.71
1.7.70
1.7.69
1.7.66
1.7.65
1.7.64
1.7.63
1.7.62
1.7.61
1.7.59
1.7.58
1.7.57
1.7.56
1.7.55
1.7.54
1.7.53
1.7.52
1.7.51
1.7.49
1.7.44
1.7.43
1.7.42
1.7.41
1.7.39
1.7.38
1.7.37
1.7.36
1.7.34
1.7.33
1.7.31
1.7.30
1.7.29
1.7.28
1.7.27
1.7.26
1.7.25
1.7.24
1.7.23
1.7.22
1.7.21
1.7.20
1.7.19
1.7.18
1.7.17
1.7.16
1.7.15
1.7.14
1.7.13
1.7.12
1.7.11
1.7.10
1.7.9
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
1.7.3
1.7.2
1.7.1
1.7.0
1.6.20
1.6.19
1.6.18
1.6.17
1.6.16
1.6.15
1.6.14
1.6.13
1.6.12
1.6.11
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.5.2
1.5.1
1.5.0
1.4.9
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.10
1.2.9
1.2.8
1.2.7
1.2.5
1.2.4
1.2.2
1.2.1
1.2.0
1.1.0
1.0.0
A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more
Current section
Files
Jump to
Current section
Files
lib/mix/tasks/phoenix_kit.gen.admin_page.ex
defmodule Mix.Tasks.PhoenixKit.Gen.AdminPage do
@moduledoc """
Igniter task that generates admin pages using template files.
## Usage
mix phoenix_kit.gen.admin_page MyCategory MyPage "Page Title" --url="/admin/my-page"
## Arguments
- `category` - The category name
- `page_name` - The name for the page module (PascalCase)
- `page_title` - The display title for the page
## Options
- `--url` - The URL path for the page (required)
- `--icon` - Heroicon name for the page (optional, defaults to "hero-document-text")
- `--description` - Brief description for the page (optional)
- `--category-icon` - Heroicon name for the category (optional, defaults to "hero-folder"). Only used when creating a new category.
"""
@shortdoc "Generates admin page using template files"
use Igniter.Mix.Task
require Igniter.Code.Common
require Igniter.Code.Module
alias PhoenixKit.Install.IgniterConfig
alias PhoenixKit.Install.IgniterHelpers
@impl Igniter.Mix.Task
def info(_argv, _composing_task) do
%Igniter.Mix.Task.Info{
group: :phoenix_kit,
example:
"mix phoenix_kit.gen.admin_page Analytics Reports \"Reports Dashboard\" --url=\"/admin/analytics/reports\" --category-icon=\"hero-chart-bar\"",
schema: [
url: :string,
icon: :string,
description: :string,
category_icon: :string
],
aliases: [u: :url, i: :icon, d: :description, ci: :category_icon]
}
end
@impl Igniter.Mix.Task
def igniter(igniter) do
# Get options and arguments from igniter context
opts = igniter.args.options
argv = igniter.args.argv
case parse_args(argv, opts) do
{:ok, {category, page_name, page_title}} ->
igniter
|> generate_admin_page(category, page_name, page_title, opts)
{:error, message} ->
Igniter.add_notice(igniter, """
❌ Error: #{message}
Usage: mix phoenix_kit.gen.admin_page <category> <page_name> <page_title> --url=<url>
Example: mix phoenix_kit.gen.admin_page Analytics Reports "Reports Dashboard" --url="/admin/analytics/reports"
""")
end
end
@impl Mix.Task
def run(argv) do
# Handle --help flag manually
if "--help" in argv or "-h" in argv do
Mix.shell().info("""
Generates admin page using template files.
Usage:
mix phoenix_kit.gen.admin_page MyCategory MyPage "Page Title" --url="/admin/my-page"
Arguments:
category - The category name
page_name - The name for the page module (PascalCase)
page_title - The display title for the page
Options:
--url - The URL path for the page (required)
--icon - Heroicon name for the page (optional, defaults to "hero-document-text")
--description - Brief description for the page (optional)
--category-icon - Heroicon name for the category (optional, defaults to "hero-folder")
Example:
mix phoenix_kit.gen.admin_page Analytics Reports "Reports Dashboard" \\
--url="/admin/analytics/reports" \\
--icon="hero-chart-bar" \\
--category-icon="hero-chart-bar"
""")
:ok
else
# Delegate to Igniter.Mix.Task for standard execution
super(argv)
end
end
defp parse_args(argv, opts) do
# Filter out option arguments (starting with --) from argv
positional_args = Enum.reject(argv, &String.starts_with?(&1, "--"))
case positional_args do
[category, page_name, page_title] ->
url = Keyword.get(opts, :url)
if url do
{:ok, {category, page_name, page_title}}
else
{:error, "--url option is required"}
end
args when length(args) < 3 ->
{:error, "not enough arguments"}
_ ->
{:error, "invalid arguments"}
end
end
defp generate_admin_page(igniter, category, page_name, page_title, opts) do
url = Keyword.get(opts, :url)
icon = Keyword.get(opts, :icon, "hero-document-text")
description = Keyword.get(opts, :description)
# Validate inputs
cond do
!url ->
Igniter.add_issue(igniter, {:fatal, "--url option is required", []})
!String.starts_with?(url, "/") ->
Igniter.add_issue(igniter, {:fatal, "URL must start with '/'", []})
byte_size(page_title) > 100 ->
Igniter.add_issue(igniter, {:fatal, "Page title must be less than 100 characters", []})
description && byte_size(description) > 200 ->
Igniter.add_issue(igniter, {:fatal, "Description must be less than 200 characters", []})
true ->
igniter
|> create_template_based_live_view(page_name, page_title, url, category)
|> update_admin_categories_config(category, page_title, url, icon, description, opts)
|> print_success_message(category, page_name, page_title, url)
end
end
defp create_template_based_live_view(igniter, page_name, page_title, url, category) do
# Create nested module name with category
category_module_name = Macro.camelize(String.replace(category, " ", "_"))
app_name = IgniterHelpers.get_parent_app_name(igniter)
web_module = IgniterHelpers.get_parent_app_module_web(igniter)
module_name = "Live.Admin.#{category_module_name}.#{page_name}"
# Read the EEx template file
template_path =
case :code.priv_dir(:phoenix_kit) do
priv_dir when is_list(priv_dir) or is_binary(priv_dir) ->
Path.join(priv_dir, "templates/admin_category_page.ex")
_ ->
"priv/templates/admin_category_page.ex"
end
case File.read(template_path) do
{:ok, template_content} ->
# Build full module name as a string
web_module_string =
web_module
|> to_string()
|> String.replace_prefix("Elixir.", "")
full_module_name = Module.concat([web_module_string, "PhoenixKit", module_name])
# Use string replacement to avoid EEx/HEEX conflicts
rendered_content = template_content
# Extract the module name without Elixir prefix for the template
module_name_without_elixir =
full_module_name
|> to_string()
|> String.replace_prefix("Elixir.", "")
rendered_content =
rendered_content
|> String.replace("<%= @module_name %>", module_name_without_elixir)
|> String.replace("<%= @web_module_prefix %>", web_module_string)
|> String.replace("<%= @page_title %>", to_string(page_title))
|> String.replace("<%= @url %>", to_string(url))
|> String.replace("<%= @category %>", to_string(category))
# Build the correct path
file_path = build_live_view_file_path(app_name, category, page_name)
igniter
|> Igniter.Project.Module.create_module(full_module_name, rendered_content,
path: file_path
)
{:error, reason} ->
igniter
|> Igniter.add_issue({:fatal, "Failed to read template file: #{reason}", []})
end
end
defp update_admin_categories_config(igniter, category, page_title, url, icon, description, opts) do
new_subsection = %{
title: page_title,
url: url,
icon: icon,
description: description
}
# Get category icon from options or use default
category_icon = Keyword.get(opts, :category_icon, "hero-folder")
# Use IgniterConfig to add the page to the category (creates category if needed)
IgniterConfig.add_to_admin_category(
igniter,
category,
new_subsection,
icon: category_icon
)
end
defp print_success_message(igniter, category, page_name, _page_title, url) do
web_module_name = IgniterHelpers.get_parent_app_module_web_string(igniter)
# Generate the full module name for display
category_module_name = Macro.camelize(String.replace(category, " ", "_"))
full_module_name =
"#{web_module_name}.PhoenixKit.Live.Admin.#{category_module_name}.#{page_name}"
Igniter.add_notice(igniter, """
✅ Admin page generated successfully using template!
Created: #{full_module_name}
Added to category: #{category}
URL: #{url}
Template: admin_category_page.ex
What was done:
1. ✓ Created LiveView module with authentication requirements
2. ✓ Added to admin dashboard configuration
📝 Important: Router Setup Required
Please add this route to your admin live_session in your router:
live "#{url}", #{full_module_name}, :index
The route should be added inside the live_session with:
- on_mount: [{PhoenixKitWeb.Users.Auth, :phoenix_kit_ensure_admin}]
- Session name: :phoenix_kit_admin or :phoenix_kit_admin_locale
Example location in your router (lib/your_app_web/router.ex):
scope "/" do
pipe_through :browser
live_session :phoenix_kit_admin_custom_categories,
on_mount: [{PhoenixKitWeb.Users.Auth, :phoenix_kit_ensure_admin}] do
# ... existing admin routes ...
live "#{url}", #{full_module_name}, :index
end
end
Next steps:
1. Add the route to your admin live_session (see above)
2. Restart your server
3. Implement the page functionality in the LiveView module
4. Customize the page content as needed
""")
end
# Builds the full file path for the LiveView template
defp build_live_view_file_path(app_name, category, page_name) do
# Use the app_name to get the correct web directory name
# E.g., phoenix_kit_parent_project -> phoenix_kit_parent_project_web
web_path =
app_name
|> to_string()
|> Kernel.<>("_web")
|> String.downcase()
# Convert category to path-safe format
category_path =
category
|> String.replace(" ", "_")
|> String.downcase()
# Convert page name to lowercase for the file
file_name = String.downcase(page_name)
# Return the full file path
"lib/#{web_path}/phoenix_kit/live/admin/#{category_path}/#{file_name}.ex"
end
end