The shell component
Personalize the "shell" surrounding your page contents. Used to set properties for the entire page.
Top-level parameters
css
description
favicon
The URL of the icon the web browser should display in bookmarks and tabs. This property is particularly useful if multiple sites are hosted on the same domain with different site_prefix
.
fixed_top_menu
font
font_size
footer
icon
image
javascript
javascript_module
language
layout
link
manifest
The location of the manifest.json if the site is a PWA. Among other features, serving a manifest enables your site to be "installed" as an app on most mobile devices.
menu_item
navbar_title
norobot
preview_image
refresh
rss
search_target
search_value
sidebar
sidebar_theme
social_image
theme
title
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/lovasoa/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.sql","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/lovasoa/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/lovasoa/sqlpage/issues","title":"Report a bug","icon":"bug"},{"link":"//github.com/lovasoa/sqlpage/discussions","title":"Discussions","icon":"message"},{"link":"//github.com/lovasoa/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/lovasoa/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.datapage.app/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.datapage.app) 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/lovasoa/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.sql","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.sql","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.datapage.app) documentation' as footer;