Search code examples
episerver

Episerver create page programmatically


I am using this code

        var parent = ContentReference.StartPage;
        IContentRepository contentRepository = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IContentRepository>();

        PageData myPage = contentRepository.GetDefault<LoginPage>(parent);
        myPage.PageName = "My new page";

        var page = contentRepository.GetChildren<LoginPage>(parent).FirstOrDefault(name => name.Name == myPage.Name);

        if (page == null)
            contentRepository.Save(myPage, EPiServer.DataAccess.SaveAction.Publish);

to create a page programatically. The thing is I am not sure where to put this code?

I don't want to show LoginPage which is page type to show in the list in the admin/edit panel as I want to create only one page under that page type. Maybe there is another way where I can just create a stand alone page and don't have to create the page type or maybe use an already made page type.

This is the code for my page type

[ContentType(DisplayName = "Custom Login Page", GUID = "c0d358c3-4789-4e53-bef3-6ce20efecaeb", Description = "")]
public class LoginPage : StandardPage
{
    /*
            [CultureSpecific]
            [Display(
                Name = "Main body",
                Description = "The main body will be shown in the main content area of the page, using the XHTML-editor you can insert for example text, images and tables.",
                GroupName = SystemTabNames.Content,
                Order = 1)]
            public virtual XhtmlString MainBody { get; set; }
     */
}

Then I am creating a model like this

public class LoginModel : PageViewModel<LoginPage>
{
    public LoginFormPostbackData LoginPostbackData { get; set; } = new LoginFormPostbackData();
    public LoginModel(LoginPage currentPage)
        : base(currentPage)
    {
    }
    public string Message { get; set; }
}

public class LoginFormPostbackData
{
    public string Username { get; set; }
    public string Password { get; set; }
    public bool RememberMe { get; set; }
    public string ReturnUrl { get; set; }
}

And my controller looks like this

    public ActionResult Index(LoginPage currentPage, [FromUri]string ReturnUrl)
    {

        var model = new LoginModel(currentPage);
        model.LoginPostbackData.ReturnUrl = ReturnUrl;
        return View(model);
    }

Do you think there is another way to do it? I will also show my login view

@using EPiServer.Globalization
@model LoginModel

<h1 @Html.EditAttributes(x => 
x.CurrentPage.PageName)>@Model.CurrentPage.PageName</h1>
<p class="introduction" @Html.EditAttributes(x => 
x.CurrentPage.MetaDescription)>@Model.CurrentPage.MetaDescription</p>
<div class="row">
<div class="span8 clearfix" @Html.EditAttributes(x => 
x.CurrentPage.MainBody)>
    @Html.DisplayFor(m => m.CurrentPage.MainBody)

</div>

@if (!User.Identity.IsAuthenticated && 
!User.IsInRole("rystadEnergyCustomer"))
{
<div class="row">
    @using (Html.BeginForm("Post", null, new { language = ContentLanguage.PreferredCulture.Name }))
    {
        <div class="logo"></div>
        @Html.AntiForgeryToken()

        <h2 class="form-signin-heading">Log in</h2>
        @Html.LabelFor(m => m.LoginPostbackData.Username, new { @class = "sr-only" })
        @Html.TextBoxFor(m => m.LoginPostbackData.Username, new { @class = "form-control", autofocus = "autofocus" })

        @Html.LabelFor(m => m.LoginPostbackData.Password, new { @class = "sr-only" })
        @Html.PasswordFor(m => m.LoginPostbackData.Password, new { @class = "form-control" })
        <div class="checkbox">
            <label>
                @Html.CheckBoxFor(m => m.LoginPostbackData.RememberMe)
                @Html.DisplayNameFor(m => m.LoginPostbackData.RememberMe)
            </label>
        </div>

        @Html.HiddenFor(m => m.LoginPostbackData.ReturnUrl, "/login-customers")
        <input type="submit" value="Log in" class="btn btn-lg btn-primary btn-block" />
    }
    @Html.DisplayFor(m => m.Message)
</div>
}
else
{
<span>Welcome @User.Identity.Name</span>
@Html.ActionLink("Logout", "Logout", "LoginPage", null, null);
}

Solution

  • I think you're misunderstanding some of the Episerver concepts.

    If you don't want it to be a page in Episerver, you shouldn't use PageController, page types, or templates. Instead, just use a standard controller and view to create your login page.

    Otherwise, you do have to create a page of type LoginPage, which will be visible in the page tree. No need to create it programmatically, you can just add the page manually and then hide the LoginPage type from edit mode to avoid editors creating additional login pages.