d4l-data4life / kirby3-static-site-generator

Static site generator plugin for Kirby 3+. With this plugin you can create a directory with assets, media and static html files generated from your pages. The result is an even faster site with less potential vulnerabilities.
MIT License
134 stars 8 forks source link

Tags and blog-pages #64

Closed Anjade closed 1 year ago

Anjade commented 1 year ago

Is there a way to produce the static blog-pages for tags and the following pages with articles on it?

Now i have only the first page of my blog. All tags leads to /news/tag:tag-name and the pages leads to /api/generate-static-siteo/page:2

Anjade commented 1 year ago

You may give an example to use routes and filters for the Kirby CMS demo, please? It seems there is less interest to support your addon at other sites. Many people talk about, but i am not shure if they ever tried it, because to show how to use routes and filters for blog-pages and tags should be a really interesting theme for all these SEO-people talking about your add-on.

Anjade commented 1 year ago

One more time, sorry:

To make something static, we need to know:

What we should watch to make it static? What is the static page we want to produce?

=>

/notes/page:2 should be transformed to /notes/page2/index..html

but how it do that with path and page? path is the result, page is the thing we want to use for the static page?

Wih real world data in the examples (for the kirby demo), this would be clear, i guess.

Now i tried a lot of combinations to make notes/page:2 to something like /notes/2/index.html, bit i fail.

jonathan-reisdorf commented 1 year ago

Hello @Anjade, thank you for your messages, if I understand it correctly, you are doing something similiar to this Kirby cookbook recipe where you make use of Kirby's query params feature to paginate through and/or filter collections.

While query params are not natively supported by the static site generator plugin, you can achieve the desired behavior by adding a route specifically for the static site generator and connecting it to custom routes when generating the static site.

Example config.php:

<?php

return [
    'routes' => [
        [
            'pattern' => 'ssg/(:all)/(:any):(:any)',
            'action' => function ($pageId, $param, $value) {
                kirby()->request()->url()->params()->$param = $value;
                return page($pageId)->render();
            }
        ],
    ],
    'd4l' => [
        'static_site_generator' => [
            'endpoint' => 'generate-static-site',
            'custom_routes' => [
                [
                    'path' => 'notes/2',
                    'route' => 'ssg/notes/page:2',
                ],
                [
                    'path' => 'notes/3',
                    'route' => 'ssg/notes/page:3',
                ],
                [
                    'path' => 'news/tag-name',
                    'route' => 'ssg/news/tag:tag-name',
                ],
            ]
        ]
    ]
];

In the next step, of course you do not want to manually enter every page as a custom route but instead dynamically generate these custom routes. I will post an example of how to achieve that in a few minutes. Since it is possible that these manually set params are accidentally transferred over to the next rendered page (as all are rendered in a row), you might also want to reset the param after using it for rendering. I will include that in the next example as well.

jonathan-reisdorf commented 1 year ago

Here is the aforementioned example for dynamically generating the custom routes. I tested it using the starterkit, hence the use of photography/trees in the custom routes. Kirby has a ready option which allows you to add config options even after it's bootstrapped, giving you the option to use $kirby, page() etc. inside the config:

<?php

return [
    'routes' => [
        [
            'pattern' => 'ssg/(:all)/(:any):(:any)',
            'action' => function ($pageId, $param, $value) {
                $params = kirby()->request()->url()->params();
                $params->$param = $value;
                $html = page($pageId)->render();
                $params->$param = null; // reset the param after rendering the page
                return $html;
            }
        ],
    ],
    'd4l' => [
        'static_site_generator' => [
            'endpoint' => 'generate-static-site'
        ]
    ],
    'ready' => function ($kirby) {
        $pagesCount = 7; // add your code to calculate the number of pages
        $pageNumbers = range(2, $pagesCount); // [2, 3, 4, 5, 6, 7] - I assume that for page 1 you want to use the main URL of the page
        return [
            'd4l.static_site_generator.custom_routes' => array_map(function($pageNumber) {
                return [
                    'path' => "photography/trees/$pageNumber",
                    'route' => "ssg/photography/trees/page:$pageNumber",
                ];
            }, $pageNumbers)
        ];
    }
];

Let me know if that works for you :) If that is a common use case as you said it may also make sense to add concrete usage examples into the readme or into an examples folder. Otherwise you can also add custom routes with page instead of route and pass the page number as data to achieve the same result without the ssg route. You'd then only have to tweak your template accordingly.

