module IHP.IDE.CodeGen.ApplicationGenerator (buildPlan) where
import IHP.Prelude
import IHP.IDE.CodeGen.Types
buildPlan :: Text -> IO (Either Text [GeneratorAction])
buildPlan applicationName =
if (null applicationName)
then do
pure $ Left "Application name cannot be empty"
else do
let applicationName' = ucfirst applicationName
pure $ Right $ generateGenericApplication applicationName'
generateGenericApplication :: Text -> [GeneratorAction]
generateGenericApplication applicationName =
let
typesHs =
"module " <> applicationName <> ".Types where\n\n"
<> "import IHP.Prelude\n"
<> "import IHP.ModelSupport\n"
<> "import Generated.Types\n\n"
<> "data " <> applicationName <> "Application = " <> applicationName <> "Application deriving (Eq, Show)\n\n"
<> "\n"
<> "data StaticController = WelcomeAction deriving (Eq, Show, Data)"
<> "\n"
routesHs =
"module " <> applicationName <> ".Routes where\n"
<> "import IHP.RouterPrelude\n"
<> "import Generated.Types\n"
<> "import " <> applicationName <> ".Types\n\n"
<> "-- Generator Marker\n"
<> "instance AutoRoute StaticController"
frontControllerHs =
"module " <> applicationName <> ".FrontController where\n\n"
<> "import IHP.RouterPrelude\n"
<> "import " <> applicationName <> ".Controller.Prelude\n"
<> "import " <> applicationName <> ".View.Layout (defaultLayout)\n\n"
<> "-- Controller Imports\n"
<> "import " <> applicationName <> ".Controller.Static\n\n"
<> "instance FrontController " <> applicationName <> "Application where\n"
<> " controllers = \n"
<> " [ startPage WelcomeAction\n"
<> " -- Generator Marker\n"
<> " ]\n\n"
<> "instance InitControllerContext " <> applicationName <> "Application where\n"
<> " initContext = do\n"
<> " setLayout defaultLayout\n"
<> " initAutoRefresh\n"
controllerPreludeHs =
"module " <> applicationName <> ".Controller.Prelude\n"
<> "( module " <> applicationName <> ".Types\n"
<> ", module Application.Helper.Controller\n"
<> ", module IHP.ControllerPrelude\n"
<> ", module Generated.Types\n"
<> ")\n"
<> "where\n\n"
<> "import " <> applicationName <> ".Types\n"
<> "import Application.Helper.Controller\n"
<> "import IHP.ControllerPrelude\n"
<> "import Generated.Types\n"
<> "import " <> applicationName <> ".Routes\n"
viewLayoutHs =
"module " <> applicationName <> ".View.Layout (defaultLayout, Html) where\n"
<> "\n"
<> "import IHP.ViewPrelude\n"
<> "import IHP.Environment\n"
<> "import Generated.Types\n"
<> "import IHP.Controller.RequestContext\n"
<> "import " <> applicationName <> ".Types\n"
<> "import " <> applicationName <> ".Routes\n"
<> "import Application.Helper.View\n"
<> "\n"
<> "defaultLayout :: Html -> Html\n"
<> "defaultLayout inner = [hsx|\n"
<> "\n"
<> "\n"
<> "
\n"
<> " {metaTags}\n"
<> "\n"
<> " {stylesheets}\n"
<> " {scripts}\n"
<> "\n"
<> " {pageTitleOrDefault \"App\"}\n"
<> " \n"
<> " \n"
<> " \n"
<> " {renderFlashMessages}\n"
<> " {inner}\n"
<> "
\n"
<> " \n"
<> "\n"
<> "|]\n"
<> "\n"
<> "-- The 'assetPath' function used below appends a `?v=SOME_VERSION` to the static assets in production\n"
<> "-- This is useful to avoid users having old CSS and JS files in their browser cache once a new version is deployed\n"
<> "-- See https://ihp.digitallyinduced.com/Guide/assets.html for more details\n"
<> "\n"
<> "stylesheets :: Html\n"
<> "stylesheets = [hsx|\n"
<> " \n"
<> " \n"
<> " \n"
<> " |]\n"
<> "\n"
<> "scripts :: Html\n"
<> "scripts = [hsx|\n"
<> " {when isDevelopment devScripts}\n"
<> " \n"
<> " \n"
<> " \n"
<> " \n"
<> " \n"
<> " \n"
<> " \n"
<> " \n"
<> " \n"
<> " \n"
<> " \n"
<> " \n"
<> " |]\n"
<> "\n"
<> "devScripts :: Html\n"
<> "devScripts = [hsx|\n"
<> " \n"
<> " |]\n"
<> "\n"
<> "metaTags :: Html\n"
<> "metaTags = [hsx|\n"
<> " \n"
<> " \n"
<> " \n"
<> " \n"
<> " \n"
<> " \n"
<> " {autoRefreshMeta}\n"
<> "|]\n"
viewPreludeHs =
"module " <> applicationName <> ".View.Prelude\n"
<> "( module IHP.ViewPrelude\n"
<> ", module " <> applicationName <> ".View.Layout\n"
<> ", module Generated.Types\n"
<> ", module " <> applicationName <> ".Types\n"
<> ", module Application.Helper.View\n"
<> ") where\n"
<> "\n"
<> "import IHP.ViewPrelude\n"
<> "import " <> applicationName <> ".View.Layout\n"
<> "import Generated.Types\n"
<> "import " <> applicationName <> ".Types\n"
<> "import " <> applicationName <> ".Routes ()\n"
<> "import Application.Helper.View\n"
welcomeControllerStaticHs =
"module " <> applicationName <> ".Controller.Static where\n"
<> "import " <> applicationName <>".Controller.Prelude\n"
<> "import " <> applicationName <>".View.Static.Welcome\n"
<> "\n"
<> "instance Controller StaticController where\n"
<> " action WelcomeAction = render WelcomeView\n"
welcomeViewStaticHs =
"module " <> applicationName <> ".View.Static.Welcome where\n"
<>"import " <> applicationName <> ".View.Prelude\n"
<>"\n"
<>"data WelcomeView = WelcomeView\n"
<>"\n"
<>"instance View WelcomeView where\n"
<>" html WelcomeView = [hsx|\n"
<>" \n"
<>"\n"
<>" \n"
<>"

