lektor-website/docs/guides/single-page/index.html

361 lines
17 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="../../../static/styles.css?h=ae0cc228">
<link rel="stylesheet" href="../../../static/pygments.css">
<link rel="shortcut icon" href="../../../static/favicon.png?h=fa09bedd">
<title>Single-Page | Documentation | Lektor Static Content Management System</title>
</head>
<body class="default">
<nav class="navbar navbar-inverse navbar-static-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed"
data-toggle="collapse" data-target="#navbar"
aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="../../../">Lektor</a>
</div>
<div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li><a href="../../../downloads/">Download</a></li>
<li class="active"><a href="../../">Documentation</a></li>
<li><a href="../../../showcase/">Showcase</a></li>
<li><a href="../../../plugins/">Plugins</a></li>
<li><a href="../../../community/">Community</a></li>
<li><a href="../../../blog/">Blog</a></li>
</ul>
</div>
</div>
</nav>
<div class="body-wrapper">
<div class="container">
<div class="row">
<div class="col-sm-3">
<ul class="tree-nav nocontent">
<li><a href="../../">Welcome</a></li>
<li><a href="../../what/">What is Lektor</a>
<li><a href="../../installation/">Installation</a>
<li><a href="../../quickstart/">Quickstart</a>
<li><a href="../../project/">Project</a>
<li><a href="../../content/">Content</a>
<li><a href="../../templates/">Templates</a>
<li><a href="../../themes/">Themes</a>
<li><a href="../">Guides</a>
<ul>
<li><a href="../blog/">Blog</a>
<li><a href="../categories/">Categories</a>
<li><a href="../disqus/">Disqus Comments</a>
<li><a href="../error-pages/">Error Pages</a>
<li><a href="../page-order/">Page Order</a>
<li><a href="../pagination/">Pagination</a>
<li><a href="../portfolio/">Portfolio Sites</a>
<li><a href="../redirects/">Redirects</a>
<li class="active"><a href="./">Single-Page</a>
<ul></ul>
<li><a href="../sitemap/">Sitemap</a>
<li><a href="../webpack/">Webpack</a>
</ul>
<li><a href="../../deployment/">Deployment</a>
<li><a href="../../plugins/">Plugins</a>
<li><a href="../../models/">Data Modelling</a>
<li><a href="../../cli/">Command Line</a>
<li><a href="../../api/">API</a>
<li><a href="../../search/">Search</a>
</ul>
<div class="visible-md-block visible-lg-block">
<h4>This Page</h4>
<ul class="toc">
<li><a href="#the-models">The Models</a><ul>
<li><a href="#index.ini`"><code>index.ini</code></a></li>
<li><a href="#doc-pages.ini`"><code>doc-pages.ini</code></a></li>
<li><a href="#doc-page.ini`"><code>doc-page.ini</code></a></li>
</ul></li>
<li><a href="#initializing-the-contents">Initializing the Contents</a><ul>
<li><a href="#contents.lr`"><code>contents.lr</code></a></li>
<li><a href="#doc/contents.lr`"><code>doc/contents.lr</code></a></li>
</ul></li>
<li><a href="#templates">Templates</a></li>
<li><a href="#other-things-to-do">Other Things To Do</a></li>
</ul>
</div>
</div>
<div class="col-sm-9 doc-styling">
<h1>Single-Page</h1>
<ul class=page-meta>
</ul>
<p>Lektor builds a page out of every source file. However that does not mean
that you cannot have multiple pages combined into a single one. You have
probably already seen that when doing something with the children of a page
in templates. But you can do this in much more elaborate ways.</p>
<p>You could for instance generate a huge page out of individual pages to
achieve a page where you can scroll to all parts.</p>
<p>In this example we will implement a project documentation where all
documentation pages are rendered into a long page.</p>
<h2 id="the-models">The Models</h2><p>First we need to define the models. We will need three here:</p>
<ul>
<li><code>doc-pages.ini</code>: this is a dummy model that we will use to hide away the
parts of our big page.</li>
<li><code>doc-page.ini</code>: this is the model for our documentation pages.</li>
<li><code>index.ini</code>: this is the model we just use to combine everything together.</li>
</ul>
<p>We will just sort all the documentation pages by the page ID so it's possible
to just order the pages by prefixing the page with a number
(<code>0001-installation</code>, <code>0002-quickstart</code> etc.)</p>
<h3 id="index.ini`"><code>index.ini</code></h3><div class="hll"><pre><span></span><span class="k">[model]</span><span class="w"></span>
<span class="na">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">Documentation</span><span class="w"></span>
<span class="na">label</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">{{ this.title }}</span><span class="w"></span>
<span class="na">hidden</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">yes</span><span class="w"></span>
<span class="na">protected</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">yes</span><span class="w"></span>
<span class="k">[fields.title]</span><span class="w"></span>
<span class="na">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">string</span><span class="w"></span>
</pre></div>
<h3 id="doc-pages.ini`"><code>doc-pages.ini</code></h3><div class="hll"><pre><span></span><span class="k">[model]</span><span class="w"></span>
<span class="na">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">Documentation Pages</span><span class="w"></span>
<span class="na">label</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">Documentation Pages</span><span class="w"></span>
<span class="na">hidden</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">yes</span><span class="w"></span>
<span class="na">protected</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">yes</span><span class="w"></span>
<span class="k">[children]</span><span class="w"></span>
<span class="na">model</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">doc-page</span><span class="w"></span>
<span class="na">order_by</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">_id</span><span class="w"></span>
</pre></div>
<h3 id="doc-page.ini`"><code>doc-page.ini</code></h3><div class="hll"><pre><span></span><span class="k">[model]</span><span class="w"></span>
<span class="na">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">Documentation Page</span><span class="w"></span>
<span class="na">label</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">{{ this.title }}</span><span class="w"></span>
<span class="na">hidden</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">yes</span><span class="w"></span>
<span class="k">[fields.title]</span><span class="w"></span>
<span class="na">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">string</span><span class="w"></span>
<span class="k">[fields.body]</span><span class="w"></span>
<span class="na">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">markdown</span><span class="w"></span>
</pre></div>
<h2 id="initializing-the-contents">Initializing the Contents</h2><p>Now that we have the models we need to set up the initial pages. All our
models are hidden which means that we cannot use the admin panel to setup
the initial pages. So we need to set up the structure outselves. The
following pages and contents we will need:</p>
<h3 id="contents.lr`"><code>contents.lr</code></h3><pre><code>_model: index
---
title: My Documentation
</code></pre>
<h3 id="doc/contents.lr`"><code>doc/contents.lr</code></h3><pre><code>_model: doc-pages
---
_hidden: yes
</code></pre>
<p>This will set up our index model and our doc-pages model for the <code>doc/</code>
folder. The latter is also set to <code>_hidden</code> which will make Lektor prevent
the generation of those files: they are invisible. So we need to find other
ways to render them.</p>
<h2 id="templates">Templates</h2><p>For now we only need a single template: <code>index.html</code>, the one that will be
used by the only page that actually renders. Within that template we now
need to query for all the other pages we have below <code>doc/</code>:</p>
<div class="hll"><pre><span></span><span class="cp">{%</span> <span class="k">extends</span> <span class="s2">&quot;layout.html&quot;</span> <span class="cp">%}</span>
<span class="cp">{%</span> <span class="k">block</span> <span class="nv">title</span> <span class="cp">%}{{</span> <span class="nv">this.title</span> <span class="cp">}}{%</span> <span class="k">endblock</span> <span class="cp">%}</span>
<span class="cp">{%</span> <span class="k">block</span> <span class="nv">body</span> <span class="cp">%}</span>
<span class="cp">{%</span> <span class="k">set</span> <span class="nv">pages</span> <span class="o">=</span> <span class="nv">site.query</span><span class="o">(</span><span class="s1">&#39;/doc&#39;</span><span class="o">)</span><span class="nv">.include_undiscoverable</span><span class="o">(</span><span class="kp">true</span><span class="o">)</span><span class="nv">.all</span><span class="o">()</span> <span class="cp">%}</span>
<span class="p">&lt;</span><span class="nt">header</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span><span class="cp">{{</span> <span class="nv">this.title</span> <span class="cp">}}</span><span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">nav</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">ul</span><span class="p">&gt;</span>
<span class="cp">{%</span> <span class="k">for</span> <span class="nv">page</span> <span class="k">in</span> <span class="nv">pages</span> <span class="cp">%}</span>
<span class="p">&lt;</span><span class="nt">li</span><span class="p">&gt;&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">&quot;#</span><span class="cp">{{</span> <span class="nv">page._id</span> <span class="cp">}}</span><span class="s">&quot;</span><span class="p">&gt;</span><span class="cp">{{</span> <span class="nv">page.title</span> <span class="cp">}}</span><span class="p">&lt;/</span><span class="nt">a</span><span class="p">&gt;&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
<span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span>
<span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">nav</span><span class="p">&gt;</span>
<span class="p">&lt;/</span><span class="nt">header</span><span class="p">&gt;</span>
<span class="cp">{%</span> <span class="k">for</span> <span class="nv">page</span> <span class="k">in</span> <span class="nv">pages</span> <span class="cp">%}</span>
<span class="p">&lt;</span><span class="nt">div</span> <span class="na">class</span><span class="o">=</span><span class="s">&quot;section&quot;</span> <span class="na">id</span><span class="o">=</span><span class="s">&quot;</span><span class="cp">{{</span> <span class="nv">page._id</span> <span class="cp">}}</span><span class="s">&quot;</span><span class="p">&gt;</span>
<span class="p">&lt;</span><span class="nt">h1</span><span class="p">&gt;</span><span class="cp">{{</span> <span class="nv">page.title</span> <span class="cp">}}</span><span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span>
<span class="cp">{{</span> <span class="nv">page.body</span> <span class="cp">}}</span>
<span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span>
<span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span>
<span class="cp">{%</span> <span class="k">endblock</span> <span class="cp">%}</span>
</pre></div>
<h2 id="other-things-to-do">Other Things To Do</h2><p>Now every time you add or change a page below <code>doc/</code> it will start rebuilding
the overview page. Obviously you can further complicate the setup by doing
something with attachments, supporting different models etc. The
possibilities are endless.</p>
<div class="comment-box">
<h2>Comments</h2>
<div id="disqus_thread"></div>
<script>
var disqus_config = function() { this.page.identifier = "/docs/guides/single-page"; this.page.url = "https://www.getlektor.com/docs/guides/single-page/"; };
(function() {
var d = document, s = d.createElement('script');
s.src = '//lektordocumentation.disqus.com/embed.js';
s.setAttribute('data-timestamp', +new Date());
(d.head || d.body).appendChild(s);
})();
</script>
<noscript>
Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript"
rel="nofollow">comments powered by Disqus.</a>
</noscript>
</div>
</div>
</div>
</div>
</div>
<div class="bottomsummary">
<div class="container">
</div>
</div>
<footer>
<div class="container">
<div class="row">
<div class="col-sm-4 icon-bar">
<a href="https://github.com/lektor/lektor/" title="Lektor on GitHub"
><i class="fa fa-github"></i></a>
<a href="https://github.com/lektor/lektor/issues/" title="Report Issues for Lektor"
><i class="fa fa-bug"></i></a>
<a href="https://twitter.com/getlektor" title="Find Lektor on Twitter"
><i class="fa fa-twitter"></i></a>
<a href="https://gitter.im/lektor/lektor" title="Chat on Gitter"
><i class="fa fa-comment"></i></a>
<a href="https://github.com/lektor/lektor-website/tree/master/content/docs/guides/single-page/contents.lr" title="View source for this page"><i class="fa fa-code"></i></a>
</div>
<div class="col-sm-8">
<a href="../../../license/">License & Copyright</a>
<a href="../../../contact/">Contact</a>
Made with <i class="fa fa-fw fa-heart" title="Heart"><span hidden>Heart</span></i> in Carinthia
</div>
</div>
</div>
</footer>
<script type=text/javascript src="../../../static/app.js?h=bb1b933a" charset="utf-8"></script>
<script>
((window.gitter = {}).chat = {}).options = {
room: 'lektor/lektor',
activationElement: null
};
document.write('<button class="js-gitter-toggle-chat-button">Toggle Chat</button>');
var dnt = navigator.doNotTrack || window.doNotTrack || navigator.msDoNotTrack;
if (dnt != "1" && dnt != "yes") {
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
ga('create', 'UA-70822533-1', 'auto');
ga('set', 'anonymizeIp', true);
ga('send', 'pageview');
} else {
console.debug("Respecting Do-Not-Track, not running analytics.");
}
</script>
<script async src='https://www.google-analytics.com/analytics.js'></script>
<script async defer id="github-bjs" src="https://buttons.github.io/buttons.js"></script>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<script src="https://sidecar.gitter.im/dist/sidecar.v1.js" async defer></script>
</body>
</html>