Override site title for specific page(s)

Hi!

How can I override the site title only for specific pages?

For example, I want my blog posts to be ‘$page.title - $site.title’. I can set title to $site.title.prefix($page.title, ' - ') in templates/layouts/base.shtml, but that does it for my whole site.

I tried following the “Extending templates” section at SuperHTML Basics - Zine , but everything I tried either didn’t take, or made zine segfault.

(I’m on 0.12.0)

You need getOr():

<title :text="$page.custom.getOr('custom_title', $site.title.prefix($page.title, ' - '))"></title>

Then in the corresponding page frontmatter:

---
.custom = {
	"custom_title" : "Something Funny",
}
---

If you would like a custom title for every page other than the home page then you would need to use something like this:

<ctx :if="$site.page('').isCurrent()">
    <title :text="$site.title"></title>
</ctx>
<ctx :if="$site.page('').isCurrent().not()">
    <title :text="$site.title.prefix($page.title, ' - ')"></title>
</ctx>
1 Like

thanks! That second snippet got me there.

This is what I have now

<ctx :if="$site.page('').isCurrent().or($site.page('about').isCurrent())">
    <title :text="$site.title"></title>
</ctx>
<ctx :if="$site.page('').isCurrent().and($site.page('about').isCurrent()).not()">
    <title :text="$site.title.prefix($page.title, ' - ')"></title>
</ctx>

This gets rid of the prefix on ‘about’ as well. I’m okay with this, but I’m wondering if there’s a nicer way of writing that logic.

No problem. I have looked around previously and now too, but I haven’t found a cleaner way.

This seems a problem to me better solved via template extension.

If it makes sense for those page groups to have different templates, then all you have to make sure to do is to make it so that each of their template gets to personalize the title as they require.

base.shtml:

<title id="title"><super></title>

blog-post.shtml:

<title id="title" :text="$page.title.suffix(' - ', $site.title)"></title>

index.shtml (and also maybe about.shtml or they could share the same template):

<title id="title" :text="$site.title"></title>

I just tried locally and this works (I believe it’s also covered by the test suite).

If you have found a way to crash Zine by editing templates, I’m very interested in a reproductible bug report!

When it happens please push to a repository (or zip the files) and share it with me in a GitHub Issue.

Also note that if you’re building Zine yourself from source, a debug build will always end with a stack trace when a build fails, so you will see one independently whether it’s a crash or not.

This seems a problem to me better solved via template extension.

If it makes sense for those page groups to have different templates, then all you have to make sure to do is to make it so that each of their template gets to personalize the title as they require.

This is kind of what I tried to do at first.

Unfortunately, I can’t figure out how to make your suggestion work. I keep getting this error:

---------- MISSING TOP-LEVEL BLOCK ----------
A template that extends another must have a
top-level element (called 'block' in Zine) for
each <super> element in the template being
extended.

Each block must match both 'id' and tag name of
the element that contains <super> in the template
being extended.

[missing_block]
(blog.shtml) layouts:
        <body id="body"></body>
        <head id="head"></head>


note: extended block defined here:
(base.shtml) layouts/templates/base.shtml:6:13:
    <title id="title"><super></title>
               ^^^^^

note: extended template super tag:
(base.shtml) layouts/templates/base.shtml:6:21:
    <title id="title"><super></title>
                       ^^^^^

Extended template interface (base.shtml):
        <title id="title"></title>
        <head id="head"></head>
        <body id="body"></body>
trace:
    layout `blog.shtml`,
    content `content/blog/index.smd`.

My layouts/templates/base.shtml (attaching the full head for context):

	<head id="head">
		<meta charset="utf-8">
		<meta name="viewport" content="initial-scale=1">
		<meta name="author" content="me">
		<title id="title"><super></title>
		<link type="text/css" rel="stylesheet" href="$site.asset('style.css').link()">
		<link type="text/css" rel="stylesheet" href="$site.asset('highlight.css').link()">
		<!-- mathtex -->
		<link type="text/css" rel="stylesheet" href="$site.asset('Temml-Local.css').link()">
		<script defer src="$site.asset('temml.min.js').link()"></script>
		<script defer src="$site.asset('render-mathtex.js').link()"></script>
		<!-- /mathtex -->
		<super>
	</head>

The blog.shtml it’s complaining about:

<head id="head">
	<style>
		.date {
			font-size: 0.9em;
		}
		
		.title h3{
			margin-top: 0;
		}
	</style>
	<title id="title" :text="$page.title.suffix(' - ', $site.title)"></title>
</head>

If I rerun zine (without changing anything), it complains about a different template, like index.shtml, which also has a title set like this:

<head id="head">
	<title id="title" :text="$site.title"></title>
</head>

Rerun again, and it’s post.shtml, same deal (head looks similar to the blog.shtml above, title set the same way), and so on.

To be honest, on the whole, even if I could make this approach work, I have mixed feelings about it. It feels cleaner code-wise, but requires modifying every template, versus just the base like @alectronic’s suggestion I am using now.

If you have found a way to crash Zine by editing templates, I’m very interested in a reproductible bug report!

When it happens please push to a repository (or zip the files) and share it with me in a GitHub Issue.

If I run into a segfault again, I’ll try to make an issue with something to reproduce. It happened pretty frequently when I was messing around with templates and didn’t know what I was doing, like putting <super> in a child template.

using zine on linux x86 from the github release

The error you’re getting is about the fact that <title> in the layout needs to be a top level element instead of being nested in <head>.

All elements that can be extended need to have their definition at the top level, as that’s essentially the interface that the file is fulfilling.

1 Like

Got it, thanks. I might give it another go some time. Also useful to know if I want to do other template extensions.

1 Like