StaticBuilder - Kirby as a static site generator

no, all pages with just the default language (de in my case) are skipped. if i never switch to “en” in the panel and save the page there, there will only one file: template.de.txt… and this is skipped by staticbuilder.

That’s strange.

Anyway, I changed the technique for trying to determine if a page has a content file or not. (The built-in methods in Kirby don’t seem to do that, or there is a bug.) It should be more reliable now.

2.1.0: https://github.com/fvsch/kirby-staticbuilder/releases/tag/v2.1.0

2 Likes

Now it works as expected! Only the module-templates are skipped. Great! <3

Thank you very much!

It seems like language strings get stripped:

<a href="http://example.com"><?php echo l::get('education-home'); ?></a>

Becomes

<a href="http://example.com"></a>

Any ideas?

@PaulMorel Looks like a bug.
I opened an issue, could you try the workaround mentioned in it?

1 Like

Hello,

how can i copy a special files to the static root? In my case: a special .htaccess file.
Is this possible with a config setting?

Another question: after exporting a static version of my site some background images are not visible.
I use the modules plugin and on the non static site it looks like this (working):

background-image: url(<?= $module->url().'/'.$module->bgimage(); ?>);

gives:

background-image: url(http://localhost/kirby/site/products/columns-ix4gsq/gilles-lambert-mobile-call-thin.jpg);

Exported it looks like this (not working):

background-image: url(./columns-ix4gsq/gilles-lambert-mobile-call-thin.jpg);

$module->bgimage() is a image field and i get the right file name if i echo this.
But how i get the URL working in the static version?

if i use (image:gilles-lambert-mobile-call-thin.jpg) in the module text the URL is correct:

<img src="http://localhost/kirby/site/content/3-products/9-columns-ix4gsq/gilles-lambert-mobile-call-thin.jpg" alt="">

How does the Image tag get the right URL? Can’t find it anywhere.

Any ideas?

S.

Yes, see the docs on GitHub.

In your case, it might look like:

c::set('staticbuilder.assets', [
    'assets' => 'assets',
    'thumbs' => 'thumbs',
    'site/static-template/favicon.ico' => 'favicon.ico',
    'site/static-template/.htaccess-template' => '.htaccess'
]);

(Just an example, the source paths can be anything you want, and the destination paths are the paths/filenames to use inside of the static folder.)

You should make sure that the image is available in the static build (the contents of the static folder should be self-sufficient), then provide a URL that works.

In this specific case, since the site folder is not copied to the static folder (and should not be!), even if the $module->url() resolved to something sensible (no idea why it doesn’t here), that would not be very helpful since you’re not copying the site directory or even the module’s directory (which probably contains some PHP you should not copy either).

If it’s just images, my recommendation would be to make thumbs of the image so they end up — even as a pure copy with no image processing — in the thumbs folder. Something like:

background-image: url("<?= $module->bgimage()->thumb()->url(); ?>");

If you have other resource you’re calling directly, be them JS or CSS or documents, I’m not sure what the right solutions would be. You can list specific files individually in the 'staticbuilder.assets', but if you have many it’s going to be tedious and not future-proof.

By the way, in this example I’m supposing that $module->bgimage() is an image object, but if it’s a field where you wrote the filename of an image, you probably need to do something like this:

<?php if ($image = $module->bgimage()->toFile()): ?>
  background-image: url("<?= $image->thumb()->url() ?>");
<?php endif ?>

thank you! helped a little bit but i have still issues with the url to thumbs:

I do not get a URL to the thumbs folder:

$myimage = new Asset($img);
thumb($myimage, array(), false);

gives always a URL like localhost/kirby/site/home/slider-a4xiyr/reflist-greentech.png. This works on the original site but fails after static export.

$myimage = new Asset($img);
$myimage->thumb()->url()

also does not give a URL to the thumbs folder.

S.

EDIT:

Now i got a link to the thumbs folder:

$myimage = new Asset($tag->file($img));
$myimage->thumb()->url()

but only if $img is a full path to the image like: home/slider-a4xiyr/reflist-alpenbank.gif
it seems this is due the path resolving issue in the actual kirby version.

Hello,

i use a route to get a link to my sitemap:

c::set('routes', array(
    /* https://github.com/getkirby/kirby/issues/93 */
    array(
        'pattern' => 'sitemap.xml',
        'action'  => function() {
            return site()->visit('sitemap');
        }
    ),
    array(
        'pattern' => 'sitemap',
        'action'  => function() {
            return go('sitemap.xml');
        }
    ),
));

Template:

<?php

$ignore = array('sitemap', 'error', 'search', 'demo');

// send the right header
header('Content-type: text/xml; charset="utf-8"');

// echo the doctype
echo '<?xml version="1.0" encoding="utf-8"?>';

?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <?php foreach($pages->index() as $p): ?>
  <?php if( in_array($p->uri(), $ignore) || substr( $p->intendedTemplate(), 0, 6 ) === 'module' ) continue ?>
  <url>
    <loc><?php echo html($p->url()) ?></loc>
    <lastmod><?php echo $p->modified('c') ?></lastmod>
    <priority><?php echo ($p->isHomePage()) ? 1 : number_format(0.5/$p->depth(), 1) ?></priority>
  </url>
  <?php endforeach ?>
</urlset>

Is there any way to generate the static sitemap.xml in the document root with the builder or do i need something self made (maybe in the deploy script)?

S.

Currently there is no support for routes, or for Kirby Content Representations (which are a bit similar to routes).

What you could do, though, is to rename your page from sitemap to sitemap.xml. Not sure if the Panel lets you do that, but on the filesystem side there should be no problem. For instance on a project I have a page whose folder is named searchdata.json, that’s not a problem at all.

The result will be that your page’s URL will already contain an extension, so StaticBuilder won’t try to add a .html extension (or /index.html if you’re using that). The resulting file will be static/sitemap.xml.

Note that Ui: Use Vue value model bindings (e.g. for radio, checkboxes) · Issue #93 · getkirby/kirby · GitHub says extensions in URLs don’t work, but in my experience they do and I made a project in 2016 – updated recently to latest stable Kirby – which uses that. Not sure what that issue is about. Maybe that the Panel doesn’t let you input a page slug with a dot or something like that. But if you create the page’s folder manually, nothing stops you from naming it sitemap.xml (just checked that).

Once you do that, remove your two routes (since they’re now irrelevant), and add a header function for your sitemap:

c::set('headers' [
  /* Executed for pages using the sitemap template, but ignored by StaticBuilder */
  'sitemap' => function() {
    header('Content-type: text/xml; charset="utf-8"');
  }
]);

And remove the corresponding header(...) line from your template, because it could break the static build.

For the record, this is documented here: Best practices for static sites.

1 Like

Whow! It works and i have a static sitemap.xml now.

Thanks a lot!

S.

Hello,

is it possible to load a different config file for the static export?
The dynamic page runs at localhost but must be ready for https://www.mydomain.com/ after export.

any ideas?

S.

Isn’t this handled by default?
See: Kirby StaticBuilder options > Hosting on a domain or subdomain.

With default settings your page URLs should look like this in the HTML:

<a href="/some/page">Some Page</a>

If you configure the MultiViews option (for Apache, or a similar option for other webserver software) you should get the some/page.html file.

But if you want to have the full domain in the HTML attributes for some reason, you can always declare your base URL explicitely:

c::set('staticbuilder.baseurl' => 'https://www.mydomain.com/');

This will prevent you from checking that your site is built correctly by navigating between pages in your local static folder, though, since each link will send you to the live website.

Of course this does the trick.

But my usecase here is a little tricky: i have to export the site to something like a stating/testing server without the final URL but the URL of the testing server. After that the static site should be deployed to a live server.

Anyway…just ‘loud thinking’ by me.
It seems this is something you can’t solve in your plugin. so no problem… for you.

Thank you for the great plugin!

S.

Doesn’t c::set('staticbuilder.baseurl' => '/'); (the default) work for both the staging and the production servers?

Yes, removing c::set('url... and set c::set('staticbuilder.baseurl' => '/'); seems to do the trick.
Thanks a lot!

S.

@fvsch: Is it possible to check (on a template/module…) if a static export is running?
Or start a static export as a not logged in user? I have some frontend snippets only
visible to editors. They should not be exported to static.

S.

@fvsch:
I have tested the new version. Thank you, it runs very good, after I have added to the working config.php:

c::set('staticbuilder.filter', function($page){
    if ($page->isVisible()) {
        return true;
    } else {
        return [false, "Invisible page '$page' excluded from static build"];
    }
});


But how can I avoid to copy the *.txt and *.md files within the /content directory to the static files?

Yep: https://github.com/fvsch/kirby-staticbuilder/blob/master/doc/static.md#knowing-when-were-rendering-a-static-page
(One person has reported that it doesn’t work for them, but in my tests it always worked. :stuck_out_tongue:)

1 Like

You can decide to not copy the content directory:

c::set('staticbuilder.assets', ['assets', 'thumbs']);

But if you’re referencing files from the content folder directly in your HTML, for example if you have some pages that output <img src="/content/2-my-page/1-sub-page/cool-image.jpg" alt="…">, not copying the content folder is going to be an issue.

StaticBuilder does not include an option to only copy images from the content folder because Kirby pages can have all sorts of associated files that are referenced publicly in the HTML, in any format: image, PDF, SVG, audio or video, and even plain text.

Alternatively, you could use the withfiles option, but note that files will be copied to a different location than the URL produced by the (image: …) KirbyText syntax (or $file->url()), so this only works for files you’re linking to yourself using HTML or Markdown syntax (for example: <img src="cool-image.jpg" alt="…">).