jonathan-reisdorf commented 1 year ago

I consider this issue solved but let me know if it works and in case it doesn't, I'll reopen this.

jonathan-reisdorf commented 1 year ago

Reopened due to the number of issues opened by you indicating that there may still be things left to resolve. Please explain with as many details as possible or ideally with the full config code where you are still encountering issues. Thanks

Anjade commented 1 year ago

There are many typical scenarios, where a working example would be a great deal for all users, i guess.

The maximal scenario that i could not solve in all parts is that:

  1. Two languages

  2. Blog-Pages

  3. Tags

  4. Linking every single page to just that page in the other language

  5. Two languages and linking could be solved by a config like this:

` 'routes' => [ [ 'pattern' => '(:all)/(:any):(:num)', 'action' => function ($pageId, $param, $value) { $params = kirby()->request()->url()->params();
$params->$param = $value; $html = page($pageId)->render(); $params->$param = null; // reset the param after rendering the page return $html; } ],
],

'd4l' => [ 'static_site_generator' => [ 'endpoint' => 'generate-static-site' ] ],

'ready' => function ($kirby) {

  $notePerPage = 2; // change!
  $pagesCount = page('notes')->children()->listed()->count();

  $pageNumbers = intval($pagesCount/$notePerPage);

  if (($pagesCount % $notePerPage) != 0)
  {
    $pageNumbers++;
  }

  for ($i = 2; $i <= $pageNumbers; $i++)
  {        
    $myRoutes[] = [
      'path' => "en/notes/$i",
      'route' => "notes/page:$i",
      'languageCode' => 'de',
    ];
    $myRoutes[] = [
      'path' => "de/notes/$i",
      'route' => "notes/page:$i",
      'languageCode' => 'en',
    ];

  }  

  return [
      'd4l.static_site_generator.custom_routes' => $myRoutes
  ];

},`

If you watch that closer, you will see something strange here:

$myRoutes[] = [ 'path' => "en/notes/$i", 'route' => "notes/page:$i", 'languageCode' => 'de', ]; $myRoutes[] = [ 'path' => "de/notes/$i", 'route' => "notes/page:$i", 'languageCode' => 'en', ];

I dont know why, but this is the only way to make my pages like they should be. If i change the languageCode i got mixed content in the blog and wrong data in the header here:

<!DOCTYPE html>

The german pages (form blog/page:2 have html lang=en and vice versa. This means that also the articles are fetched in the wrong language. Also it was not possible for me to use the typical linking for pagination. I had to rewrite this like this: ` pagination(); $pageNumber = $pagination->page(); if ($pagination->hasPages()): $prevUrl = "/" . t('lang') . "/notes"; if ($pageNumber > '2') { $prevUrl .= "/page:" . $pageNumber-1; }; ?>` ... ` hasPrevPage()): ?>
` If i try to use: $pagination->prevPageUrl() $pagination->nextPageUrl() the links are broken with something like "api/generate-static-site" To link pages i use something like this: ` // for all normal pages " hreflang="de"> " hreflang="en"> ` I could not solve to build tag-pages and link them by language. For this i made a new field in blog.yml with pairs like: hund/dog katze/cat With this list and using arrays i could connect from de/blog/tag/hund to en/blog/tag/dog in Kirby, i also was somehow able to produce these pages, but not to do the linking in the static pages. If you agree, i can do the following: i will setup a minimal kirby with these things: 1. two languages 2. blog with articles linked to each other 3. tags with a pair-list for linking and a tag-cloud for both languages 4. linking for every single page Then we try to solve this and document what we have done for these pages, so everybody could see a real world solution. If this is ok for you, i will setup such a page in the next days on a domaine xyz open for everybody.
Anjade commented 1 year ago

Sorry, i dont know to add the code without the problems above. Better you try the ftp, i will send soon.

Anjade commented 1 year ago

Can be deleted while the problem is described shoter here: https://github.com/d4l-data4life/kirby3-static-site-generator/issues/72

jonathan-reisdorf commented 1 year ago

There are many typical scenarios, where a working example would be a great deal for all users, i guess

A static site generator can be used to create all kinds of websites but also completely other things such as static APIs, news feeds etc. - there are no typical scenarios when it comes to such a plugin. The good thing about this being open-source is that everyone can and is encouraged to contribute. So far within the almost 4 years this plugin exists, no one has reported an issue similiar to your problem, but then again we also just recently added support for custom routes anyway. I will have a look at your issues this week as soon as I find some time.