\n"
<>"
\n"
<>" You can modify this start page by making changes to \"./Web/View/Static/Welcome.hs\".\n"
<>"
\n"
<>"
\n"
<>"|]"
in
[ EnsureDirectory { directory = applicationName }
, EnsureDirectory { directory = applicationName <> "/Controller" }
, EnsureDirectory { directory = applicationName <> "/View" }
, EnsureDirectory { directory = applicationName <> "/View/Static" }
, AddImport { filePath = "Main.hs", fileContent = "import " <> applicationName <> ".FrontController" }
, AddImport { filePath = "Main.hs", fileContent = "import " <> applicationName <> ".Types" }
, AddMountToFrontController { filePath = "Main.hs", applicationName = applicationName }
, CreateFile { filePath = applicationName <> "/Types.hs", fileContent = typesHs }
, CreateFile { filePath = applicationName <> "/Routes.hs", fileContent = routesHs }
, CreateFile { filePath = applicationName <> "/FrontController.hs", fileContent = frontControllerHs }
, CreateFile { filePath = applicationName <> "/Controller/Prelude.hs", fileContent = controllerPreludeHs }
, CreateFile { filePath = applicationName <> "/View/Layout.hs", fileContent = viewLayoutHs }
, CreateFile { filePath = applicationName <> "/View/Prelude.hs", fileContent = viewPreludeHs }
, CreateFile { filePath = applicationName <> "/Controller/Static.hs", fileContent = welcomeControllerStaticHs }
, CreateFile { filePath = applicationName <> "/View/Static/Welcome.hs", fileContent = welcomeViewStaticHs }
]