Download
We're evolving to serve you better! This current forum has transitioned to read-only mode. For new discussions, support, and engagement, we've moved to GitHub Discussions.

Folder structure

  • #6064
    Avatar photo[anonymous]

    Hi guys, I’ve been using Publii for about a year now and really love the product and the philosophy behind it. I can also see myself financially supporting Publii in the future.

    As someone who uses a hodge-podge of approaches with all my hosted sites, some hand-coded HTML, some WordPress, and some Publii, I frequently explore and work directly with my cPanel directory and have noticed that Publii’s structure is really unwieldy. I know this isn’t much of a concern for most people, but has cleaning it up or better organizing it ever come up as something to be addressed in the future?

    I know others have asked if there will ever be a distinction made between pages functionally used as pages, and others functionally used as blog posts, and I think this would be a great opportunity for that; for instance, a page checked off as a “page” could be listed as-is in the file structure, while a page checked off as a “blog post” could be tucked away under a date stamped folder, organized by year or something. (The granularity perhaps decided by the user, if they wanted just year demarcations or something more detailed like year/month/day.)

    So instead of potentially 100s of alphabetically listed page-folders, you could have an hierarchy that is much easier to navigate at first glance.

    #6079
    Avatar photoBob

    The folder structure is strictly related to the pretty URLs, your suggestion would change the way Publii generates posts slug.
    We’re not planning to change this at the moment as it is optimal from an SEO point of view.

    #6153
    Avatar photo[anonymous]

    I’ve been thinking about this today. While I’m fine with the URL structure for my personal site, it’s rather small, I’d like to convert my business site too.

    That site has 1000s of posts and pages, if much rather be able to organize them even a little. Maybe by tag, then “post-title”.html, maybe many different configuration options.

    is there a technical reason this can’t be added, or a low priority. What is ideal fir SEO today may be very different tomorrow.

    Thanks, JM

    #6154
    Avatar photo[anonymous]

    I like the pretty URL and see that as the most appealing for the visitors, that do not know that it is only a few pages or 1000s of pages, so places keep that as the default 🙂

    But of the topic. Yes to could make a hierarchy of the pages for search engines. Like how you see in the image. All the url are <domain>/topic/<title>  but are shown as <domain>/<categories>/<title>. Her google is probably using the json-ld/breadcrumb, I don’t know if they could use other sources for generating that, but if not could we get a breadcrumb generator 🙂 <domain>/<main-tag>/<title> would be very nice 🙂

    Skjermbilde-2021-08-11-kl.-01.21.08

    <domain>/<main-tag>/<title>   For normal post?

    <domain>/<menu top level>/<menu secound level>/…/<title> For post used in a menu?

    #6158
    Avatar photo[anonymous]

    Made a helper that generates a breadcrumb 🙂 where the tags are used for categories the page. Following the instruction to google https://developers.google.com/search/docs/advanced/structured-data/breadcrumb and generates one breadcrumb per tag.

    module.exports = function (Handlebars) {
        return {
      
      // Helper that generates breadcrumb based on the tags.	
      breadcrumb: function(post) {
          
        let jsonLDObjectArray = [];
        
        // breadcrumb header
        let breadcrumbObject = {};
        breadcrumbObject['@context'] = 'https://schema.org';
        breadcrumbObject['@type'] = 'BreadcrumbList';
        breadcrumbObject['itemListElement'] = [];
        
        // this, the post page
        let thisPage = {};
        thisPage['@type'] = 'ListItem';
        thisPage['position'] = 2;
        thisPage['name'] = post.title;
        thisPage['item'] = post.url;
        
        if (post.tags.length > 0) {
        
          // generate one breadcrumb for each tag
          for (tagIndex in post.tags) {
            
            // the tag page
            let tagPage = {};
            tagPage['@type'] = 'ListItem';
            tagPage['position'] = 1;
            tagPage['name'] = post.tags[tagIndex].name;
            tagPage['item'] = post.tags[tagIndex].url;
            
            let breadcrumbObjectCopy = JSON.parse(JSON.stringify(breadcrumbObject));
            breadcrumbObjectCopy['itemListElement'].push(tagPage);
            breadcrumbObjectCopy['itemListElement'].push(thisPage);
            jsonLDObjectArray.push(breadcrumbObjectCopy);
            
          }
        
        } else {
          
          // if no tag put only this post in the breadcrumb.
          thisPage['position'] = 1;
          breadcrumbObject['itemListElement'].push(thisPage);
          jsonLDObjectArray.push(breadcrumbObject);
          
        }
        
        var output = "<script type='application/ld+json'>";
        output += JSON.stringify(jsonLDObjectArray);
        output += "</script>";
        
        return new Handlebars.SafeString(output);
      }		
        };
    };
    
    
    //////////////////////////////////////////////////////////////////////
    
    // in header.hbs
    
    <head>
    
            {{#is 'post'}}
        {{#post}}
          {{breadcrumb this}}
        {{/post}}
      {{/is}}
    
    </head>
    
    
    // in config.json
    
      "renderer": {
                   ...
                   "includeHandlebarsInHelpers": true,
    
    
    
    //////////// Output::::
    
    // post with no tag.
    
    <script type="application/ld+json">
        [{
            "@context": "https://schema.org",
            "@type": "BreadcrumbList",
            "itemListElement": [{
                "@type": "ListItem",
                "position": 1,
                "name": "Need some images for testing",
                "item": "file:////Users/t/Publii/sites/publiitest/preview/need-some-images-for-testing.html"
            }]
        }]
    </script>
    
    // post with two tags.
    
    <script type="application/ld+json">
        [{
            "@context": "https://schema.org",
            "@type": "BreadcrumbList",
            "itemListElement": [{
                "@type": "ListItem",
                "position": 1,
                "name": "Background",
                "item": "file:////Users/t/Publii/sites/publiitest/preview/tags/background/index.html"
            }, {
                "@type": "ListItem",
                "position": 2,
                "name": "Fixed background image",
                "item": "file:////Users/t/Publii/sites/publiitest/preview/fixed-background-image.html"
            }]
        }, {
            "@context": "https://schema.org",
            "@type": "BreadcrumbList",
            "itemListElement": [{
                "@type": "ListItem",
                "position": 1,
                "name": "Git",
                "item": "file:////Users/t/Publii/sites/publiitest/preview/tags/git/index.html"
            }, {
                "@type": "ListItem",
                "position": 2,
                "name": "Fixed background image",
                "item": "file:////Users/t/Publii/sites/publiitest/preview/fixed-background-image.html"
            }]
        }]
    </script>

    Have not found out how to get the menu data, and if there is possible to make a helper that makes a breadcrumbs based on the menu hierarchy.

    If someone want to use this or edit it, then just do it 🙂

    Edit: and this is also based on https://github.com/GetPublii/Publii/blob/master/app/back-end/modules/render-html/handlebars/helpers/json-ld.js 🙂

    #6159
    Avatar photo[anonymous]

    Sorry to repost, but the indents disappeared :/

    Edit: there they where back, so bug in the forum :/ but den this post can be deleted.