Packages
phoenix_kit
1.7.61
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/phoenix_kit/install/layout_config.ex
defmodule PhoenixKit.Install.LayoutConfig do
@moduledoc """
Handles layout integration configuration for PhoenixKit installation.
This module provides functionality to:
- Detect app layouts using Phoenix conventions
- Add layout configuration to config files
- Handle recompilation requirements
- Generate appropriate notices for layout setup
"""
use PhoenixKit.Install.IgniterCompat
alias Igniter.Project.Config
alias PhoenixKit.Install.IgniterHelpers
alias PhoenixKit.Utils.PhoenixVersion
@doc """
Adds layout integration configuration to the Phoenix application.
## Parameters
- `igniter` - The igniter context
## Returns
Updated igniter with layout configuration and notices.
"""
def add_layout_integration_configuration(igniter) do
case detect_app_layouts(igniter) do
{igniter, nil} ->
# No layouts detected, use PhoenixKit defaults
add_layout_integration_notice(igniter, :no_layouts_detected)
{igniter, {layouts_module, _}} ->
# Add layout configuration to config.exs
igniter
|> add_layout_config(layouts_module)
|> add_layout_integration_notice(:layouts_detected)
end
end
# Detect app layouts using IgniterPhoenix
defp detect_app_layouts(igniter) do
layouts_module = IgniterHelpers.get_parent_app_module_web_layouts(igniter)
if layouts_module != nil do
{igniter, {layouts_module, :app}}
else
{igniter, nil}
end
end
# Add layout configuration to config.exs with Phoenix version support
defp add_layout_config(igniter, layouts_module) do
# Add modern layout configuration based on Phoenix version
igniter
|> add_modern_layout_config_with_comments(layouts_module)
|> recompile_phoenix_kit_dependency()
end
# Add modern layout configuration with Phoenix version detection and comments
defp add_modern_layout_config_with_comments(igniter, layouts_module) do
case PhoenixVersion.get_strategy() do
:modern ->
# Phoenix v1.8+ - Use function component configuration
add_modern_layout_config(igniter, layouts_module)
:legacy ->
# Phoenix v1.7- - Use legacy layout configuration
add_legacy_layout_config(igniter, layouts_module)
end
|> add_version_aware_comments(layouts_module)
end
# Skip redundant layout notice since already covered
defp add_layout_integration_notice(igniter, :layouts_detected) do
igniter
end
defp add_layout_integration_notice(igniter, :no_layouts_detected) do
notice = "💡 To integrate with your app's design, see layout configuration in README.md"
Igniter.add_notice(igniter, notice)
end
# Recompile PhoenixKit dependency to pick up layout configuration changes
defp recompile_phoenix_kit_dependency(igniter) do
# Since this is running during installation, we need to recompile the dependency
# to ensure the layout configuration changes are picked up immediately
recompile_notice = """
🔄 Recompiling PhoenixKit to apply layout configuration...
"""
igniter = Igniter.add_notice(igniter, recompile_notice)
# Run the recompilation in the background using System.cmd instead of Mix task
# to avoid potential issues with Mix state during Igniter execution
try do
{output, exit_code} =
System.cmd("mix", ["deps.compile", "phoenix_kit", "--force"], stderr_to_stdout: true)
if exit_code == 0 do
success_notice = "✅ PhoenixKit dependency recompiled successfully!"
Igniter.add_notice(igniter, success_notice)
else
warning_notice =
"⚠️ Could not automatically recompile PhoenixKit dependency. Output: #{String.slice(output, 0, 200)}"
Igniter.add_warning(igniter, warning_notice)
end
rescue
_ ->
warning_notice =
"⚠️ Could not automatically recompile PhoenixKit dependency. Please run: mix deps.compile phoenix_kit --force"
Igniter.add_warning(igniter, warning_notice)
end
end
# Phoenix v1.8+ layout configuration - uses function components, no router-level config needed
defp add_modern_layout_config(igniter, layouts_module) do
igniter
|> Config.configure_new(
"config.exs",
:phoenix_kit,
[:layouts_module],
layouts_module
)
|> Config.configure_new(
"config.exs",
:phoenix_kit,
[:phoenix_version_strategy],
:modern
)
rescue
_ ->
add_layout_config_simple(igniter, layouts_module, :modern)
end
# Phoenix v1.7- legacy layout configuration
defp add_legacy_layout_config(igniter, layouts_module) do
igniter
|> Config.configure_new(
"config.exs",
:phoenix_kit,
[:layout],
{layouts_module, :app}
)
|> Config.configure_new(
"config.exs",
:phoenix_kit,
[:root_layout],
{layouts_module, :root}
)
|> Config.configure_new(
"config.exs",
:phoenix_kit,
[:phoenix_version_strategy],
:legacy
)
rescue
_ ->
add_layout_config_simple(igniter, layouts_module, :legacy)
end
# Simple file append for layout configuration when Igniter fails
defp add_layout_config_simple(igniter, layouts_module, strategy) do
layout_config =
case strategy do
:modern ->
"""
# PhoenixKit layout configuration (Phoenix v1.8+)
config :phoenix_kit,
layouts_module: #{inspect(layouts_module)},
phoenix_version_strategy: :modern
"""
:legacy ->
"""
# PhoenixKit layout configuration (Phoenix v1.7-)
config :phoenix_kit,
layout: {#{inspect(layouts_module)}, :app},
root_layout: {#{inspect(layouts_module)}, :root},
phoenix_version_strategy: :legacy
"""
end
try do
igniter =
Igniter.update_file(igniter, "config/config.exs", fn source ->
content = Rewrite.Source.get(source, :content)
# Check if already configured
if String.contains?(content, "config :phoenix_kit") &&
String.contains?(content, "layouts_module") do
source
else
# Find insertion point before import_config
updated_content =
case find_import_config_location_simple(content) do
{:before_import, before_content, after_content} ->
before_content <> layout_config <> "\n" <> after_content
:append_to_end ->
content <> layout_config
end
Rewrite.Source.update(source, :content, updated_content)
end
end)
igniter
rescue
e ->
IO.warn("Failed to configure layout automatically: #{inspect(e)}")
add_layout_config_manual_notice(igniter, layouts_module, strategy)
end
end
# Helper to find import_config location (simplified version)
defp find_import_config_location_simple(content) do
if String.contains?(content, "import_config") do
lines = String.split(content, "\n")
import_index =
Enum.find_index(lines, fn line ->
String.contains?(line, "import_config")
end)
case import_index do
nil ->
:append_to_end
index ->
# Find start of import block
start_index = max(0, index - 3)
before_lines = Enum.take(lines, start_index)
after_lines = Enum.drop(lines, start_index)
before_content = Enum.join(before_lines, "\n")
after_content = Enum.join(after_lines, "\n")
{:before_import, before_content, after_content}
end
else
:append_to_end
end
end
# Manual configuration notice for layout
defp add_layout_config_manual_notice(igniter, layouts_module, strategy) do
config_example =
case strategy do
:modern ->
"""
config :phoenix_kit,
layouts_module: #{inspect(layouts_module)},
phoenix_version_strategy: :modern
"""
:legacy ->
"""
config :phoenix_kit,
layout: {#{inspect(layouts_module)}, :app},
root_layout: {#{inspect(layouts_module)}, :root},
phoenix_version_strategy: :legacy
"""
end
notice = """
⚠️ Manual Layout Configuration Required
PhoenixKit couldn't automatically configure layouts.
Please add this to config/config.exs:
#{config_example}
"""
Igniter.add_notice(igniter, notice)
end
# Add version-aware comments to configuration
defp add_version_aware_comments(igniter, _layouts_module) do
# Simple notice that layout integration is configured
notice = "✅ Layout integration configured automatically"
igniter
|> Igniter.add_notice(notice)
end
end