The shell component
Personalize the "shell" surrounding your page contents. Used to set properties for the entire page.
Top-level parameters
name | required | type | description |
---|---|---|---|
css | URL |
The URL of a CSS file to load and apply to the page. | |
description | TEXT |
A description of the page. It can be displayed by search engines when your page appears in their results. | |
favicon | URL |
||
fixed_top_menu | BOOLEAN |
Fixes the top bar with menu at the top (the top bar remains visible when scrolling long pages). | |
font | TEXT |
Specifies the font to be used for displaying text, which can be a valid font name from fonts.google.com or the path to a local WOFF2 font file starting with a slash (e.g., "/fonts/MyLocalFont.woff2"). | |
font_size | INTEGER |
Font size on the page, in pixels. Set to 18 by default. | |
footer | TEXT |
Muted text to display in the footer of the page. This can be used to display a link to the terms and conditions of your application, for instance. By default, shows "Built with SQLPage". Supports links with markdown. | |
icon | Name of an icon (from tabler-icons.io) to display next to the title in the navigation bar. | ||
image | URL |
The URL of an image to display next to the page title. | |
javascript | URL |
The URL of a Javascript file to load and execute on the page. | |
javascript_module | URL |
The URL of a javascript module in the ESM format (see javascript.info/modules) | |
language | TEXT |
The language of the page. This can be used by search engines and screen readers to determine in which language the page is written. | |
layout | TEXT |
The general page layout. Can be "boxed" (the default), "horizontal" (for a full-width menu), "vertical"(vertical menu), "fluid" (removes side margins). | |
link | URL |
The target of the link in the top navigation bar. | |
manifest | URL |
||
menu_item | TEXT |
Adds a menu item in the navigation bar at the top of the page. The menu item will have the specified name, and will link to as .sql file of the same name. A dropdown can be generated by passing a json object with a `title` and `submenu` properties. | |
navbar_title | TEXT |
The title to display in the top navigation bar. Used to display a different title in the top menu than the one that appears in the tab of the browser. | |
norobot | BOOLEAN |
Forbids robots to save this page in their database and follow the links on this page. This will prevent this page to appear in Google search results for any query, for instance. | |
preview_image | URL |
The URL of an image to display as a link preview when the page is shared on social media | |
refresh | INTEGER |
Number of seconds after which the page should refresh. This can be useful to display dynamic content that updates automatically. | |
rss | URL |
The URL of an RSS feed to display in the top navigation bar. You can use the rss component to generate the field. | |
search_target | TEXT |
When this is set, a search field will appear in the top navigation bar, and load the specified sql file with an URL parameter named "search" when the user searches something. | |
search_value | TEXT |
This value will be placed in the search field when "search_target" is set. Using the "$search" query parameter value will mirror the value that the user has searched for. | |
sidebar | BOOLEAN |
Whether the menu defined by menu_item should be displayed on the left side of the page instead of the top. Introduced in v0.27. | |
sidebar_theme | BOOLEAN |
Used with sidebar property, It can be set to "dark" to exclusively set the sidebar into dark theme. | |
social_image | URL |
The URL of the preview image that will appear in the Open Graph metadata when the page is shared on social media. | |
target | TEXT |
"_blank" to open the link in a new tab, "_self" to open it in the same tab, "_parent" to open it in the parent frame, or "_top" to open it in the full body of the window | |
theme | TEXT |
Set to "dark" to use a dark theme. | |
title | TEXT |
The title of your page. Will be shown in a top bar above the page contents. Also usually displayed by web browsers as the name of the web page's tab. |
No data |
Example 1
This example contains the values used for the shell of the page you are currently viewing.
The menu_item
property is used both in its simple string form, to generate a link named "functions" that points to "functions.sql",
and in its object form, to generate a dropdown menu named "Community" with links to the blog, the github repository, and the issues page.
The object form can be used directly only on database engines that have a native JSON type.
On other engines (such as SQLite), you can use the dynamic
component to generate the same result.
You see the page layouts demo for a live example of the different layouts.
select
'shell' as component,
'SQLPage: SQL to web pages' as title,
'database' as icon,
'/' as link,
JSON('{"title":"About","submenu":[{"link":"/safety.sql","title":"Security","icon":"lock"},{"link":"/performance.sql","title":"Performance","icon":"bolt"},{"link":"//github.com/sqlpage/SQLPage/blob/main/LICENSE.txt","title":"License","icon":"file-text"},{"link":"/blog.sql","title":"Articles","icon":"book"}]}') as menu_item,
JSON('{"title":"Examples","submenu":[{"link":"/examples/tabs/","title":"Tabs","icon":"layout-navbar"},{"link":"/examples/layouts.sql","title":"Layouts","icon":"layout"},{"link":"/examples/multistep-form","title":"Forms","icon":"edit"},{"link":"/examples/handle_picture_upload.sql","title":"File uploads","icon":"upload"},{"link":"/examples/authentication/","title":"Password protection","icon":"password-user"},{"link":"//github.com/sqlpage/SQLPage/blob/main/examples/","title":"All examples & demos","icon":"code"}]}') as menu_item,
JSON('{"title":"Community","submenu":[{"link":"/blog.sql","title":"Blog","icon":"book"},{"link":"//github.com/sqlpage/SQLPage/issues","title":"Report a bug","icon":"bug"},{"link":"//github.com/sqlpage/SQLPage/discussions","title":"Discussions","icon":"message"},{"link":"//github.com/sqlpage/SQLPage","title":"Github","icon":"brand-github"}]}') as menu_item,
JSON('{"title":"Documentation","submenu":[{"link":"/your-first-sql-website","title":"Getting started","icon":"book"},{"link":"/components.sql","title":"All Components","icon":"list-details"},{"link":"/functions.sql","title":"SQLPage Functions","icon":"math-function"},{"link":"/custom_components.sql","title":"Custom Components","icon":"puzzle"},{"link":"//github.com/sqlpage/SQLPage/blob/main/configuration.md#configuring-sqlpage","title":"Configuration","icon":"settings"}]}') as menu_item,
'boxed' as layout,
'en-US' as language,
'Go from SQL queries to web applications in an instant.' as description,
'https://sql-page.com/sqlpage_social_preview.webp' as preview_image,
'Poppins' as font,
'https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11/build/highlight.min.js' as javascript,
'https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11/build/languages/sql.min.js' as javascript,
'https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11/build/languages/handlebars.min.js' as javascript,
'https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11/build/languages/json.min.js' as javascript,
'/highlightjs-launch.js' as javascript,
'/highlightjs-tabler-theme.css' as css,
'Official [SQLPage](https://sql-page.com) documentation' as footer;
Example 2
A page without a shell
SQLPage provides the shell-empty
component to create a page without a shell.
In this case, the html
and body
tags are not generated, and the components are rendered directly in the page
without any styling, navigation bar, footer, or dynamic content.
This is useful when you want to generate a snippet of HTML that can be dynamically included in a larger page.
Any component whose name starts with shell
will be considered as a shell component,
so you can also create your own shell component.
If you generate your own HTML from a SQL query, you can also use the shell-empty
component to include it in a page.
Make sure you know what you are doing, and be careful to escape the HTML properly,
as you are stepping out of the safe SQLPage framework and into the wild world of HTML.
select
'shell-empty' as component,
'<!DOCTYPE html>
<html>
<head>
<title>My page</title>
</head>
<body>
<h1>My page</h1>
</body>
</html>' as html;
Examples
Sharing the shell between multiple pages
It is common to want to share the same shell between multiple pages.
Static menu
If your menu is completely static (it does not depend on the database content),
you can use the dynamic
component together with the
sqlpage.read_file_as_text
function to load the shell from
a json file.
SELECT 'dynamic' AS component, sqlpage.read_file_as_text('shell.json') AS properties;
and in shell.json
:
{
"component": "shell",
"title": "SQL + JSON = <3",
"link": "/",
"menu_item": [
{"link": "index.sql", "title": "Home"},
{"title": "Community", "submenu": [
{"link": "/blog.sql", "title": "Blog"},
{"link": "//github.com/sqlpage/SQLPage", "title": "Github"}
]}
]
}
Dynamic menu
If your menu depends on the database content, or on special sqlpage
functions,
you can use the dynamic
component,
but this time with the sqlpage.run_sql
function to generate the menu from the database.
SELECT 'dynamic' AS component, sqlpage.run_sql('shell.sql') AS properties;
and in shell.sql
:
SELECT 'shell' AS component, 'run_sql is cool' as title,
json_group_array(json_object(
'link', link,
'title', title
)) as menu_item
FROM my_menu_items
(check your database documentation for the exact syntax of the json_group_array
function).
Another case when dynamic menus are useful is when you want to show some menu items only in certain conditions.
For instance, you could show an "Admin panel" menu item only to users with the "admin" role, a "Profile" menu item only to authenticated users, and a "Login" menu item only to unauthenticated users:
set role = (
SELECT role FROM users
INNER JOIN sessions ON users.id = sessions.user_id
WHERE sessions.session_id = sqlpage.cookie('session_id')
); -- Read more about how to handle user sessions in the "authentication" component documentation
SELECT
'shell' AS component,
'My authenticated website' AS title,
-- Add an admin panel link if the user is an admin
CASE WHEN $role = 'admin' THEN '{"link": "admin.sql", "title": "Admin panel"}' END AS menu_item,
-- Add a profile page if the user is authenticated
CASE WHEN $role IS NOT NULL THEN '{"link": "profile.sql", "title": "My profile"}' END AS menu_item,
-- Add a login link if the user is not authenticated
CASE WHEN $role IS NULL THEN 'login' END AS menu_item
;
More about how to handle user sessions in the authentication component documentation.
Menu with icons
The "icon" attribute may be specified for items in the top menu and submenus to display an icon before the title (or instead). Similarly, the "image" attribute defines a file-based icon. For image-based icons, the "size" attribute may be specified at the top level of menu_item only to reduce the size of image-based icons. The following snippet provides an example, which is also available here.
SELECT
'shell' AS component,
'SQLPage' AS title,
'database' AS icon,
'/' AS link,
TRUE AS fixed_top_menu,
'{"title":"About","icon": "settings","submenu":[{"link":"/safety.sql","title":"Security","icon": "logout"},{"link":"/performance.sql","title":"Performance"}]}' AS menu_item,
'{"title":"Examples","image": "https://upload.wikimedia.org/wikipedia/en/6/6b/Terrestrial_globe.svg","submenu":[{"link":"/examples/tabs/","title":"Tabs","image": "https://upload.wikimedia.org/wikipedia/en/6/6b/Terrestrial_globe.svg"},{"link":"/examples/layouts.sql","title":"Layouts"}]}' AS menu_item,
'{"title":"Examples","size":"sm","image": "https://upload.wikimedia.org/wikipedia/en/6/6b/Terrestrial_globe.svg","submenu":[{"link":"/examples/tabs/","title":"Tabs","image": "https://upload.wikimedia.org/wikipedia/en/6/6b/Terrestrial_globe.svg"},{"link":"/examples/layouts.sql","title":"Layouts"}]}' AS menu_item,
'Official [SQLPage](https://sql-page.com) documentation' as footer;