Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example usage #6

Open
dk-ok opened this issue Mar 23, 2023 · 3 comments
Open

Example usage #6

dk-ok opened this issue Mar 23, 2023 · 3 comments
Labels
question Further information is requested

Comments

@dk-ok
Copy link

dk-ok commented Mar 23, 2023

Hi. It would be nice to have an example project available that demonstrates usage exactly for a RazorWeb or MvcWeb template app using top-level statements in an app with a Program.cs entry point.

I'm unable to see the module in action by my best efforts. I would like to host a sort of flat-file CMS and this module seems to indicate it can be done with Piranha.

Per the instructions, I've copied the Piranha docs to Content/help.

and set up

var builder = WebApplication.CreateBuilder(args);
builder.AddPiranha(options => { ... });

builder.Services.AddStatica(
	new Statica.Models.StaticStructure {
		Id = "help",
		DataPath = Path.Combine("Content, "help", "src"),
		BaseSlug = "help",
		UseAssets = true
	});

var app = builder.Build();

if (app.Environment.IsDevelopment()) {
	app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
app.UseStatica(app.Environment);

app.UsePiranha(options => { ... });

app.Run();

Navigating to localhost/help/basics/what-is-piranha ought to get me to the first page, I thought. 404 instead.
I am able to fetch /help/_assets/modules-list.png which proves the StaticFileProvider is correctly mapped on the _assets folder by StaticaExtensions.UseStatica().

If you have no idea, perhaps you can point me in the direction where in Piranha the module intercepts an http request to provide content as I've been unable to discern that as well. I'm a newbie with Piranha. I see StructureService.GetPageAsync but it is not ever called.

As a side note, the lib needs publishing to nuget to be compatible with Piranha 10.3. Statica 2.0 will not load (compiled against P 10.0) - type load exception.

Thanks!

@tidyui
Copy link
Owner

tidyui commented Mar 23, 2023

The problem is most likely not your setup as this looks correct, it's rather that you don't have anything that handles the routing/rendering for it. Static only loads the structure and serves the content through an API, it doesn't do any rendering or routing. On PiranhaCMS.org I have the following razor page that handles all requests for the docs.

Docs.cshtml

@page "/docs/{**slug}"
@model DocsPageModel
@inject Statica.Services.IStaticaService Statica
@{
    ViewData["Title"] = Model.StaticPage != null ? Model.StaticPage.Title : "Not Found";
    ViewData["StaticSlug"] = Model.StaticPage?.Slug;

    var structures = Statica.GetStructures();
}

<div>
   ...
   @Html.Raw(Model.StaticPage.Body)
   ...
</div>

Docs.cshtml.cs

public class DocsPageModel : PageModel
{
    private readonly IStaticaService _service;

    public string StaticId { get; set; }
    public StaticSitemap StaticSitemap { get; set; }
    public StaticPageModel StaticPage { get; set; }
    public string Slug { get; set; }

    public DocsPageModel(IStaticaService service)
    {
        _service = service;
    }

    public async Task<IActionResult> OnGetAsync(Guid id, string slug)
    {
        string[] segments = new string[0];

        if (!string.IsNullOrEmpty(slug))
        {
            segments = slug.Split("/", options: StringSplitOptions.RemoveEmptyEntries);
        }

        var structure = segments.Length > 0 ?
            _service.GetStructure(segments[0]) :
            _service.GetStructure("master");

        if (structure != null)
        {
            StaticId = structure.Id;
            StaticSitemap = structure.Sitemap;

            if (segments.Length > 1)
            {
                Slug = string.Join("/", segments.Subset(1));
                StaticPage = await structure.GetPageAsync(Slug);

                if (StaticPage != null && !string.IsNullOrWhiteSpace(StaticPage.Redirect))
                {
                    return Redirect($"~/{ StaticPage.Redirect }");
                }
            }
        }
        return Page();
    }
}

Please note that the backing PageModel is a bit more advanced than it needs to be in your case, simply because we host multiple versions/branches of the documentation on the site, and the first segment in the URL tells which one of the structures that should be loaded.

Best regards

@tidyui tidyui added the question Further information is requested label Mar 23, 2023
@dk-ok
Copy link
Author

dk-ok commented Apr 1, 2023

Thank you very kindly. Tells me about all I need to know about Piranha. Will need some effort to integrate a flat-file datasource. For the record, to generate a menu, I used the following (it's a start):

Pages/Menus/SitemapMenu.cshtml:

@using Statica.Models;
@model IList<StaticPage>
@{
	string activeSlug = ViewData["StaticSlug"] as string  ?? String.Empty;
	string getClasses(StaticPage pg) {
		if (pg.Items != null && pg.Items.Count > 0) {
			if (activeSlug.StartsWith(pg.Slug))
				return "folder expanded";
			return "folder";
		}
		if (pg.Slug == activeSlug)
			return "active";
		return "";
	}

}
<ul class="navbar-nav">
	@foreach (StaticPage sp in Model) {
		<li class="nav-item @getClasses(sp)">
			@if (sp.Items.Count > 0) {
				<a href="#" class="folder-toggle expand"><i class="fas fa-chevron-right"></i></a>
				<a href="#" class="folder-toggle collapse"><i class="fas fa-chevron-down"></i></a>				
			}
			<a href="~/@sp.Slug" class="nav-link">@sp.Title</a>
			@if (sp.Items.Count > 0) {
				await Html.RenderPartialAsync("Menus/SitemapMenu", sp.Items, ViewData);
			}
		</li>
	}
</ul>

and included it into Docs.cshtml as:

<div class="col-lg-3 pt-4 sub-nav">
			<nav class="navbar">
				<button class="btn btn-sm btn-light d-lg-none mb-3 subnav-toggle"><i class="fas fa-times"></i> Close</button>  
				@await Html.PartialAsync("Menus/SitemapMenu", Model.Sitemap.Items, ViewData)
			</nav>
		</div>

For correct nav use (copied from Piranha site):

@section EndScripts {
<script>
		$(document).on("click", ".folder-toggle", function () {
				$(this).parent().toggleClass("expanded");
				return false;
		});

		$(document).on("click", ".subnav-toggle, .blocker", function () {
				$(".sub-nav").toggleClass("active");
		});
</script>

Add EndScript section to _layout in order to take advantage of jquery.

@dk-ok
Copy link
Author

dk-ok commented Apr 1, 2023

How do you get that nice colored syntax highlight in git? Must be easy to include :)
Secret has been revealed....

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants