Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
We're constantly putting together Tutorials and Guides to help you get started with each area of Siteglide.
A collection of 3rd party links that our partners find useful when developing websites.
These sites are full of useful content, but any advice and examples published by 3rd party Sites is their own. We do not recommend any particular Front End library and encourage your agency to find the front-end tools and techniques that work for you.
Siteglide is built upon platformOS, so their documentation is a fantastic resource for adding custom functionality to your Siteglide Website:
We also recommend the platformOS docs as the ultimate authority on using Liquid in your Siteglide Site. They include documentation on the original Liquid features and the additional features platformOS have added themselves:
You'll come across JSON when you are working on Migrations and commonly when working with Liquid. It's a common language for storing data-structures, so if you output {{this}}
in a Layout- we'll show you the JSON which stores the fields you need.
Using a third party JSON tool is useful to actually take the raw data and make it easy to read. Everyone has a different favourite tool, but you can see a third party comparison here to help you get started and find one:
w3schools give a fantastic introduction to all web development topics, including reference guides and examples on HTML, JS, CSS, accessibility and more. https://www.w3schools.com/
MDN is another fantastic reference guide. It's useful if you need a little bit of extra depth and context. https://developer.mozilla.org/en-US/
Bootstrap is a useful library of Front-End components and features that we've made fully compatible with the Siteglide Design System because it is so widely used and familiar. If you have Design System enabled on your Page, there is no need to install
Stack Overflow is fantastic for FAQs on every aspect of development.
Code Pen is a great source of inspiration for all things CSS and JavaScript. It is full of fancinating community generated examples of everything from User-interfaces to animations:
Wes Bos has earned a reputation for teaching courses in JavaScript that are accessible to beginners and experts alike:
We use the Glide.js plugin to power out Slider Module Layouts. Check out the docs to customise your Layouts and build new ones:
Google Maps are used by the Events Module. Read the docs and customise here:
FullCalendar.io is the plugin which powers the Calendar Layout of the Events Module. Read the docs and customise here:
CSS tricks is a great resource for staying up to date on the latest in CSS and specialises in helping you tackle those issues that leave you scratching your head:
June 25, 2024
We strive to support all recent versions of major browsers front-end JavaScript features that we deliver to your site, such as eCommerce or Forms.
For the sake of security and providing the best experience to the majority of customers, we do not support browsers that are no longer receiving security updates and represent a small minority of traffic.
We support Edge v79 onwards per Microsoft's lifecycle policy. We do not support Legacy Edge or Internet Explorer versions as they are no longer supported by Microsoft.
We support Chrome, Safari and Firefox on desktop platforms.
We support the Android native browser on Android 4.4 and later.
iOS and iPadOS version 10 and later. This also includes browser variants on iOS such as Chrome, Firefox, Brave etc.
We respond to bug reports but do not proactively test other browsers.
If you have any system related issues in the browsers above then please don't hesitate to contact us for support.
We recommend always using the latest browser version available to your operating system for the best support and security while using the internet. You can use the links below for your browser’s documentation to learn more about checking and updating your version:
For Safari, and Microsoft Edge browsers, this may depend on your device's operating system so check your OS is up to date as well.
Our Agency Success team here at Siteglide are dedicated to providing exceptional support and assistance to Digital Agencies and Siteglide Experts which ensures they are able to deliver the best solutions for their customers.
Please note: Website owners need to contact their Digital Agency for assistance, if you do not have one let us know and we'll recommend a reliable local agency or you can use our services team, Sitegurus.
Here we'll outline the ways in which we can help you and a few things that fall outside of our scope that we cannot assist with but we'll point you in the right direction whether it's via our Community or external resources.
Live Chat - Click the blue bubble in the bottom right hand corner of our services to speak with the team. Please leave as much information as possible by answering any questions that appear.
Documentation - Access our growing library of Docs, FAQs, examples, videos and more, right here
Discord Community - Have a question that needs a creative solution or a project scope you'd would like some suggestions on from other experienced partners? https://discord.gg/BsmP3au6Am
Please note our working hours are 8am - 6pm GMT (London). We aim to answer queries outside these hours where possible.
We assist agencies and developers with the following types of issues/queries:
Platform Issues/Bugs: If you experience an issue with the core platform please report it to us and we'll help resolve it asap.
High Level Platform Capabilities: We're always here to help answer questions about the platform and confirm whether it has specific features/capabilities.
Account and Sales Questions: If you have a billing, account or sales related question we're always here to assist.
Troubleshooting: If you're struggling with a feature in Siteglide we'll point you in the right direction.
Technical Queries: Initial guidance but then you would need to use Sitegurus for assistance implementing Siteglide features.
3rd Party Code and Custom Development: We only support the core platform code and functionality supplied out of the box as described in our documentation. We cannot support you on any 3rd party code or custom development even if we've recommended looking at 3rd party options. You are responsible for the implementation and maintenance of any custom code, design, bespoke functionality and any 3rd-party integrations. Note: Any custom code samples are provided as a guide only. We cannot provide support on use or implementation of any code that is not in our documentation. We want to focus on providing the best support of our code and platform that we possibly can. See #community-support-and-resources below.
Specific project issues/assistance: We cannot help you build projects or scope out exactly how you will build each project. We will help answer high level capability questions but cannot map out how to implement Siteglide for specific project requirements. If you need help with using Siteglide for a project please review our Community Support and Resources options below.
Client/business specific questions: Siteglide is built primarily to help Digital Agencies and Expert Partners and to ensure we deliver on this mission we only provide basic account related support to end clients or Business plan users. See below for our Community Support and Resources options.
We have a fantastic community of Siteglide Experts that can assist in various ways where we simply cannot (we want to stay focused on supporting you with the platform itself):
Discord Forum: The forum is the best place to start. Search to see if your question/issue already exists and post a new one if not! You can access the Forum via the Single Sign On link from the Welcome page in the Portal: https://discord.gg/BsmP3au6Am
Siteglide Experts: We have various experts all over the globe ready to assist whether it's help scoping projects, solving issues, building projects, building specific functionality or even providing pre-built Modules or code. Browse our List of Experts here: https://www.siteglide.com/partners
Sitegurus: Our services team, Sitegurus, are here to assist you with any task big or small.
External Resources: There are thousands of websites and resources to help with anything from project planning through to custom development and integrations. We've curated the ones that tend to be most useful to our partners here: External Resources
There are a few main ways to work with your Siteglide Site:
Using the Siteglide Admin - Create an Account and use the User Interface to explore and build your Site. If you have any questions, use our live chat button to get help.
Using the Siteglide CLI - Efficiently work directly with your Site's code on your own machine.
Wait I'm not a developer? Don't worry, Siteglide has low-code tools like Studio, Toolbox and SiteBuilder to help Designers and Agents get stuck in as well!
In the course of this Documentation, you will probably come across the following languages that we use in many of our features and examples:
HTML - The standard Markup Language of the web. Learn more at MDN
JavaScript - The standard client-side scripting language of the web. Learn more at MDN
YAML - Used by Siteglide to store settings like page metadata, normally at the top of Liquid files.
Liquid - Used by Siteglide for dynamic server-side rendering of HTML and other languages.
GraphQL - Used by Siteglide to query the database and modify data. Often for beginners this will be tucked away inside our features, but learning it allows you to unlock more powerful possibilities.
Siteglide works very closely with our partners at platformOS to provide you with all the benefits of a modern cloud-based infrastructure like AWS, while at the same time making your life easier so you can focus on delivering the best for your clients.
platformOS are behind a lot of the code used on Siteglide sites, developing everything from new Liquid filters on top of Liquid's open-source starting point and a fully functional GraphQL schema you can plug into for making database queries and mutating to modify data. We also work with a range of other open-source and 3rd party technologies to bring you our full suite of features.
In our documentation we will often direct you to the pOS documentation and those of other 3rd parties to help you dig deeper into what it is possible to build. platformOS have won awards for their innovative documentation and we will try not to re-invent the wheel when we cover the same topics as them, but instead hope to present topics like GraphQL with a more beginner-friendly slant.
Most platformOS features can be built on Siteglide - if you find one you like and are not sure if it's supported yet, we encourage you to let us know about it.
This guide will walk you through the process of creating a new site using Siteglide's admin area.
Once you're logged into the portal, you'll find yourself on the dashboard.
If you don't see a 'Create a Website' button (as per 2nd screenshot) please contact us via Live Chat to prove you're human and we'll get you setup!
Once you're account is approved you should see the Create a Website button:
If you already have 1 or more site you'll see options to create a site, manage existing sites, or manage your company:
You have the option to create a new site from scratch or use a Template.
If you're new to Siteglide or less technical, it's recommended to start with a template because they're built with SiteBuilder, a tool to help you rapidly build and customise websites:
Please follow the above link if you're new to Siteglide
The rest of this Quickstart guide will focus on building a Custom Site. Click the 'Build a Custom Site' button.
Give the site a name and it will automatically create the URL. You will need to ensure it's unique, if it turns red please amend by making it more unique. Then click Create Site.
And that's it! You've successfully created a new site, you will need to wait for it to be ready to use:
You will receive an email when it's done but can also find it under the Sites area:
The Status will show as Trial and there will be a new blue button in the bottom bar that will likely say Sign up for Admin Access if you've not yet used it, otherwise it'll say Admin going forwards:
Click through to Administer the Site and you'll end up on the Dashboard:
If you're a developer you'll likely want to set up our CLI:
The home of Siteglide Docs - Build Limitless Digital Experiences
Siteglide allows agencies to take control over code and data via API, CLI or UI. With the right blend of out-of-the-box tools and freedom to develop - without limits.
If you're new to Siteglide we recommend starting from a pre-built Template that leverages our SiteBuilder tool: Create Site From Template.
If you're looking for help with a site and not sure where to look you can check out our Quickstart Guides.
If you're already working on a site and you're code savvy we strongly recommend setting up our CLI so you can get the most from Siteglide via VSCode or your preferred IDE: Quickstart: CLI
Looking for something else? Use the Search (top right) or navigate through the left menu which is organised to match the menu you will see in Siteglide.
Quickstart: Bare essential guides with links to more detailed articles if you get stuck
About / Introduction: A brief overview of the topic
Step by Step Articles: How to Implement a Feature or Solve a Problem
Concept: Will take a feature and explain it in a little more depth
SiteBuilder: How to get setup and get the most from the SiteBuilder module
Reference: A brief reference guide to this feature for developers and anyone interested in code
File Structure: This will show you which folders and files are necessary and where to add them to your codebase. This will be presented in the format from which you would see it in Siteglide CLI
Troubleshooting: Find answers to common challenges
Go Further: This is where you'd find more detailed docs that help you really push the boundaries of all things web development
API: Endpoints and articles related to our API
Changelogs: Releases, Updates and any important changes to Siteglide
Billing/Account: Articles related to Billing, Payments and Subscriptions
Agencies: Articles specific to Digital Agency partners
Manage your Siteglide Account
Looking for Agency Account information?
You can manage your company profile and account settings here:
This is also where you invite Account level users who have access to all sites:
Simply add a name and email address of a person you'd like to add to the Account:
This shows all the Sites directly under your account (this will not show any Sites in Client folders):
Launchpad shows you how much of Siteglide you've used and setup. It's a great way to ensure your team learns the platform:
Go to a specific site in Portal and click the Modules tab. This will show all Modules in the Marketplace but it will not show Marketplace Templates because they cannot be installed onto an existing site).
You can filter to see which Modules are installed:
We recommend keeping Modules Updated (yellow Update button shows an update is available), read more on managing Modules:
You can filter in the Name field if you're looking for a specific module:
Clicking a module will give you more information:
When ready just click install to install it to that site.
How to Go Live with a Site on Siteglide
Great news! You're ready to Go Live? Just follow these steps or contact us if you get stuck.
Head to the Go Live tab on the Site in the Siteglide Portal, if this is your first Site you'll likely see a message asking you to add your billing information:
Just click the link which will take you to the Billing Setup page, you just need to fill out the form:
More information on Billing Setup:
The Subscription tab will show your current usage and recommend which plan you need, it'll only suggest the lowest plan that your Site currently fits into. We'd recommend considering picking a higher plan if you know usage is going to increase, this will help avoid paying overages:
On the Go Live tab there are a few options, firstly pick your currency then select the Plan (based on Step 2) and finally pick your preferred/closest Datacenter (this cannot be changed).
The button will not turn blue until you've selected a Plan:
It will then confirm the last 4 digits of the card that will be used and that you will be charged pro-rata for the remainder of the month based on the selected plan. When ready click Start Subscription. Please contact us if you are unsure about any of these steps, we cannot make changes once the site is Live.
You don't need to do anything but once you click Start Subscription the site will automatically be copied from Staging to Production. You will need to wait until this has been completed before you can work with the site or add domains.
If you use CLI you will need to ensure you no longer connect to the Staging site and instead connect to the Production site, see screenshot below (note 'production' not 'staging'):
Ready to add your domain?
Ensure email deliverability via Sendgrid:
Want to invite users to an individual Site only?:
Want to see all sites you have access to?
Manage sites in Siteglide Portal
Click the 'Sites' button in the left hand menu in Portal to see your list of sites, then click the Name of the site you want to view the settings for:
This is where you manage the site including Users, Modules and the Subscription:
ID - Unique identifier for this site
Site Name - Name of the site - this can be edited
URL - The site's live or developmental URL - this can be edited (keeping the same format. e.g. Staging/Trial Sites = https://sitename.staging.oregon.platform-os.com/ and Production/Live Sites = https://sitename.prod01.oregon.platform-os.com/ )
Status - This will be 'Trial', 'Trial Expired - Locked', 'Trial Expired - Redirected' or 'Live'.
Datacenter - One of three datacenters that was picked when this site was created (London, Oregon, Sydney)
Company (listed as Owner in 'Sites' area) - The Agency or Client that owns this site
Create Date - The date that this site was created
Created By - Email address of the user that created this site
Latest Activity - The date that this site was last edited
API Key - You can click here to reveal your key
CLI Command - A shortcut to add this Site to CLI to begin working with, e.g:
Note: Here, you can also see how long is left on your trial. When your trial has reached 0, an email will be sent out to the agency who owns this site, and this site will enter the expiry flow.
You can extend this trial by clicking 'extend' next to the Status. Sites will automatically extend their trial when users visit this site's admin or connect to this site via CLI.
After 14 days of this trial being locked and with no user extending this trial; a reminder email is sent out and this Site will now redirect to https://www.siteglide.com/ .
After 13 days of this trial being redirected; another reminder email is sent to notify the agency owner that this Site will be deleted if no action is taken.
After 1 day of this second email being sent out, this trial Site will be locked and greyed out in Siteglide.
Within 24 hours of this site being greyed out, this Site will be fully deleted.
Using the buttons at the bottom, you can also 'View' this site, edit this Site's 'Admin', 'Save' any changes made to the name or URL, or 'Delete Site'.
We strongly recommend Fully Delegating your domain for best results and to avoid additional steps redirecting the non-www to www.
If you have a domain that is managed in GoDaddy or another registrar and would like to point it to a Siteglide website you can use our External Domain feature. This means that you can continue to manage your DNS through GoDaddy/other registrar.
Navigate to the Domains tab on the Site and click Add Domain:
Type in the root domain without www and you'll likely want to set it as the Default Domain and Enable WWW Redirect. Then click Add Domain:
Important Note: Your domain can take up to a few minutes to be fully added to the system. Please check back and refresh the page shortly.
Once your domain has finished creating in the system, it's status will change to "Ownership Verification Pending" which means it is now ready.
Add the generated CNAME record to in your DNS control panel to verify ownership, generate an SSL certificate and automatically apply it to your site during the next step.
Once you have saved the record in your registrar, allow some time for propagation, check back and refresh the page.
Important Note: The CNAME verification record must NOT be deleted at any point otherwise the SSL certificate will not renew.
Once the verification CNAME record has propagated the WWW CNAME Record needs to be added in your DNS Control Panel (GoDaddy example):
The site will now be live via WWW (https://www.domain.com) but not via the root domain (https://domain.com). Complete Step 5 to fully setup the domain correctly. The domain should show as 'Live' under the Status column in Siteglide:
Most DNS Control Panels cannot correctly redirect the root traffic to the WWW over SSL so we recommend using an external service called Redirect.Pizza.
Just follow these steps to redirect your non-www to the www variant. The non-www is also sometimes called naked record or "apex" (screenshots below):
Create a redirect.pizza account.
Add your source. This should be the domain without www. For instance, enter example.com as your source.
Set the destination to the variant with www. Example: www.example.com
Press "Create redirect"
The required DNS change pops up. Go to your domain registrar to make this DNS change for the A record. This record may already exists '@'. Press 'edit' to edit it to the required DNS setting for redirect.pizza. For more info, see What are these DNS changes?
The DNS change is made! It may take up to 24 hours before the DNS is fully propagated.
These Steps can also be found here: https://redirect.pizza/support/redirecting-non-www-to-www
You can view who has access to the site on the Users tab as well as invite existing users to the site.
You can only invite existing Siteglide users to Sites, you might be working with an external Siteglide Expert, you would give them access to this Site here.
If you're looking to invite your own team to manage the site you would need to add them to your Account:
Manage Domains on Siteglide
You can only manage custom domains on a Live Production Site on Siteglide, if you see the Go Live tab and not the Domains tab then the site is not Live. Please follow the Go Live steps: Go Live
You can either Fully Delegate your DNS to Siteglide or manage it externally:
With the increasing challenges faced with spam there are now stricter rules for email deliverability but there are some simple steps you can take to ensure your emails hit the inbox:
We strongly recommend Fully Delegating your domain to Siteglide (vs External DNS) for best results and to avoid additional steps redirecting the non-www to www.
Navigate to the Domains tab on the Site and click Add Domain:
Not sure which? Please read the pros and cons of each first: Fully Delegated vs External DNS
Just click the Fully Delegated box:
Once you select Fully Delegated you need to type in your root domain (without www) and then decide if it's going to be your default domain (most likely):
You should also ensure 'Enable WWW Redirect is on unless you're adding a subdomain. Finally you can choose to add other DNS records but you can always do this later too. If you toggle to add them now you just add records and fill in the fields.
Sit back and relax or go and make a coffee while the system does the work!
If you click the domain at this stage you'll just see the records you've added as Pending, there's nothing you can do at this stage so go grab that coffee!
You can refresh the page until you see the Status as 'Awaiting Propagation':
Then click into the domain and you'll see any records you've added plus the NS Records you need to add in your Domain Control Panel (GoDaddy etc):
Please ensure you've copied ALL existing DNS records from your current provider into Siteglide otherwise important services such as Email might fail.
To add more Records just click Edit Records and add new rows as required:
No matter how many times you've put sites live you'll no doubt be refreshing and questioning if it's worked from the moment you change the Nameservers!
You're looking for the Status to show as 'Live' in Siteglide but there are other ways to check progress listed below:
Typically you'll see some positive signals within minutes but you really do need to give it an hour or so (registrars will say 24-48 hours) before stepping in.
We recommend using the following tools to monitor propagation:
Your Siteglide Subscription
The Subscription tab will show your Site Usage and what plan you're on or which plan we recommend if the site is not yet Live:
The Records Table shows a breakdown of all Records and how many have been deleted this month:
This is where you manage Account users, they would get access to all sites in your Portal
To invite users to your Account you can only do this from the Users tab on your Account (your company name in the left menu):
You will not see the blue invite button on the Users page (left hand menu Users link):
If you click a user you can see what Sites they have access to and their User Role:
Find out more on Users and User Roles:
The following code example can be added to a Page Template and applied to the home/start page of a site to load a different start page for different domains added to the site.
This method does however remove some of the ease of editing for the client, as they will not be able to use Visual Editor to manage the pages that are setup this way. We'll look at adding a smoother point and click version to Admin later.
One use case for this approach would be where a client has a small chain of businesses that each have their own domain to target the area closest to them. Each of the sites are very small and the website structure is reasonably similar, and so it makes sense for the client to be able to manage all of them from the same Admin.
I'll now explain the code snippet above and how it works.
On the first line we get the current domain (context.location.host
) when the page loads and assign it so that it has a name of domain
.
Next, we open a case
to check the result of domain
.
We then add an else
at the end of the case
to cover the default domain e.g. "if neither of these alternate domains are used, then do this" which acts somewhat like a catch all.
Finally, we close the case
.
Using the above example, visitors will see unique page content to each domain when they visit. When they click on links on the page, they will continue to other pages on the site while keeping the same domain unless you hard code a full domain URL on a link. Please note that by adding more than one domain to a site, technically all content is accessible via all domains. Though you can effectively make content hidden from domains by not adding it to pages, it could still be accessed.
Simply fill in the form to add your card details to the Account. Please note this card will be used for ALL payments unless otherwise stated on the Go Live tab.
If you haven't previously setup Billing on Siteglide it will ask for your Company Name and Address:
If you already have a card on file with us it'll show the last 4 digits but you can replace this card with a new one:
User Roles determine what users can see and do within Siteglide. Account owners have granular control over this and can set others as Admins or limit what they can do.
You can then change or add additional Roles for that User:
To create a New Role just give it a name and select the granular controls they have access to:
You can also copy permissions from an existing role to save time:
You can see what Role a User has by clicking the Roles tab on a User:
For each of the alternate domains we would like to check for, we create a when
within the case
. We include two versions of the domain to catch the majority of users. One that includes the . and another that does not.
Inside each when
we call in a content section that should contain all of the page content. We also define an SEO page title to match our page and wrap that in siteglide_head_scripts
to automatically move it to the head on page load (Check out this document to find out more: ).
Manage Users in Siteglide
The Users page in Siteglide Portal shows you all the Users in your company:
It's important to understand User Roles and how to control what other users can see and do:
Ready to invite Users to your account?
Sites can be automatically upgraded to the next available plan on the 1st of the following month if the cost of Extras exceeds the difference in cost to upgrade to the appropriate plan. Automatic upgrades by the system ensure that if usage increases on a site, the cheapest option is chosen and charged.
The default "Agency Global Preferences" is to not allow automatic upgrades. The "Site Preferences Override" has no override set and so will follow your Agency Preference. You can change this setting by following the information below.
Site owners and agencies have granular control over automatic upgrades via Siteglide Portal. You can choose to control the setting either Globally for all of your sites, or individually for specific sites.
Please ensure you set this up to suit your billing preferences.
Within your Agency Account Details in Portal, you can choose for the default setting to enable or disable automatic upgrades for all sites within your Agency and Clients.
The "Automatic Site Upgrades?" toggle can be set to two different states:
Yes - Automatic upgrades are turned on for all sites unless you override at site level. Upgrades will take place if it is cheaper than paying Extras
No - Automatic upgrades are turned off for all sites unless you override at site level. No upgrades will take place unless you action them yourself
Once you have chosen a state, make sure to save.
Note: This preference can be overridden by a selected state applied at the site level.
Within the Subscriptions tab for a site, you can choose to override the global preferences and control each site separately.
Above the peak usage table, you'll see the current state for this site and an option to change this.
Click "Change" to open a pop up modal, where you'll be shown the current state for this site and an option to override Global Preferences in two ways.
To override, tick the "Override?" checkbox and select the appropriate state you would like to apply as an override.
To remove an override, untick the "Override?" checkbox.
An override can be set to either of the following states:
Automatic - Automatic upgrades are turned on for this site only. Upgrades will take place if it is cheaper than paying Extras
Manual - Automatic upgrades are turned off for this site only. No upgrades will take place unless you action them yourself
Once you have chosen an override state, make sure you click save.
You can view your previous and upcoming invoices on the Invoices page:
Log and Manage Support Tickets in Siteglide
Live Chat or Tickets? We recommend using Tickets over Live Chat when it's something that needs further investigation.
This is where you can contact us about an issue by logging a Support Ticket:
Just give it a title, select which site it relates to (if applicable) and please provide as much information as you can:
The Subscriptions tab shows you exactly what each site uses broken down into high-level types of infrastructure usage and then down to specific Siteglide features to help show more value to clients.
For example, you can see the total number of Units but the real value is seeing that this is made up of CRM Contacts, Form Cases, WebApp items, Module Items, Products and much more.
Note: External API calls are unlikely to be used for many sites if you're not working on platformOS directly via CLI.
When comparing the cost of the various different tools required to achieve the same result and then trying to somehow connect them all together you can show huge savings to clients both in terms of cost and time.
You can see the individual Site Plan pricing on the Plans page:
Extras are charged pro-rata based on the plan price. Simply divide the Plan Price by the Units included you get the Unit Rate that you will be charged if you exceed the limit.
We replaced the old, more costly Overages with Extras. If your site subscription tab shows a 'Legacy' plan please refer to old old Overages pricing or speak to the team about switching to one of our new plans!
Storage, Records, Domains and Client Admin Users do not reduce unless deleted.
Emails, API Calls and Bandwidth renew each month.
You are billed based on the peak usage each calendar month.
Deleted items count towards peak usage for that month but do not count in subsequent months.
Once you hit 70% usage of any metric it will be marked as orange as a warning.
Once you hit 100% usage of any metric you will start incurring Extras.
If you have Automatic Upgrades turned on and the cost of Extras exceeds the difference in cost to upgrade to the appropriate plan the site will automatically be upgraded on the 1st of the following month.
You can manually upgrade or downgrade to any plan once per month but if the new plan doesn't cover the usage you will be charged overages.
We do not downgrade automatically as we do not know what usage will be required in a given month and assume most sites increase in usage as the business grows and the site becomes more successful/popular.
To give you full use of the Siteglide platform we simply charge you based on your usage which can change over time and likely increase as you help your clients grow.
Please ensure you're aware of how subscription changes work before going live:
We monitor usage and provide the Subscriptions tab for each site to show if you are close to exceeding or exceeding the usage available on the current plan. Find out more about the Subscriptions Area in Portal.
We calculate usage at midnight on the 1st of each month for the whole of the previous month. If you have Automatic Upgrades turned on and exceed any usage limits we will apply the cheapest option at the time which will either be to charge Extras or Upgrade the plan. If you have Automatic Upgrades turned off we will only charge the Extras.
Extras are charged in blocks as a one-off charge for excess usage in that billing period. Typically you could use double the allowance of one usage metric before it’s cheaper to upgrade to the next plan.
For Monthly Upgrades the new plan will be applied immediately both for the new month and retrospectively for the previous month (to avoid paying more costly overages). We will charge for the new month and the increase between the new and previous plan. This will only be done to save higher overage costs, we will always apply the cheapest option.
Annual Upgrades will start a new 12 month subscription crediting the balance of the previous subscription prior to payment (e.g. $250 - $63 (6 months remaining of Starter plan).
For Sites on Connect Billing (deprecated) we will continue to pick the cheapest option based on our fees not what you charge your customer as this can vary (you could manually upgrade them to a higher plan if preferred).
If your site usage decreases and you believe it will not increase again then you might wish to Downgrade to a lower plan. Simply press Downgrade on the Subscriptions page, pick your chosen plan and request the Downgrade. The Downgrade will not take effect until the end of the current billing period. Note: You may prefer not to do this on Connect Billing to avoid lots of changes.
If you wish to cancel a site we recommend first discussing any issues with our Success team but alternatively you can delete the site via the portal. Please note deleting a site takes effect immediately and all data will be irretrievably lost. All payments are non-refundable so we recommend making full use of the current billing cycle before deleting the site (any remaining time will be forfeited).
Please see our full Payment Terms and Payment Failure Process in our End User Licence Agreement (sections 7 and 8).
The Siteglide Marketplace has a variety of useful Modules, Templates, Themes and Integrations.
Some of which have been built by Siteglide so that you can pick and choose which to install onto each site and reduce clutter/usage if they're not required. These are called Core Modules and are denoted by the 'by Siteglide' text under each title:
Find out more about the Core Modules:
Other Modules, Templates, Themes and Integrations have been built by the Siteglide Community of Experts including our services team, Sitegurus.
Sitegurus have built SiteBuilder, a tool to speed up development of web projects while ensuring best practice and quality. Check out the Marketplace Templates that leverage SiteBuilder:
Organise your Sites into Client Folders
The Clients feature in Portal is only available to Agencies and gives you an extra level of management allowing you to group multiple Sites under one Client and control who can see it.
You can create unlimited Clients and Invite Users who would then only have access to that Client area and any Sites linked to it.
You can access this from the left hand side menu but also from within your Agency Account.
If you invite a User within a Client they only have access to that Client Company and any Sites within it. It's very useful when a customer has multiple Sites but it's also a good way to keep Siteglide organised and clutter free!
The Sites tab shows the Sites linked to this Client Company. Create a new Site here to ensure it can only be seen by the right Clients (your Agency users can see ALL sites):
Add your own branding to the Siteglide Admin
Whitelabelling enables your Agency to re-brand the Siteglide portal by replacing our logo with your own. Re-branding the platform in this way means you are able to provide a more consistent, branded and streamlined service to your clients and maintain a single point of contact with them.
Over time we will continue increasing coverage of the whitelabling capabilities to include things like domain name, among others.
To re-brand your Portal and Admin, head over to the Agency Details page, upload your logo and enable "whitelabelling".
Below is an Endpoint and example snippets of code you can use to enable your Clients to login to Admin directly from your own Agency website.
You'll need the code below as a minimum. You can then add your own HTML/CSS/JS designs and branding on top.
An Agency only feature is being able to make copies of existing sites either to a blank Staging or to an existing Site (can be a Production Site):
To copy to a new Staging Site click the first radio button and then choose the Site Owner (your Agency or a Client folder) and give the Site a Name/URL:
To copy to an existing site (Trial or Production) click the second radio button and then choose the Site from the dropdown:
What is the CLI and Why use it?
Siteglide CLI (Command Line Interface) is a tool that enables you to work on your project from your local IDE or Code Editor; it has similar behaviours to FTP (File Transfer Protocol), in that you can sync up and pull down changes from your website.
Developers will be at home with the Siteglide CLI. It allows them to work faster than they can using the User Interface of the website. It also allows them to access the full suite of time-saving extensions and search tools in IDEs like VSCode and Atom.
But it's not just for Developers! Designers, SEO specialists and Agency Leaders may also find benefits to learning and using Siteglide CLI - allowing them to see an overview over their entire project and quickly find the files they're looking for.
Check the "File Structure" in each documentation topic, and this will help you find your way around the folders and files.
With CLI, we can validate code sent to the site. This is especially useful if you are syncing Liquid or GraphQL code where there are fewer 3rd party tools for linting. If there is a problem we can pick up automatically- the sync will fail and an error message will try to help you find the problem.
With Siteglide CLI we can keep track of the Code pushed to the Site from Admin and from local machines and make sure the Site always contains the most up to date pushes. It gives us scope to improve this functionality in the future.
Other CLI commands like siteglide-cli graphql and siteglide-cli logs
provide developers with advanced tools that would not be available with an FTP.
Siteglide Command Line Interface
Get started with our CLI
If unsure please read more about CLI first:
The Siteglide CLI can be installed from NPM using:
If you hit any issues please check our Troubleshooting guide:
Setup a local folder and use the site specific command to connect directly to your site (you can find this on the site details page in Portal - more info):
Need some help? Read our full Site Setup Guide:
You should now be ready to start work, you'll likely want to pull down the files from the server:
Check out our Reference article for a full list of useful Commands:
If you're using Flowbite/Tailwind please ensure you have Tailwind setup to compile CSS: Set Up Tailwind CSS with the recommended CLI method
If you're not an Agency and have a Business account visit: Account
If you are an approved Siteglide Agency you will have additional features accessible from the tabs across the top:
The Community Expert Details tab is where you can brand Siteglide to your Agency and create a page on the Experts area so users in need of your services can find you:
Read more about Whitelabelling Siteglide to your Agency:
The Marketplace Payment Details tab allows you to take payments for any Modules you sell in the Marketplace. You would need to use Stripe to take payments and insert your secret key:
The Partner Programme tab provides more information on how you can partner with us:
The Affiliate Programme tab lets you setup and control the affiliate commission for referring new users to Siteglide:
Siteglide is built for Digital Agencies by Agency owners that hit too many limitations with the platforms available. While anyone can use Siteglide it's designed with agencies in mind.
Approved Siteglide Agencies get various benefits and extra features to help them deliver the best results to end customers.
Connect to a site via CLI
You need CLI installed first, check out our Quickstart guide:
Once you've installed the CLI you should be ready to learn how to set up a new project folder and connect it to a specific Siteglide Site. You'll need to follow these steps every time you want to use the CLI to work on a new site, so over time these will become very familiar.
Your project folder will contain all of your Site's files.
Use Finder on Mac, or Windows Explorer to create this new empty folder, and give it a similar name to your site so you can find it again. We recommend creating this folder inside a sensible organisation structure, for example you may have a single folder which contains all of your project folders, or you might organise by customer.
In order for a CLI tool's ability to deploy and pull code from a Site to be useful, we need to have a good place to look at and change that code.
While you are free to use any kind of terminal or any kind of Text Editor, we'll use VSCode for these steps- one major benefit is that its integrated terminal allows you to easily manage your project in one place. It also comes with lots of useful extensions.
If you do not already have a text editor installed, you can browse for one or install VSCode here: https://code.visualstudio.com/download
You can then open your project folder in the Text Editor:
If your IDE or Text Editor does not have an integrated terminal, you can open any terminal and change directory to your project folder.
The terminal will appear in its own panel, by default below the code. In VSCode this will automatically change directory to your project folder (if not, do this manually)!
If you need to run multiple commands at once, you will need two terminals. In VSCode you can "split" the terminal window if you want to run multiple commands at once and keep an eye on all of them.
Open up the Siteglide Portal and find your Site in the Sites option in the left-hand-side menu.
In the Users tab, make sure your user's email address is listed. If not, invite yourself (as an existing user) to the Site.
In the Details tab, near the bottom of the Site information, find the CLI Command and copy it.
Paste the command into your integrated terminal.
When prompted, enter the Siteglide Password associated with the email address in the command.
This won't work unless you follow step 5 first! If you forget your password, you can reset your password on the Siteglide Portal first.
This command creates what we call an envrionment. Think of it as a connection between a project and a Site. Sometimes you may maintain a staging Site and a live Site for the same project and you might create both a staging and a production environment.
You will need to remember the name of your environment in order to use any other Siteglide-CLI commands, but if you forget, there will be a .siteglide-config file in the root of your project folder which will list them:
You're now set up with Siteglide-CLI for this Site! The obvious first move would be to pull the existing Site's files down to the Site, using the following command in the terminal:
This will create your directory structure and populate it with your site's files and assets (images will not be pulled due to their size - see export command).
If you use Github for backing up your code, debugging and undoing mistakes, it's a good idea to initiate it and make your initial commit now.
You now know how to set up Siteglide CLI on a Site! You can follow these steps every time you want to work on a new Site.
Next, check the Reference for how to:
Deploy all your code to the site
Sync individual files to the site as you save them
And remember how to pull all the code down to your project folder
The main commands you'll need when using Siteglide CLI
You need CLI installed first, check out our Quickstart guide:
These commands should be run from within the project folder. Commands follow the format of siteglide-cli <command> <env> <flags>
, so for example if you would like to view the logs of your production environment in "quiet mode", you would run:
siteglide-cli logs production -q
Please note that some commands may fail if you run them in your users home directory. We recommend a folder structure such as siteglide/
and then give each project/site it's own folder.
Command flags such as <command>
<env>
and <flags>
should be replaced with the relevant data. For example, <env>
should be replaced with the chosen name for the environment such as production
.
The first time you use the CLI with a project on your device, you will need to create an environment. This is essentially a config file that authorises your connection.
siteglide-cli add <env> --email me@mydomain.com --url https://my_great_site.com
You must use the email of your Siteglide partner account to replace me@mydomain.com and the development domain of the website you are connecting with to replace https://my_great_site.com
After your site goes live, you will only be able to add the development domain to an environment, not your main user-facing domain.
Replace with a chosen name for the environment, for example production
. On larger projects you may have more than one environment to allow you to interact with both staging and production websites.
siteglide-cli sync <env>
This command will setup a watcher that will automatically sync file saves and deletions when that action happens on your machine. To stop the sync running, enter use the shortcut control + c in your terminal.
Flags:
-l
: Turns on the live reload server. This enables automatic browser reloading of a page when a file is saved in your IDE.
siteglide-cli logs <env>
This command will output the last 20 logs and then a live list of logs from your site. Logs are written by using the log liquid code, for example: `
. To stop the logs running, enter use the shortcut
control + c` in your terminal
Flags: -f
: Filter log types -q
: Quiet mode
siteglide-cli -v
siteglide-cli help
Generates a list of valid Siteglide CLI commands available to you.
Deprecated - Please see the GUI command below
siteglide-cli gui <env>
This command will open up the GraphiQL and Liquid Evaluator editors locally. This will let you run Graph queries and mutations to test them out before creating them within your site. Also good for quickly getting data out of the database to check.
The Liquid evaluator tool lets you quickly test Liquid from the CLI, without having to create and save a page in Siteglide Admin.
To stop the GUI command running, enter use the shortcut control + c
in your terminal
Flags: -o
: Automatically open GraphiQL in default browser
siteglide-cli pull <env>
This will pull down all files from the site in to a folder named marketplace_builder within your current directory. During this process it will also overwrite any local versions of files if they already exist. If you have made any changes locally that you have not synced they WILL be overwritten.
Flags:
-i
: Ignore assets such as CSS and JS as part of the pull.
-m
: Provide the name of a module to download. Note that this will only download that module and not the site as well. This will only download the public
folder within the module, if the module only contains a private
folder then nothing will be downloaded.
Note: Assets such as images and videos are not downloaded as part of CLI Pull
siteglide-cli init
This will create a blank folder structure within the folder you run the command, which includes all folders that are automatically created for you when making a new website on Siteglide. If these folders already exist, you will receive an error and so it will not overwrite existing files.
siteglide-cli deploy <env>
If you have made a lot of changes in your codebase, then you can use deploy to re-send all files to your site at once. Deploy is a single command that will create a .zip file of your site and then upload that to your website.
Flags:
-w
: With assets, also deploys your sites assets
folder, supports total assets of up to 5GB.
siteglide-cli export <env>
Export is very similar to Pull, but it will also grab all data. This command will first grab all data from the site and export it into a data.json file, then it will run a pull to grab your code base.
Flags: -w
: With assets, also download asset files from your instance such as images and PDFs.
--csv
: Export the data files as CSV instead of JSON. Please note that these CSV's are currently not compatible with the ones that are exported/imported from Siteglide Admin
-a
: Only export assets and not the sites codebase. This by default will only export code related assets (CSS/JS etc) within the /assets folder. It can be mixed with -w above to export all assets
siteglide-cli migrate <env> --url <existing url>
Download and migrate an existing site to Siteglide using our site import tool. This tool will scrape the existing site, download all of the publicly accessible pages and assets, compress CSS/JS/images. The migrate command will also convert any existing forms (using the <form>
tag) to a "form to email" in Siteglide. When filled in, this will email the user who triggered the CLI migration with an autoresponder. These forms can then optionally be updated at a later date within Siteglide Admin.
Note: If you are using a Mac, running migrate in your “home” folder may fail. Please move into a different folder in terminal and then try again.
Flags:
--url
: Existing sites URL, usually the homepage. This flag is mandatory
-n
: No Optimization, skips the CSS/JS and Image optimization
-m
: A number to set the level of recursion that the scraper will search through the site. For example setting -m 1
will only follow 1 link deep from the entry page
-i
: A string to send to the scraper that if found in the URL it will ignore downloading that page. For example if your blog posts are links such as site.com/post/post-name
and you wanted to ignore them, you could use the flag -i /post/
This flag can be used multiple time such as -i /blog -i /posts/
siteglide-cli list
Output a list of environments you have previously added and their relative URLs for the current folder.
siteglide-cli modules <env>
Provides a list of modules installed onto the instance. These names can then be used in the pull
command to download the contents of that module.
In a Command Line, in any directory, type in:
If you already have siteglide-cli installed globally, this will tell you which version you have installed.
You can find out which is the latest version here:
The CLI is distributed via Node Package Manager (NPM) and so you will need NodeJS installed on your machine. The easiest way to get this is to visit and download the LTS version as this has better support.
Siteglide CLI requires a minimum of NodeJS version 10 but we recommend using the latest / LTS version
Open the download and follow the wizard with the default options to finish install.
You can use the following to install Siteglide CLI in any directory. The -g
flag instructs your machine to make this command available in any directory (globally)- so you only need to do this on your machine once.
npm i -g @siteglide/siteglide-cli
When an update is released for the CLI, you can use the same command as above to install the updated version. Please note that the flags for commands below are not available on all versions of the CLI, updating to the latest version will allow you to use all of them.
The following video will give you a complete walkthrough guide for setting up Siteglide CLI on a Windows machine. Feel free to skip ahead to the parts you find the most useful.
The following video will give you a complete walkthrough guide for setting up Siteglide CLI on a Mac. Feel free to skip ahead to the parts you find the most useful.
Read our in-depth guide:
Sometimes Siteglide support may ask you to run the CLI in "debug mode". This provides more output into your terminal so that we can use it to aid in supporting you. To do this, you need to prefix the command you are running with some extra information. This prefix differs slightly on macOS, Linux and Windows, for example if you were to want to sync to a site with debug mode on:
Note, for macOS and Linux, debugging will be turned on for that one command that you prefix. For Windows, debugging will be turned on for as long as Command Prompt or Powershell is open. Closing Command Prompt or Powershell and re-opening it will turn debug mode off.
We are using 99
as an example WebApp ID in this doc. Depending on the WebApp ID that you'd like to use, replace 99
with the correct ID. Keep in mind that if you already have WebApps in the site you are working on then then some WebApp IDs may already be reserved.
WebApps in Siteglide rely on 3 different files to work correctly.
JSON Structure - Used by Siteglide Admin and front-end to define structure of the WebApp with user-friendly names, and other UI metadata.
Schema - Used to define the database structure itself
Form Configuration - Used when submitting WebApp items front-end
There are 2 ways to create/edit a WebApp via CLI.
Safest - Create/Edit the JSON structure file (marketplace_builder/views/partials/tables/webapps/99.liquid
), and then in Siteglide Admin simply click 'Save' in the Table Builder view. This will generate a matching Form Configuration and Schema file.
Most flexible - Create/Edit each of the 3 files manually. However, this relies on you keeping all 3 files in sync.
This is used by Siteglide Admin to output WebApp field data with user-friendly names and other UI options (order, field type, etc.)
Location: marketplace_builder/views/partials/tables/webapps/99.liquid
Contents:
This is what defines the database table structure, and how data will be stored.
Location: marketplace_builder/custom_model_types/webapps/webapp_99.yml
Contents:
This is used when submitting a WebApp item front-end. This file was also previously used to output WebApp structure data in Siteglide Admin, but that is now the job of the JSON structure file.
Location: marketplace_builder/form_configurations/webapps/webapp_99.liquid
Contents:
After both the above files are synced you will then need to refresh Siteglide Admin and your WebApp will appear under WebApps in the sites left hand menu
If you need layouts for your WebApp, these will be saved to:
marketplace_builder/views/partials/layouts/webapps/webapp_99/detail/default.liquid
marketplace_builder/views/partials/layouts/webapps/webapp_99/list/default.liquid
Both files contain the following layout by default: <p>{{this['name']}}</p>
This Liquid is useful when you are accessing a WebApp 'collection', creating a Categories layout, using a custom GraphQL query and more.
Choose your favourite third party tool for parsing and formatting JSON. Everyone has a different favourite tool, but you can see a third party comparison here to help you get started and find one: We'll look at this again below in "Using a Third Party Tool to Visualise Objects"
Understanding dot notation is a really useful skill for Developers who are trying to get the most out of Siteglide and the platformOS technology it runs on. This Getting Started Article will cover:
What is dot notation?
How to find a property of an Object
How to chain dot-notation
The Data Tree
Visualising the Data Tree
You will come across the following terms which might be new:
Object
Array
Key-value Pairs
properties
Curly Bracket
This Article is intended to be the starting point for a Series of Articles involving dot notation.
Normally when you're accessing data on Siteglide, you simply want to access a single value. For example, on a Starter Site (using the WebApp installed by default, Gallery), you might need to output a Title on your Layout: {{this.Title}}
In this example, this outputs a String: The Latest Music
You could use this syntax from memory, or by referring to the Docs, but you're actually already using dot notation. The syntax above takes a variable this
which returns an object. .Title
is dot notation which specifies that the Developer wants to access the Title
which is a property of this
.
Note: Sometimes you may see something like this: {{this['Title']}}
This is the exactly same thing, except this alternative syntax also allows you to add spaces in field names. We'll cover this in more detail in the next Article.
Another important piece of terminology is the concept of a Key-Value Pair.
A key is a place where data is stored; a value is the data itself.
In the previous example, this
and Title
are both keys. The key Title
has the value The Latest Music
.
You can chain dot notation. The following example will output the first name of the User currently signed in to a Secure Zone: {{context.current_user.first_name}}
This accesses the context
object, then accesses its current_user
property and finally accesses the id
property of current_user
. current_user
can be considered an Object, because it has properties of its own, however, id
has no properties and is stored as a String.
You can think of objects in pOS and Siteglide as a Tree. The Object you start on like context
or this
is like the trunk of the tree. Each time you use a dot to access a property, you are going one level down the tree, until you reach the branch of data you needed.
Just outputting this
on its own would show you the real JSON Object behind the first example in this Article and all of its properties: {{this}}
This outputs an object of data, which to start with is a little hard to read. That's because whitespace is removed for efficiency reasons. Adding the whitespace back in with a third party tool will allow us to read it more easily (see the next section).
To make sense of the JSON that the Liquid outputs, you'll need a tool for automatically formatting the JSON data and adding whitespace. Some tools even help you visualise the data in other more advanced ways.
Important Note
We'd recommend when parsing JSON using third party tools that you do not use sensitive Client data. It's best to use test data and publically accessible data when testing and developing dot-notation. We cannot verify that any third party tool will handle your data safely.
Here is an example of a tree-view. It's the JSON data with extra whitespace and newlines added for readability (colours too).
From this view you can make the same observations we made when using the <pre> tag, but it is easier because each level of the tree is indented and all keys are coloured light blue:
The first and last character is a curly bracket- this represents the this object we are accessing.
The key id has no properties, it has a value of 98656
which is stored as a String. this.id will be enough to access it.
The key properties has properties which are accessible by dot notation. You can tell because the properties key is followed by more curly brackets indicating that it is an object. All the properties inside this set of curly brackets are properties of properties. `{{this.properties.name}}`
will access the name property of properties.
Here is a chart view from the same tool. It shows more clearly how some objects are nested within others. You can use this to help you chain dot-notation to get the values you need.
You may notice that category_array
looks slightly different in the examples above. This is because its value is an array. You can notice an array in your data when square brackets are used around a list of values separated by commas e.g "category_array":["98479", "111111"]
We will cover arrays in the next Article: Advanced Dot Notation: Arrays and Key Maps
How to use Liquid For Loops and Indexing to handle arrays. Also, how to use a key to access key maps, using categories as an example.
This Article is the second in a series on using Dot Notation in Siteglide. We strongly recommend reading the Article below first:
If you're using dot notation, you'll probably come across arrays and maps. The syntax for dealing with them is slightly different, but this actually makes them more powerful when you're building complex Layouts.
The examples below focus mainly on Categories because they are a good example of arrays and maps.
An array is a group or list of data. A key might have a single value, or an array of values.
In Siteglide for example, each WebApp item for example has a field called category_array
which stores a list of the IDs of every Category assigned to that item. The more categories an item belongs to, the longer the array. E.g. { "category_array":["98479", "111111"] }
If you try to use standard dot notation as we practised in the previous Article, you will be able to output the array as it is using the key category_array
and the liquid {{this.category_array}}
:
["98479", "111111"]
However, there aren't many places where this would actually be helpful. It would probably be more useful to do one of the following:
Access one of the Array items by its Index
Loop over the array Items
Find the length of the array (how many items are there?)
Arrays have an index, which means they are numbered. In Siteglide (and in JavaScript) Arrays are zero-indexed, meaning the first item has the index of 0
while the second item has the index of 1
.
We can access the first value in the category_array
by its index using the following Liquid: {{this.category_array[0]}}
outputs 98479
Note that straight after the key, we give the index number of the value we want in square brackets. If the array contained objects, you could go a step further and access one of their properties with a dot after the square brackets.
We can access all values in the Array using a Liquid For Loop:
This outputs:
You can find the length of an array using a Liquid filter: {{this.category_array | size}}
outputs: 2
As well as arrays, you might come across a map of data. Here is an example which can be tried on any Siteglide Starter Site using the Liquid: {{context.exports.categories}}
It outputs something like this (but I've shortened it here!):
A map is used to store data when you know the ID of an item and want to fetch it using it's ID as a key. In Siteglide we use them for performance reasons. You can tell this is a map, because the key items
contains several comma-separated objects instead of a single value. Each of these has a key representing an ID, instead of the name of a property.
Let's say you have the ID of a category, but you want to display the Category's name: {{context.exports.categories.items["98490"].name}}
This outputs: Women
This sounds odd, but it's the name of the eCommerce Category we wanted! You can achieve the same if you have the ID stored as a variable:
You can loop over all keys in a key map using a Liquid FOR loop. Inside the loop, each key-value pair is treated as an array with the key being the first item in the array and the value being the second and last value in the array.
In this example, we'll loop over all Categories in context.exports.categories.data
and see what data is available to output:
Here's a challenge you can try.
Can you create a WebApp with Categories and in your Layout output a list of the Category names that belong to the item?
Step 1) Create a WebApp and assign more than one Category to each of the Items. Step 2) In the Layout, access the this object. Step 3) Use your Understanding of arrays to loop through every category belonging to the item. Step 4) Use your understanding of maps to find the name of each category in the Loop and output it.
Next, we'll look at how you can use dot-notation to work with WebApp collections: Using WebApp Collections
Take control over your WebApp Layouts by exposing the Data and making your own For Loop with Liquid
In this Tutorial, we'll be using dot notation, so if you're not familiar with it, you may want to brush up here:
You'll also need to be familiar with WebApps:
By default in Siteglide, when you include a WebApp, we query the database and loop over the items for you. We take the data inside the loop and assign it to a variable called this
which holds dynamic data about the current item. In certain situations, you may want to do something different, so we have provided the optional parameter collection
.
Setting collection to 'true'
makes the data from the behind-the-scenes query available to you directly, without a layout.
In the following example, we show the difference between a WebApp list which does use Collection and one which doesn't:
This outputs:
To break it down further, setting collection to true
exports the data to {{context.exports}}
Under that, you can access it by the id of the WebApp in the original include
tag. In this example, it's 1
so we can access {{context.exports.webapp_1.data | json}}
.
You can then use dot notation to access the data as you wish.
When would you use collection?
Well some people will prefer to always use collection, others will prefer to use layouts. One possible use-case where Collection works better though is if you want to display the same WebApp twice on the Page but differently each time.
For example, what if you wanted to display the first item largely at the top, then display other items in smaller cards below?
You could use the `
` tag twice to achieve this, with different Layouts each time, but this would have a negative effect on performance. This would slow the Page down, because we would be querying the database behind the scenes twice (once for every time you include the tag).
Alternatively, you could include the webapp just once as a collection, then use Liquid to display the items you want in the way you want:
This outputs:
Great! Only one query needed behind the scenes and we've nearly met the objective, but there's one problem. The item "A Special Guest Appearance" has been included twice!
We can use the offset
parameter on our loop tag to start the loop at a different index. Let's skip the first index when we loop, as this item has already been displayed.
Hang on, wasn't the point of Collections to avoid Layouts? Not quite! The idea was to give you control over the loop- layouts are still possible. I can still include my portfolio_2
layout, but I need to work out its path from SITE MANAGER / Code Editor in Admin.
I can now include the Layout at this Path: `
`
The Layout is expecting an object called this
containing the data, but as in the example above we already assigned variables called this
containing the right data, the Layout works without further modification:
Check the current version of Siteglide CLI you are running. See the to find the latest version number. If you need to update, see the "Installing & Updating" command section above.
The steps followed in the video can be found . If you are using zsh as your shell then the commands here will have to be run against the ~/.zshrc
file, not ~/.profile
. ZSH is the default for Macs since macOS Catalina, to find out which shell you are using you can run echo ${SHELL}
in terminal. If the ~/.profile
or ~/.zshrc
files do not already exist then you may need to create them first before running the export PATH command
Please see the document for all the relevant types.
The above are all the default fields that are needed, the last field is an example of a standard text field. Please see the document for all the relevant types.
We don't have a favourite JSON parsing tool, but you can see a third-party comparison here: Many Code Editing environments like VSCode also have a useful extension for prettifying JSON data.
You can do a lot with loops. Offset is just one of your options. Head to the pOS documentation to learn more about loops in Liquid:
Want to use Liquid Dot Notation to find dynamic data on your Site? The context variable is most likely the place to look.
In this Article, we'll be using dot notation, so if you're not familiar with it, you may want to brush up here:
Advanced Dot Notation - Arrays and Key Maps - You might not need to fully understand this topic- but a first read of it will be very useful in helping you to recognise the more difficult to handle types of data structure- even if you're not ready to tackle them yet.
Once you've got a good understanding of Liquid Dot Notation, the next step is branch out and discover what is possible.
Here are some of the most useful places to look for data:
{{context}}
The platformOS object context
contains a huge tree of information about your Site- often including variables you didn't know you wanted until you discovered them.
{{context.exports}}
The object exports
sits on the root level of context
and its role is to allow a global storage location for any custom variables not already included in context
. You'll mostly use it as a place to access Siteglide specific data, for example, it is the home of data relating to Siteglide categories and will contain WebApp or module data when you use the collection
parameter in the include
tag. exports
will also contain any keys that you have entered within the Integrations area in Siteglide Admin. You can also add your own data to a namespace in exports
- see the platformOS docs to see how. This is especially useful if you want to include some data in a Content Section, Code Snippet or Layout- but access it in on a higher level e.g. the Page Template.
{{this}}
- This is a Siteglide variable containing data specific to a Layout- you'll only be able to use if within a Layout file. The data will completely change depending on the type of content, so it's a good place to use Dot Notation to explore each time you try a new feature.
In this article, we'll explore the context
object in more detail.
The this
object is used differently in different features, so the best place to learn about it is by reading the documentation on the specific feature you're using it with.
The context
object's role is to provide your Site with contextual information which might help it render HTML in a more flexible and personalised way.
Context should be available in any Liquid file, and this includes auto-responder and workflow notifications. However, bear in mind that context may work subtly differently in an email- for example- it's not possible to see information about the person reading an email- current_user
would refer to the person submitting the Form which triggers the email to be queued.
We'll go through the top level of context's keys and explain each namespace's role. Beyond that, you will have to explore for yourself!
If a property is marked advanced only, it is because we haven't found a use-case for it yet on a Siteglide site, or they are not supported, or there is a newer version of this property which is easier to use. We may mark a feature as advanced only because it is possible for it to conflict with a Siteglide feature and it needs to be used with caution. You may be able to discover your own Use Cases for these- if so we'd be very interested to hear about them! To be clear, we can't offer support if these are used in your Site, but we're noting them here in order to be comprehensive.
Advanced only - You won't need to use this directly- it is a frequently changing token used as part of the security on form submissions.
platformOS uses a single cookie to identify a visitor- whether signed in or not. The session
object holds information in the database which relates to the visitor with that cookie. This is used in Siteglide eCommerce to allow us to identify someone who has added items to a Cart, without requiring them to Sign In. Learn more about how we use this essential cookie here.
***Adding Session Fields ***You can add fields to session and exports objects only.
The easiest way to add session fields is to use the
You can then use logic to only show these features to Users who have opted-in.
***Removing Session Fields ***To continue our previous example, if the User chooses to change their preferences and opt out, you can forget the setting by setting it to an empty String:
Ending a Session- Advanced only You can use custom GraphQL to completely forget a visitor and end their session. Use at your own risk as we cannot support Secure Zones with Users who have had their Session ended in this way: https://documentation.platformos.com/api-reference/graphql/mutations#user_session_destroy
Unlike session
, this only holds information relating to a User if they are currently logged in to a Secure Zone. It is more sensitive than `session`
and will include a name and email address. If there is no current_user, it will hold the value null
.
Headers are information sent and received when a browser sends a request to a server for an HTML Page. This is a technical area which can be nevertheless useful on some every-day use cases.
For example, in this Article, we show you how to set up canonical URLs. We use the headers
object to grab a useful version of the URL: https://developers.siteglide.com/preventing-duplicate-content-with-query-parameters-canonical-url-and-robotstxt
Another helpful property is HTTP_REFERER
. This tells you the URL of the Page that the User was visited before the current one- assuming this was not deliberately hidden. This can be really useful for redirecting a User back to a particular Page after carrying out an Action.
This object helpfully takes the URL of the current Page and dissects it into chunks which you can use.
slugs refer to parts of a URL separated by forward slashes / - slug, slug2 and slug3 will be available to you only if they exist. This can be helpful if you're implementing breadcrumbs.
query parameters will become available to you if they exist and will be available under the same key they use in the URL. E.g. a parameter in the URL https://siteglide.com?password=test will become available here: {{context.params.password}}
Advanced only- When using CLI- params
can also be used in a form_configuration to interrogate the form data being sent to the server, including virtual fields.
Advanced only- You can ignore this, as Siteglide does not support this pOS feature.
Advanced only- This will currently only read the value of "Production" as currently all Siteglide Sites are Production ready- but watch this space!
Advanced only - Returns true if the Page is being rendered by an XHR (sometimes referred to as Ajax) Request.
This is analogous to "location" in JavaScript and can provide you with useful URL information.
{{context.location.url}}
will get you the full absolute URL for the current Page
{{context.location.href}}
will get you the relative URL for the current Page without query parameters- useful if you want to set new query parameters!
{{context.location.pathname}}
will get you the relative URL for the current Page including query parameters.
This Object is often useful when you use it alongside params
.
This contains metadata for the Page.
This actually gives you metadata relating to the chosen Page Template, not about Layouts on the Page.
This contains objects for each module you have installed on your Site. It includes Siteglide Modules and any Modules you've installed via platformOS. It only contains metadata- if you want data relating to items in that Module, you'll have to access it in a Layout with {{this}}
or through making a collection
and then looking in {{context.exports}}
.
Advanced only- Contains the IP Address of the visitor.
Advanced only-
Advanced only- Use device
instead!
Device should give you information about your visitor's device, operating system and browser. However, use it with caution - you'll still need to make websites responsive! You could use this to suggest to certain Users that they will have a better experience if they update their browser to a modern one.
This lists the cookies currently used by the Site.
Siteglide only uses the session cookie directly which you can learn more about here: https://help.siteglide.com/en/article/the-cookies-we-use-on-a-site-you-build-with-siteglide-yjurtu/
Any payment gateways you are using as part of Siteglide eCommerce e.g. Stripe may also have a cookie listed here.
You may also see cookies relating to browser extensions. Ignore these- as your Users will have different extensions to your Developers!
Advanced only
Advanced only
Advanced only
This is where all context data is kept which is custom- either to Siteglide or that you have added to your Site.
The pOS documentation covers Liquid comprehensibly and includes Liquid functionality specific to the pOS Platform and Siteglide.
Siteglide runs on platformOS and we use their implementation of Liquid which adds a large range of useful functionality.
The best place to start learning is their Introduction to Liquid documentation, which will explain the different types of Liquid syntax. From there, you can find more helpful documentation on the Liquid topic you are interested in.
Some useful Liquid tags:
Although it can feel like a big leap at first, using custom GraphQL gives you ultimate control over dynamic data. We'll guide you through.
Firstly, let's go through a few frequently asked questions about GraphQL. In the next article, we'll then get started on our first Query on a new Starter Site.
GraphQL is an open-source querying language which was originally developed by Facebook. The general idea was to create a language which allowed Developers to quickly develop flexible requests for data, while being efficient and only asking for exactly the data they needed. The structure of the query, including relationships between different tables, matches the structure of results- making it easy to iterate over the data after the query is complete. You can read about the open-source project on their website here: https://graphql.org/
It's worth noting that you don't need to learn GraphQL to use Siteglide's core features. Most of the time, Siteglide does the querying for you. However, learning GraphQL will allow your Agency to take on more challenging projects- see the next question.
Although the language is open source, actual implementations of it can be quite different across platforms. This is because a GraphQL implementation has two parts:
The Schema - this defines different types of Query you can use, which parameters you can add, and what sort of output you can request. It reflects, in part, the database structure that the Platform uses, so it varies from Platform to Platform. Siteglide runs on platformOS and we use platformOS's implementation of GraphQL.
The Query Language - This is the syntax for writing queries- it is exactly the same across platforms, but can feel very different when the Schema is different.
If you've used GraphQL before with a different Schema, you will start to see lots of similarities.
Liquid is a templating language; GraphQL is a query language. To put it another way, think of GraphQL as a re-usable question.
Liquid will both ask the question- and listen to the answer, using it to build a dynamic website. The question itself is in a different language: GraphQL.
GraphQL files are stored inside the marketplace_builder folder. They can be called by Liquid and re-used as many times as you like.
GraphQL can be tricky to get started with, but most of our Developers report that at a certain stage, it just 'clicks' for them. We want to help any Agency who wants to learn to get there.
We'll provide a series of Tutorials, starting off simple and becoming progressively more challenging. As part of this, we'll aim to give you the skills you need to carry out further learning yourself- often this will mean learning to read the platformOS schema- finding the type of query you need, and experimenting with how to make it work.
Every time we add a new GraphQL Tutorial, you'll be able to access increased support on that topic via the Forum. You can see an overview of the topics we've covered so far here
In the next Tutorial, we'll show you how to use the GraphQL sandbox to test out Queries. Let's go
We want to give you all the tools you need to learn GraphQL and we'll give our general tips, tricks and links to help you solve problems. Unfortunately, Siteglide support can't build a custom Page for you or assist with custom GraphQL questions - we want to stick to providing first class support on the core product.
If you're stuck, here are some things you can try:
Help us improve our general documentation on GraphQL. We'll keep adding and improving on our articles. See the "did this page help you" buttons at the bottom of each developer docs page.
Ask the Community on Discord. We have an ever-growing Community of developers from around the globe, join the discussion.
Siteglide's custom support partner, Sitegurus, can provide developers who are experts in using GraphQL with Siteglide. Create a task with SiteGurus
Maybe this particular solution isn't suited to custom GraphQL, maybe it's better as an official feature? You can request features on the Roadmap.
Writing GraphQL queries gives you ultimate control over your dynamic data. Now, for a small Site, it's probably faster to use Siteglide's pre-built features to cover this for you.
Here are some examples of where some custom GraphQL could open some doors for your Agency. We'll update this list with tutorials and suggestions in the future:
Get any data from your Siteglide instance
Reporting- Your Client wants several bespoke, complex queries of data, all organised into tables and charts? GraphQL can help you be this flexible and if implemented well, can maintain page speed.
GraphQL works inside workflow and autoresponder emails. With mutations, it can also send transactional notifications and API calls from anywhere in your Site.
Performance optimisation- We do our best to make sure all Siteglide features are delivered to you with the maximum flexibility and performance, but for very bespoke Sites we couldn't possibly make the Platform guess your priorities. Understanding GraphQL could help you optimise your most complex features for faster Page load time, while using ready-built features to save development time in other areas.
**Front End Mutations- **Use at your own risk! With mutations, you can change data in the database and trigger this with Liquid. This can make a lot of complex projects possible- see the platformOS GraphQL schema for a full list: https://documentation.platformos.com/api-reference/graphql/mutations
Update data without loading the Page- When changing Page in WebApp results, you currently have to wait for the Page to reload. Using Siteglide-CLI and GraphQL you can build an XHR endpoint to get updated data after the Page has loaded. (Note: you can do this with CLI, without GraphQL- GraphQL just gives you more flexibility.)
Jump ahead of the Roadmap- We're always updating our Roadmap with new functionality and Community requests. But what if you have that one Client that cannot wait? It'll take more time to Develop and may not be as re-usable as a fully tested official feature, but with GraphQL and Liquid understanding, you've got the power to build your own solutions.
Our first tutorial will get you set up on the GraphQL playground/ sandbox which we make available through Siteglide-CLI.
How to check if a variable exists/ is null/ is false?
Not all the variables on Siteglide will be stored as either "true" or "false". In many scenarios something may exist in one location, and simply not exist in another . To better explain this i'll use a homepage as an example:
Whether a page is the homepage or not is determined by the is_homepage variable: is_homepage
which has the value true
. However if a Page is not the homepage, rather than is_homepage
being set to false
, the is_homepage
variable doesn't exist.
Say I wanted to run some code on every Page that isn't the homepage, I'd write something like this:
This would work fine if we were on the Homepage, as the variable's value would be true. However, on other Pages, it would not behave as expected, as is_homepage would be undefined..
Now lets look at the Liquid keyword "blank". This refers to having a value of either: Empty, Null or False.
If I now check "is_homepage" like so:
This will now work!
We look at a possible answer to Tutorial 3's challenge. This shows how to write a query which fetches all WebApp items, not Module items.
This Article shows the Answers to a Challenge. If you've not had a go at the challenge yet, we'd recommend you head there first.
About GraphQL- optional- Read more about GraphQL and when it might be best used.
The trick here was to examine the tables
and spot the common patterns in their values.
The two types of records
we wanted had these tables
beginning with "webapp_":
webapp_1
webapp_2
The types of records
we don't want have table
values without "webapp_", for example:
module_3
- (Blog Module)
module_14
- (eCommerce Module)
form_1
- Newsletter Sign Up Form Submissions
So, in order to filter for the records
we do want and not the records
we don't want, we need records
which start with the string webapp_
.
Code:
Notes:
In this method, there is no need to write one filter to include webapp
items and another to remove module
and form
items from the Results. This is because the given rule efficiently achieves both at once.
Explorer:
This is just one possible answer, you may have found a different method.
Try and make sure you choose the best method for your use case. You should always be looking out for a more efficient way of doing things.
We'll continue to look at filtering queries in more detail, including:
filtering by different fields, or properties
filtering with different kinds of rules
using more than one filter at once
Let's go!
In our Tutorial 4 challenge, we asked you to write a query which returned items matching multiple filter rules. Here's a possible solution.
This Article shows the Answers to a Challenge. If you've not had a go at the challenge yet, we'd recommend you head there first.
About GraphQL- optional- Read more about GraphQL and when it might be best used.
Last time, we asked you to write a single query which utilised a combination of filters to find records
which meet these criteria:
They are Module Items
They are enabled
They have already been released
They have not yet expired
They have a `weighting`
between 1 and 3
They have a meta_title
They fall into the posters Category
This challenge required you to modify and combine the queries we'd already looked at. If you were able to match at least some of the criteria, good work.
To find the category_id for the posters
Category. One way to do it would have been to go to the Siteglide Admin:
After that, it was a case of combining what you'd learned so far to add multiple filters to a query:
Notes:
For the range
of weighting
we've added a gte
and lte
setting, in order to demonstrate the possibility. This is not really necessary as there won't be values less than 0, but it's not a bad idea to rule these out, should data be entered incorrectly.
The category_array
ID may be different from one site to another. Check your site's category_id
in the Admin.
Explorer: Unfortunately, as mentioned last time, Explorer does not yet support arrays, so it's not possible to show an Explorer demo for this challenge.
It's time for the real thing! We'll look at how you can save your GraphQL query in a File and use Liquid to run it on a website Page.
Let's go!
Turning the Page! In tutorial 2, we'll control how many items Graph returns on each Page of results and retrieve specific Pages.
You have completed the first Learning GraphQL tutorial.
About GraphQL- optional- Read more about GraphQL and when it might be best used.
When GraphQL returns results, it will organise them into pages.
This allows it to be more efficient, as it only returns the data that is needed straight away. At the same time, the rest of the pages are organised ready for the next request.
You'll always need to think about Pagination when using GraphQL, even you only want to retrieve the first Page of results.
per page
is an argument used to define the number of results that will be returned on each page.
It's now a mandatory argument on some types of query so we've already got the argument in our query from the last tutorial:
Experiment by changing the integer in the argument from 20
to another value, e.g. 1
. Observe the difference. It's recommended to keep the per_page number as low as possible- for efficiency and performance.
Let's consider a few situations:
You want to display 3 items - Set per_page
to 3- only the three items you need will be retrieved.
You want to display 20 items at a time, but allow the user to view the next 20 when they've finished reading - Set per_page
to 20
If you want the user to be able to change per_page
dynamically, we'll cover this when we look at variables in a future tutorial.
If you think you need to display more than 2000 items at a time (perhaps to provide data to a JavaScript plugin), consider using GET requests to a custom Liquid endpoint page to fetch each page of results asynchronously. You can learn more in Tutorial 8 - Building a Liquid API GET Endpoint Page powered by GraphQL queries but we recommend working through the other tutorials first.
You can return pagination metadata alongside your query results:
current_page
- Returns the number of the current page.
per_page
- Returns the number of items on every page.
has_previous_page
- A boolean which is true if there is a page before the current page.
has_next_page
- A boolean which is true if there is a page after the current page.
total_pages
- Returns an integer representing the total number of pages in these results.
These optional properties can be requested alongside total_entries
and your results
object, like in the example below. Try them out. Code:
Notes:
Properties like has_next_page
and has_previous_page
are most useful for adding pagination buttons of your own.
You can see that by default, we get the first page of results- so page
returns 1
.
Explorer:
You can view other pages by setting the page
argument to the page of results you'd like to see.
Code:
Explorer:
In the next Article, we'll look at how to filter results.
For example, we'll learn how to return items from only a specific WebApp.
Let's go!
Following on from the previous tutorial, we'll look at more advanced filtering options and show how you can filter with multiple rules.
You have completed the Learning GraphQL tutorials 1 - 3
About GraphQL- optional- Read more about GraphQL and when it might be best used.
In the last tutorial, we looked at how to filter your results so that only items from webapp_1
were returned. We also challenged you to see if you could adjust the query so that it returned all WebApp items.
This time, we'll look at:
filtering by different fields, or properties
filtering with different kinds of rules
using more than one filter at once
Some fields in records
are defined in the GraphQL schema, like table
, this often means they have their own filter option in the documentation. Siteglide fields, and your own custom fields, are very likely to be custom "properties" which are not directly defined by the schema.
If you're not sure, check the schema for the field you're looking for. If you can't find it, it's a property.
For example, release_date
is not a custom field in the Siteglide Admin, but it's not in the list of available fields to filter by in the schema- so we'll need to use properties.
A brief note on name
. You'll see the term name
available in the schema- but this is a deprecated way of referring to the table
e.g. webapp_1
. To fetch the name of the item in the Siteglide Admin, you'll need properties.name
.
In our next example query, we'll demonstrate this. Let's search for items with a properties.name
that have the exact value of the string "music".
Code:
Notes:
See that properties uses a colon : and then curly braces { }
as we have usually used so far. Properties can instead be used to store an array of filter objects, but we'll look at this later.
Note that we have to specify inside the curly braces both the name
of the property we want to filter by (which happens here to also be called name
, but it could also have been something else like release_date
) and the method we'll be matching the value by, in this case contains: music
.
Explorer: Adding a single filter to properties can be done with the Explorer wizard. However, if you want to be able to filter by an array of different properties, Explorer has no support for this yet, but it is possible by writing in the query manually.
This section of the docs used to have an example which used the "contains" comparison rather than "value". Good practice is to use "value" where possible for the best speed and performance. If you need "contains" functionality, consider whether using fulltext: {keyword: $search_keywords}
search will meet your requirements instead?
In the examples so far, we've only filtered by strings- or in other words, groups of letters or characters. Next we'll look at some other data types:
Booleans
Integers / Epoch Date stamps
Arrays
A good example of a Boolean property in Siteglide is enabled
. This is a property which is stored as either true
or false
. Let's find all the items which are currently enabled:
Code:
Notes:
Again, we need to specify the name of the property we'll be filtering by, this time: enabled
.
We'll use value_boolean
as the most appropriate way to match an exact Boolean value. It's not the only method we could choose from the documentation, but it's more specialised to filtering Booleans, so is potentially faster.
Explorer:
When filtering by integers (which also includes Siteglide's release_date
and expiry_date
fields, as these are stored as Epoch Timestamps) you've got a choice whether to filter by values or a range of values.
Code:
Notes:
value_int
works the same as value_boolean
but is designed to handle the different type of data more efficiently.
Be aware that running this query yourself on a Starter Site may produce no results. This is the correct result, because Starter Site does not at the time of writing ship with any weightings set. If you add a weighting of 1
in the Admin, you'll see it appear in the results.
Explorer:
Most often, you'll want to use more complex comparisons for integers. We'll look at how to do this next- at the same time, we'll take a look at how Siteglide normally formats dates.
The dates are stored in Epoch Timestamp format, which is an integer storing the number of seconds which have elapsed since the Epoch. You can convert a date of your choice to this format here: https://www.epochconverter.com/
In this example, I'll use the time at the current time of writing: 1582108820
. Let's query for all items which have already been released. In other words, the value stored in release_date
should be less than, or equal to, the current timestamp. When you're thinking about dates, you can think of "less than" as meaning "before" and "greater than" as meaning "after". So here we're asking for "items with a release_date before now".
Code:
Notes:
The range filter requires you create a new object { }
containing some logical comparison operators. You can choose between the operators in the documentation panel- see below.
Documentation Panel:
Available operators can be seen under RangeFilter
. They are short for Greater Than
, Greater Than or Equal
, Less Than
and Less Than or Equal
.
Explorer:
An array is a list of data. One good example in Siteglide is category_array
, which stores a list of unique IDs that refer to categories. We can now write a query to find items in a particular category.
Code:
Notes:
value_in
is special to fields which have an array data type.
It takes an array of strings ["string_1", "string_2"]
as its value. Here we are just using one category ID as an example. You could experiment with combinations of category_ids.
Explorer: Only partial support is currently available in Explorer for this. It's not so good at handling arrays. So you can select the property in Explorer, but you'll need to add the value manually into your query.
So firstly, implement with the wizard:
Secondly, change the value manually in the code from:
value_in: "158198"
...to: value_in: ["158198"]
For all the filters you've learned in this Article and the previous Article, you can apply more than one at once.
Notes:
In this example, table
and properties are both chosen as filter options.
properties
takes an array (denoted by square brackets [ ]
) of objects (denoted by curly braces { }
Each pair of curly braces { }
inside properties
should contain the name
of the property and an independent filtering method e.g. range
or value
which will be used.
Using a combination of filters in this way generally follows AND logic. Items must pass all of the filtering tests you choose before they are returned.
Explorer: Unfortunately, arrays are not currently supported in Explorer, so you'll have to enter this section of the query manually for now.
You can also find items where a property does, or doesn't exist.
In this example, we're looking for WebApps where a meta_title
was not added.
Code:
Notes:
exists accepts a Boolean, so you can use false
or true
. This shouldn't be wrapped in quotes, because Booleans don't require them.
Explorer:
What if you are looking to filter records
so you can find records
which fit either one rule or another- but don't need to match both rules?
Here's an example from the pOS team of how you can use the "or" option when filtering. In this example we get records
where either a webapp_field_1_1
exists OR a field parent
exists.
Notes:
Inside filter
we add an or property and an array with square brackets []
This array takes one or more objects with curly braces {}
each Object is compared with OR logic. Within the object, you can use the same properties you might normally use inside filter
.
You can add multiple filter properties inside each object, but these will be compared with AND logic. So, to filter records by those which have both ( webapp_field_1_1
AND webapp_field_1_2
) OR "parent", you would do the following:
See if you can write one query which uses multiple filters. Try and return records
which meet these criteria:
They are an item from a record
with a table
starting with module_
.
They are enabled
They have already been released
They have not yet expired
They have a weighting between 1 and 3
They have a meta_title
They fall into the posters
category
Hint: This search is so specific, that by default on Starter Site it will return no results. Try creating an eCommerce Product which meets these criteria before you start- that way, you'll know when you've succeeded.
It's unusual to run this many filters at once. Most of the time in a real use case, you'd have less to write than this! However, putting together everything you've done so far will be good practice.
We'll look at the answer to this Challenge in the next Article.
We'll look at a possible solution to our latest challenge question.
After that, we'll look at how to run a query on a real Siteglide Site for the first time- and look at what you can do with the results.
Hello WebApp! In Tutorial 1, we'll use Siteglide CLI to open the GraphQL sandbox. There, you'll write your first query and retrieve details about some webapp items.
Create a new Site from the Flowbite Portal Site Template. We'll use this in the examples
Siteglide-CLI - You'll need to understand how to open terminal on your machine and navigate to your Project's root folder. You'll need to have installed Siteglide-CLI and its dependency Node.js. You can't use GraphQL without Siteglide-CLI.
About GraphQL- optional- Read more about GraphQL and when it might be best used.
In this first of the GraphQL Tutorials, you'll need to either create a new Starter Site, or open up a Starter Site you've created previously.
We'll use Siteglide CLI to open the GraphQL sandbox. There, you'll write your first query- which will ask for all the data on the entire Starter Site!
The GraphQl sandbox is a place for testing Graph Queries. It has the additional benefits of giving you suggestions and documentation alongside your code.
When you open the sandbox- you'll be opening it with your chosen environment. This means you're picking a Siteglide Site to give the sandbox access to- it will be able to find database items from this Site.
For these tutorials, we strongly suggest you use a Starter Site- because then you'll have exactly the same data and it will be ready to go.
Change directory into your project folder (create a folder first if you don't have one).
Then add your Site as an environment - the quickest way to do this is to copy the CLI command from your site in the Portal- or you can replace the --url and --email flags with your own. Add your Siteglide Admin password when prompted:
The command for running the sandbox is (replace the staging
placeholder with the name you chose in the previous step):
siteglide-cli gui staging
Success should look like this:
Click, Ctrl+click (if your machine allows), or copy the "GraphQL Browser" link into a browser. This will open the sandbox.
Short Method: If you want to save time and skip the step of opening the link, add the flag -o to automatically open the link after you run the command:
siteglide-cli gui my_env -o
Your First Look at the GraphiQL Sandbox
To start with a few important features are hidden. Click and drag up the QUERY VARIABLES
panel from the bottom left and click the < Docs
button in the top right. We'll come back to these later.
Click the "Toggle Explorer" button to open the Explorer wizard. This is a new tool which will make writing (non-deprecated) queries even easier.
You've now set up your GraphiQL sandbox!
The Central Panel
This is where you write your Query
The Results Panel This is where the data will be displayed in JSON format after your query fetches it.
Query Variables Panel This is where you'll be able to simulate dynamic variable inputs when testing variables in your Query.
We'll cover this in a later Article.
Explorer Panel *NEW* This displays the GraphQL schema in the form of a "wizard". Tick the options you want to include and they will automatically be added to your query. This is the most user-friendly way to write queries for beginners (and possibly for the experienced GraphQL developers as well!). Note the explorer user-interface can't handle arrays of query language very well e.g. when filtering by multiple properties, even though it's valid GraphQL; when you hit a limitation like this, it's time to leave the explorer behind and write the code manually.
The other limitation is that it doesn't currently support older deprecated query and mutation types, if you have a need to use those.
Documentation Explorer Panel
This displays the available GraphQL schema as documentation. It works with nested levels, so each time you choose an option you can "click through" to the next level of options you can include.
This is less user-friendly than the new "Explorer" panel above, but can still be useful:
especially if you want to use a deprecated query like "customisations" (The only reason for using deprecated queries is that some support features like keyword search that are not supported on the more modern queries yet)
If you want to search the schema for features and understand which types are allowed
platformOS sometimes changes the names of elements of their schema for the sake of better communication or as part of a functionality update. For example, models
have been now renamed to records
.
We are in the process of upgrading these docs to refer to records
instead of models
but in the meantime there may be some screenshots which continue to show the older terminology.
For your first query, we'll fetch every record
on the Site. A record
is a catch-all term for WebApp and Module items that we'll use in these tutorials. The term records
does not refer to users
, as these contain more core fields like email
which set them apart and therefore they use a different query type: users
.
In these tutorials, we'll break the process of building a query into steps. For each step we'll show you:
The code you need
Notes explaining the syntax of the code example in detail
A screenshot from the Explorer Panel, showing the checkbox needed to quickly insert this code *NEW*
We'll sometimes also include a screenshot of the Documentation Explorer Panel to illustrate it's use, but this depends on whether it seems useful or not!
Code:
Notes:
The word query tells Graph we want to GET data, as opposed to modifying data.
getEverything
is simply a name we have given the query. It is optional and has no functionality.
Curly braces { }
have been added - these will contain an object containing the next level of instructions we will give the query. The next level from here is also known as RootQuery
as it is the most fundamental level at which we choose which type of query we'll use.
Explorer: The "Explorer" wizard will add this for you if you type out a name here:
The documentation panel on the right shows you the full range of query types available. Click RootQuery
to see the options on this level.
You can also see a list of non-deprecated query types in the Explorer panel:
We'll be choosing records
for our first query. This will get us a list of records
in the database.
Code:
Notes:
The new code goes within the first level of curly braces we opened in the previous step. Notice how our instructions are "nested" inside each other- like a "Russian doll", just as both the explorer panels show options nested inside each other.
We open another pair of curly braces inside records
. We'll add further options here.
Explorer: Quickly implement this level in the Explorer Panel by selecting the records
query type. This will also open the next level of options in the explorer:
A GraphQL query doesn't give you results unless you ask for them. This helps it to stay as efficient as possible. We'll ask the query to pass back some key information about the records it finds, such as their table (this will help us identify which WebApp or Module the item belongs to) and then all of its properties (fields).
Next, we'll ask the query to return results
and total_entries
.
Code:
Notes:
total entries
returns an integer, so we don't need to give it any more information.
results
requires us to specify which fields we want to return with those results. We open a new pair of curly braces and choose fields from the docs. Siteglide doesn't use all of these fields, so some will return null
. You can use properties
to return all fields which have a value. table
will return the name of the table
the record
belongs to (this was previously called model_schema_name
).
Explorer:
You can press the "play" button to test your query:
Ours is not quite ready, and the error message in the middle-right Results Panel will tell us why:
Arguments are passed into a query to modify its behaviour. They always use round brackets ( )
syntax, just like JavaScript. Different types of queries will require some arguments, while allowing others as optional arguments.
This query requires that we specify how many records we would like to retrieve on each page of the results. This is to make sure the query isn't slowed down by retrieving too many records at once. We'll learn how to navigate multiple pages later, for now we'll ask for the first 20 records.
Code:
Notes:
per_page
expects an integer, not a string, so we don't need quotes around 20
Explorer: You can set a value for per_page
in Explorer.
Notice that the asterisk by the option in Explorer lets you know the property is mandatory.
In Explorer, there is a subtle colour scheme to help you differentiate between setting arguments and returning results:
Arguments are in purple
Results, and other returned properties are in dark blue
If successful, you should see an object named "data" containing a tree of your results. Well done, you've written your first query! You've returned all records
, or, in other words: WebApp and Module items.
You'll see there are actually more total_entries
than the 20 results shown. That's because we're only viewing the first Page of the Results. We'll look at Pagination in the next Article.
If you want to get information on Siteglide CRM Users instead of WebApp or Module records, you can use the users
query instead of the records
query. The main difference is that users
can return first_name
, last_name
, email
etc. inside the results
curly braces. See the explorer panel or the documentation panel to learn more.
In the next Article we'll look at how GraphQL organises results into pages. We'll look at how to:
change page
change the number of items per page
output useful pagination metadata
Let's go!
Adding variables to your query allows you to filter results based on User interaction - and re-use queries dynamically.
So far, we've set up queries which return the same set of results each time.
Variables allow you to make queries which:
Can be re-used in different situations
Can search, sort, filter and change page based on User Interaction
Can show information which a particular User has permission to access
There are three main steps to setting up variables in a query:
Define the variables
Replace hard-coded values in the query with variables
Pass in values for the variables
There is no set order in which to follow these steps, as you'll need to follow all three before the query works as expected.
In this Article, we'll use the following query as an example.
As you might have guessed, this query aims to find WebApp or Module items with a particular category assigned to them.
As it stands, the query is not very useful or repeatable. We want to be able to pass in the category we're interested in as a variable. This would allow different Pages to use the same query to view different categories - or allow the User to choose which category they wish to view.
Normally in programming you would define the variables before you use them.
The benefit of adding the variable where you'll use it first is that the error message will tell you information about which type of data the variable will need to be.
In our example query, we'll remove the hardcoded category ID and replace it with the name of our new variable $category
.
Code:
Notes:
All variables inside the query itself must be preceded with a dollar $ sign.
This query will currently fail, because we still need to define the variable.
Explorer: Sorry, explorer does not currently support arrays or variables, so no demo is available this time.
Next, we'll define the variables we will use. These definitions will be entered as arguments on the top level of the query.
Each variable you define has two parts:
A name e.g. $category
A data type e.g. String
Here's what just the top level looks like with the newly added argument:
Here's the whole query:
Notes:
The variable name is again preceded with a dollar sign $.
A colon : and an Title Case keyword are used to set the type. See below for more information on types.
We've deliberately made a mistake with the type of the variable- we'll discuss this below.
Explorer: Sorry, explorer does not currently support arrays or variables, so no demo is available this time.
A variable's type is really important and an error will be thrown if you use the wrong one. For example, running our query now gives the following error:
We can use the error message to find the type we need- in this case it's [String!]
not String
. This indicates that an array of Strings is expected, which makes sense because "value_in" is for filtering array fields. You can also check in the documentation panel:
We'll fix this in our query:
What's important is the type of data that a particular GraphQL property expects as its value, not the type of data you were intending to pass in. In fact, you may have to modify the type of your variable with Liquid beforehand, so that it is acceptable to GraphQL.
An exclamation mark after a type e.g. String!
means that this variable will be mandatory. The query will not run without it. This is useful when that variable is used to control sensitive information- terminating the query if you can't be sure which data you need to return. However, it's important to make sure ordinary user behaviour can't cause this to happen, because the error message can be bad for UX.
Square brackets around a value, indicate that it should be an array (which may have any length). E.g.
[String]
If you require any other conversions, please request them on Intercom and we'll try and include them in the List.
*String to Int *Apply an integer filter:
String to Float
String to [String]
String to Boolean
Boolean to String
Int to String
Float to String
Literal JSON object to HASH object (Needed for advanced variables only- like passing an array of properties objects into a filter). You can also use the parse_json tag to create any of the above types; if you can write the variable in a type that's supported by JSON, the tag will convert that to a variable in the hash format that can be passed into Graph as a variable value.
You can test by entering values in JSON format in the panel in the bottom left. The panel may be hidden, in which case you'll need to click and drag it up.
Firstly, open a new JSON object:
Next, define the key of your property:
And finally, define the value of your category. Make sure the data is in the type you defined earlier. Here are some examples:
String - `"Hello"`
Int - 3
Float - 3.2
Boolean - true
[String] (Array of Strings) - ["Hello", "Hi"]
In our example, we will need an array of Strings:
Notes:
This time, you won't need to use a dollar sign $. That's because this panel represents the input and is not part of the GraphQL query- it doesn't use GraphQL syntax, instead it uses JSON syntax.
Our query is now finished:
Explorer: Sorry, explorer does not currently support arrays or variables, so no demo is available this time.
Okay, so now you can use the GraphiQL Sandbox to test your queries with variables, but the really useful bit is to be able to use Liquid to pass variables in. This will unlock the ability to fetch data dynamically with GraphQL.
Step 1) Add parameters to the graphql tag for each variable you've defined in the Query. Here, we'll continue with our example and add category
Notes:
We will add the value of the category variable in the next step.
You don't need to use a dollar sign $ before the name of your variable.
You can add new lines to the inside of the tag to keep it tidy, or write the tag on one line, it's up to you.
Step 2) Next, add the value of the parameter.
You can either hardcode the value:
Or, you can use a Liquid variable which you defined earlier:
Or, you can use data from Siteglide that's already stored in a Liquid variable. In this case, let's say we're in an item.liquid file for a Product. We already have access to the Categories that this Product is assigned to - luckily, the data is already a Liquid Array. Let's use that data to find other records in the same Category.
For this week's challenge, we'd like you to set up your own simple Pagination controls. This will combine everything you've learned so far. As usual, don't worry if you need to check the answers before completing it.
On a new Page you create, the User should be able to see the first two Items in the Gallery WebApp. Then, when they press the Page 2 button, the Page should refresh and they should see the second Page of Results. See the gif above for a demonstration.
In the Tips section, we'll give you the HTML and Liquid you need to get started, your challenge is to build the GraphQL query which will power the functionality.
Here are some snippets of code you can use to help you:
*User Interaction *You can use anchors to allow the User to refresh the Page and change the Page Parameter in the URL.
*Reading URL parameters *You can use Liquid to read the Page parameter in the URL. You'll then need to work out how to feed this variable into your GraphQL query: `
`
By the way- we're using the filters | default
and | plus: 0
to make sure the page defaults to 1 if no parameter exists, and that the data is converted to an integer.
We'll look over the answers to our toughest challenge yet.
Let's go!
This Article will show how to use custom fields to fetch dynamic content in a WebApp Layout.
Partners often ask us about outputting Liquid from a Rich Text Editor in their WebApps. Unfortunately it's not currently possible to do this- but here we'll explain a little about why- and a technique you can use to achieve the same effects.
If you want to include content from another WebApp or Module Item, we'd recommend checking out Datasources instead: Nested Content and Datasources. Datasource fields allow the Client to search and select the WebApp / Module Items they want to include from a dropdown.
Currently platformOS doesn't allow Liquid code to be executed within Liquid Fields (such as a Blog's description field). This policy improves security, by making sure it's impossible for user-submitted content to inject malicious Liquid code into your Site- giving you peace of mind that any Liquid code you write is for your eyes only.
We're working on a secure method to allow something like this in the future, but in the meantime, this Article will show you how to use custom fields to fetch dynamic content in the Layout- either above or below your Rich Text field output.
In this example, we'll be adding a Form below the WebApp rich text field.
You'll need to add the following fields to your WebApp structure:
Show Form - Checkbox containing values True & False.
Form ID - String field containing the ID of the Form you'd like to output.
Form Layout - String field containing the name of the Forms Layout.
Now the fields we'll be using have been defined, add the relevant information to the fields.
Next, locate the WebApp Layout Folder where the Form will be outputted.
Here we can output the Form using the fields that have just been set- wrap the whole include within an IF statement checking whether "Show Form" is "true" if so the Form will be outputted (with the parameters being pulled in from our WebApp). In our example, the Form will be added underneath a Rich Text field.
Now the fields within the WebApp control whether a Form is outputted for each item.
*Hardcoding parameters *If you only wish the Client to be able to display a single type of Form, you could hardcode the ID and Layout name of this Form straight to the WebApp Layout.
The Client would have control over whether or not to show a Form, but the Form type would always be the one you approved.
*Using Content Sections *Content Sections and Code Snippets can also be outputted depending on ID and could provide a range of ready-built content which you could allow the Client to add into their WebApp items.
*Expanding the Logic *You could use Liquid Logic in the Layout to only allow certain Form / Content Section IDs to be displayed and forbid others. In this example, Form 2 will never be displayed, even if it is selected:
You can also use GraphQL queries and mutations to modify and read Pages and Partial files containing Liquid. If you are creating a module and wish for users to be able to organise, store and execute Liquid, this may be a viable method to make this possible safely.
This is a brief overview of the GraphQL tutorials we currently provide and the topics we plan to cover in future.
This Article aims to give an overview of the topics currently covered in our GraphQL tutorials, and the topics we aim to provide in the future.
For a longer introduction to GraphQL and how it can be used with Siteglide, check out the following article:
These GraphQL tutorials are organised by topic, but we'd recommend you work through them one by one.
This is because each tutorial will build upon the skills covered in previous ones.
We also include challenges- because when learning something like GraphQL it always helps to get hands-on experience exploring and applying the skills you've picked up. Don't worry if you can't quite manage the challenges straight away. Give them your best shot and then check the answer pages.
The following Tutorials are currently available:
Some topics will be covered in our challenges. We'll challenge you to build upon what you've learned, before revealing a solution. If the topics interest you, try the tutorial with the same name first.
In the future, we intend to cover the following topics:
Search for Results
Use other types of Query e.g. users
Please let us know if you'd like to see anything else included.
Last Time we challenged you to pull together everything you'd learned to create some Pagination Buttons powered by Graph. Answers here!
For this challenge, we'd asked you to set up your own simple Pagination controls. This combined several of the skills you've learned so far. As usual, don't worry if you need to check these answers before completing the challenge on your own.
On a new Page you create, the User should be able to see the first three Items in the Gallery WebApp.
Then, when they press the Page 2 button, the Page should refresh and they should see the second Page of Results.
Firstly, here's the query without variables.
Now let's add the variables:
Notes:
The most difficult part here might have been working out the type. Here the query expects Page to be an integer. The documentation panel confirms this:
From the documentation panel, you can also see "= 1" after the type. This is a default, which means if no variable is passed through, the variable will be given a default value of 1. Not all variables will have defaults.
The type here does not have an exclamation mark ! so the query won't deliberately fail if no value is passed in.
We set per_page
to 3
We gave you these in the tips. You'll have needed to add them on a Page of your choice.
Pressing one of the buttons will redirect us to the same Page, but will be adding a page
query parameter to the URL. This is the easiest way to pass variables to Liquid- because Liquid runs before the Page loads, and the URL is one of the only available sources of dynamic information at this point.
It's also possible to pass information to Liquid on another Page via an XHR request. This can lead to smoother UX, but is more challenging and will be covered in a future tutorial.
Let's say we pressed the second button, our relative URL will now be:/my-page-slug?page=2
As we showed you in the tips, Liquid can read this parameter at the following dot-notation path. This will output the value on the Page: {{context.params.page}}
Or you can store this in a variable, which we'll need to do here:
By the way, the keys in context.params
are dynamically generated for any query parameter in the URL, so you can pass through any variable you like with this method.
a) First, let's set a default value, just in case a User arrives at the Page without setting the Parameter:
b) The query is expecting an integer, so let's apply an Integer filter that will change the type to an Int
without changing the value:
c) Let's add the graphql
tag with the variable parameter.
We can output the results using the variable name we defined in the graphql
tag.
If pressing the HTML anchors changes the results by fetching different "pages" of JSON results, you've been successful. Congratulations.
If you're having difficulty with any of these steps still, please don't hesitate to ask for help on the Forum.
Liquid
GraphQL
The next steps give you ideas for how to take this further. They are not part of the initial challenge!
These JSON results don't look great. Remember, you can use Liquid to pass the results into a Layout- if you can find that Layout's relative path in Code Editor.
However, you won't have access to the user-friendly names for fields in that Layout, because GraphQL will output the raw database IDs for fields.
You'll want to target fields in this Layout with syntax like:{{this.properties.webapp_field_1_2}}
You can view the database IDs for fields in the Admin using the toggle in the top-right of the screenshot, or you can look at the keys in the JSON results.
By returning total_pages
from the query, we'll know exactly how many Pagination buttons to display:
You can then use this to manipulate the HTML pagination controls:
Next time, we'll learn how to sort the results of your Query.
Let's go!
Last time we looked at how you can use mutations to create a record.
This time, we will look at a mutation to update a single record.
The syntax is very similar to creating a record, but the main differences are:
1) using a different mutation type
2) We need to pass in an ID- to identify the record which needs to be changed.
All queries started with the query
keyword; mutations start with the mutation
keyword.
We've also named our mutation editItem
.
In this example, we'll add the ID as a variable:
Note, we don't need to add an object for the ID as we might when filtering a query.
As with record_create
mutations, the record
object defines the properties the record will have after the mutation has run.
Any properties you set will be updated. Any properties you omit will stay in their current state.
You do not need to specify a table. By default, the record will remain in its current table. Attempting to change the table may not be supported on Siteglide as the new table would not have compatible fields.
As in our last tutorial, it is possible to pass in properties as a single large JSON variable, if you see a convenience in doing so.
As in the last tutorial, it is required to add something to the object which returns with the results of the mutation. This can be useful to confirm results and show you what has changed. However, if you don't need many details, the best performing option is just to ask for id
.
A successful mutation result will look like this:
Imagine you have two different forms, each with an automation attached to them and you want to count how many times the automation runs.
You set up a WebApp with a custom integer field. Each time the automation runs, you:
query the WebApp, get the current count
add 1
to the value with the add
Liquid filter and
update the count with a record_update
mutation.
9 times out of 10, this will behave as expected, but what if two people submit the form at the same time?
If both automations check the current count at the same time, they will both read the same value e.g. 5 and after adding 5, will save 6 as the updated count in the database. Even though the automation ran twice, the count would only increase by 1.
It is to combat this scenario that record_update
contains the following special operations:
array_append will push the provided value to the end of an existing array stored in a property.
array_remove will remove the provided value from an existing array stored in a property, (wherever in the array it currently is)
decrement will reduce an existing integer value by the provided integer value (could be 1 or some other integer)
increment will increase an existing integer value by the provided integer value (could be 1 or some other integer)
In our example, we could do the following:
This safely increases the counter by one per mutation run, even if the two mutations are triggered by Liquid simultaneously. There is no need to query the existing value.
Nice work following through this tutorial.
If you want to try updating users, you can experiement with the user_update
mutation.
Next time, we'll look at how to delete records.
You shall not pass! This time, we'll look at how you can use filters to only return results based on specified rules.
You have completed the Learning GraphQL tutorials 1 - 2. You can find the previous tutorial
- optional- Read more about GraphQL and when it might be best used.
records
in the database have a table
which tells us which WebApp or Module they belong to.
This time, we'll look at how you can use filters to only return results with a particular table
, or with a table
which matches a certain pattern.
The Starter Site comes packaged with a ready-built WebApp with the id of 1
and the name webapp_1
.
We'll return to our query from the previous tutorial, but this time, we'll rename it from get_all_records
to get_webapp_1
to reflect the different purpose we intend for it. We'll also be wanting to look at page 1
again.
Code:
Explorer:
Next, we'll add a filter argument:
Code:
Notes:
As an argument for the records
query, this goes inside the round brackets after records
.
Like the other arguments, filter
is followed by a colon :
We have more settings to choose next (filter
is an object) so we add curly braces { }
Explorer:
In this tutorial we'll choose the table
to apply the filter to, because we're looking for items with the table
of webapp_1
.
Code:
Notes:
We've chosen table
as the only filter. In the next tutorial we'll explore using other fields, and filtering by more than one field at once.
This field also contains further options, so we use a colon :
followed by curly braces { }
to contain the next set of options.
Explorer:
We now have a choice about:
How closely our value should match with the contents of a field before a match is returned. We'll use value
(the exact value).
The value we are matching against. We'll use webapp_1
.
Notes:
value
is a key and is followed by a colon :
Our value "webapp_1"
must be a String, so we wrap it in double quotes.
Documentation panel:
Selecting RecordsFilterInput gives you options for different filtering rules you can apply:
After the colons :
you can see the type of value expected for each of these keys. They are mostly strings String
or arrays of strings [String]
. This topic will be covered in more detail in later tutorials. Keep an eye out for the different data types expected by GraphQL in the meantime.
Explorer: When implementing this using the Explorer, the wizard will help you get the type of value correct. In this case, it provides you with quotes so that you can enter the value as a String:
You can adjust the filter to return items from a specific Module item only. In this example, we'll specify module_3
which is the Blog Module.
Code:
Explorer:
This should return Blog Posts from the Blog Module.
You can adjust the filter to return Form Submissions from a specific Form only. In this example, we'll specify form_1 which is the Newsletter Sign Up Form.
Code:
Explorer:
In order to learn GraphQL, you'll need to start experimenting with what you've picked up from this tutorials.
To help you do this, we'll now start to set you some challenges. These will ask you to tweak the examples we've given you so far and see if you can achieve the desired results.
We'll always give you the answers to the challenge in the following Article, so don't worry if you get stuck.
To carry out this challenge, you will need to create a second WebApp and add a couple of items in the Admin. By experimenting with the options in the documentation panel, see if you can filter the results so that:
your query returns all items with the table
of webapp_1
your query returns all items with the table
of webapp_2
your query does not return items which start with module_
your query does not return Form submissions which start with form_
We'll go over the answer to this challenge in the next Article.
We'll look at a possible solution to our challenge. After that, we'll continue to look at filtering queries in more detail, including:
filtering by different fields, or properties
filtering with different kinds of rules
using more than one filter at once
You've now used the GraphQL playground to write queries which fetch data. Now you're probably itching to see how you can add one to a Site!
You've completed the "Learning GraphQL" tutorials 1 - 4.
In order to use GraphQL results on your Page, you'll need to be familiar with Dot Notation Liquid syntax. You can get started with learning to use . You may find that you want to refer back and forth between articles on Dot Notation and GraphQL as you continue with your learning.
You'll need to be familiar with Siteglide-CLI. In this tutorial we'll be using Siteglide-CLI to add a GraphQL folder and sync our new queries up to the Site.
- optional- Read more about GraphQL and when it might be best used.
Last time, we looked at how to use filter
to refine your queries so that they only return results matching particular criteria.
So far we've been working in GraphiQL, the interative playground. This time, we'll run a GraphQL query on your Starter Site. We'll also take a quick look at how to handle the results- but you can learn more about this by following our Documentation on and .
The best way to run your GraphQL query on a Site is to save the query inside a GraphQL file. This keeps it tidy and allows you to easily re-use the same query elsewhere on the Site should you need to.
If you're following this tutorial with the same Site each time, you'll already have a project folder. After all, we have been using the .siteglide-config
file in your Project Folder to interact with the GraphiQL interactive playground.
In this example, my project folder
We need to add a GraphQL query inside a specific folder in order to refer to it with Liquid. Before we do that- we need to see your Site's File Structure so we know where to add the folder.
In terminal, you'll need to change directory to the Project Folder.
If you've not already, run a pull command in terminal to pull down the current file structure: siteglide-cli pull my_environment_name
If you want to refresh your memory on using the Siteglide-CLI, you can learn more** here**.
I'll be using Microsoft Visual Studio Code in this example. Other Editors are available.
All the folders and files that can be synced with your Site are in the marketplace_builder
folder.
graph_queries
Open up the marketplace_builder
folder. If you've not already got a folder inside this called graph_queries
, create one now.
Create a new file to store your query inside. It's best to give the file the exact same name as your query. This will make it easier to find later.
The file should have the extension .graphql
.
So that file now exists on your device, but not yet on your Site. You'll need to either sync
or deploy
the file to your Site.
The choice of command is up to you. sync
will watch for changes in the marketplace_builder
folder, so you'll need to make a change in the file after running the command before your file is uploaded. The sync
command will continue to watch and sync files until you cancel it. deploy
will simply deploy
all your local files to the Site as a one off command.
Here, I'll use sync:
This query file will not be visible in Code Editor, but the files will be on the server and Liquid will be able to access them. The reason for not displaying them here is to hide the most complex code from areas where Clients and non-developers can access it. This might change in the future.
If you wanted to check if the file has synced correctly, you can turn off sync
, delete the file and run a pull
command. In our experience, there's no need to run this check, as sync will tell you if a file is synced and "done" accurately.
We'll use the graphql
Liquid tag provided by platformOS. You may see other developers familiar with platformOS using tags like query_graph
or execute_query
, but graphql
is the most up-to-date:
Notes:
The tag itself is graphql
The first parameter you give should be a new variable name. This will create a Liquid variable containing your results- you can choose your own name.
After the equals = sign, you should write the file name of your GraphQL file, without its file extension or any folders. For example, my filename is "get_items_with_musical_names.graphql"
so I remove the extension: "get_items_with_musical_names"
.
You can output all of your results on the Page, using Liquid output syntax {{ }}
to output the variable we defined earlier.
Notes:
The Liquid output must be on any line below the graphql
tag.
You can output this in any Liquid File; this includes Pages, Page Templates, Headers, Footers, Layouts, Code Snippets and Workflow/ Auto-Responders.
The results will output in Hash format. You can use dot notation to access specific results within the Object.
This example uses dot notation.
It is possible to use your Query to rename the keys in your Results- doing this would require different dot notation. We'll look at this later.
For now, we'll be using the query below, which does not rename any keys. I've set per_page
to 2, in order to make the example data Object shorter and easier to read.
Code:
My Page returns the following results- don't worry- there's no need to read them in this form:
Running these results through a 3rd-party JSON parser gives me the data in a format which is much easier to read. We don't recommend any particular JSON parser, but if you're using a text editor there will normally be an extension available which does this.
The structure of the results here matches the results we see in the GraphQL playground. We're looking for the key which returns an array of results- this is indicated by the square bracket [ ]
:
The dot notation to reach the results is:
Alternatively, you can always run your query in the GraphiQL Playground and work out the dot notation needed from the results shown in the middle-right panel. You'll just need to ignore the very top key in the results data
: and use the variable from your graphql
tag instead e.g. my_results
:
We loop over every item in the Results array. We create a variable called this
with a scope which allows it to be accessed only inside each loop iteration. this
contains all the data for that result.
In this example, we'll output:
the table
An example property name
An example property webapp_field_1_2
. This is the second custom Field defined in the WebApp's structure on Starter Site.
We can now also bring in other Front End languages. I'll add some common HTML tags.
This gets me the following Results on the Page:
You can use a Liquid include
tag to output a Layout to display your results. The trick is to make sure that the data fits the same format as the layout is expecting.
You've reached the end of the first collection of our Learning GraphQL tutorials.
By now, you should be able to:
Set up a development environment to test GraphQL queries
Run GraphQL queries on a Siteglide Site
Understand and use GraphQL Pagination
Use GraphQL filters
New Tutorials will be added soon!
There's no official challenge for this tutorial, because you probably want to experiment with adding queries to your Site.
In the next Tutorial, we'll look at using variables in your Queries to make them more dynamic. We'll look at how you can use variables:
In the GraphiQL playground
Using Liquid in a Page
Let's go!
You can change the type and order of sorting. You can also sort by multiple properties at once.
In this Article, we'll look at how you can instruct the query to return items in an order of your choice.
Using sort along with pagination means you can make sure the first pagen of results shows you the items you're interested in. Using sort along with variables allows you to let your end-User customise the sort order themselves.
In this example, we'll start with a query which fetches the Categories.
Code:
Code:
Notes:
As a parameter, sort is contained within the round brackets after the query type
Explorer:
You can either use:
Code:
Explorer:
Code:
Notes:
Remember, any field which is not a Platform default field will be a property. This means any field not listed in the other options, including several Siteglide fields such as "weighting". Default fields tend to be like created_at automatically filled in when an item is created.
Explorer:
You can choose between the keywords DESC (descending) and ASC (ascending).
Code:
Explorer:
Sometimes you may want to initially sort by one property, e.g. weighting, but then some items may have a blank weighting property. Those items where the sort field is blank will go to the end of the results list, but you can add additional sort conditions to sort these further.
Let's say we wish to firstly sort by "weighting", then sort those items without a weighting by the "release date".
Code:
Notes:
Here we use an array with square brackets []
to add multiple sorting objects with curly braces {}
Unfortunately, arrays are not yet supported by the Explorer, so you'll need to add this code manually.
You can use different sort orders for each condition
If you want to challenge yourself, you could choose to try making a query which uses variables to change the order and field by which results are sorted.
Next time, we'll look at how you use what you've learned so far to start to build your own Application Programming Interface (API). This will use GraphQL to query the database, Liquid to display the results on an endpoint Page and JavaScript to GET those results on the client side.
So far, these tutorials have used GraphQL queries; in this article we're going to start looking at mutations.
The difference between queries and mutations is that:
Queries "read" data from the database
Mutations "create", "update" or "delete" data.
Keeping these types of operations separate is helpful, as it means you can be confident that running a query will not endanger the database on a live site.
When learning and testing GraphQL mutations, we strongly recommend you do so on a staging site.
If you need to test with real data, we recommend using the Siteglide Portal's Site Copy feature to create a staging site clone of a production site with a copy of the database.
Siteglide may not be able to recover the exact state of data as it was before running a mutation which modifies that data.
See for more tips on what to do if you accidentally delete data you didn't mean to. (This won't help if you accidentally change the properties!)
All queries started with the query
keyword; mutations start with the mutation
keyword.
If using explorer, click the dropdown to select mutation instead of query, to unlock different options:
This will create a new record (or user_create to create a new CRM user.)
The required record
object allows you to define both the properties of the new record and which table it should belong to.
Setting the table allows you to define which module or webapp it will belong to:
As with queries, the explorer UI cannot handle multiple properties in a mutation. You can use the explorer to figure out which individual property types are possible and then add the code manually. properties
itself can be written as an array with each object inside the array defining a property to set.
Data Types
Each property must have a name which matches the ID of the field or custom field in Siteglide. When setting a value, you need to select a property value, value_array, value_boolean etc. depending on the platformOS type of data the field expects.
To find out which Siteglide types your table uses for each field, go to the corresponding WebApp or Module in the Siteglide Admin, or you can use this query to see each field's ID and Siteglide types together (you can also change the filter and properties to see which other tables are available):
When using boolean, float or integer, you don't need to use quotes.
While results are generally less useful in a mutation than in a query, having at least one result is generally required and your mutation won't work properly without it. The idea is simply to give you information about the record in the database after the mutation to confirm that the mutation was successful - even if this is simply an ID.
Mutations which affect multiple records at once often have a count
result which only returns the number of records created.
You can add the results you need in the curly braces after the round brackets which follow record_create
If successful, your results should return like this:
If you have an error, the error information will display instead of the results. In this case, value_int was used instead of value for the Blog Item's title:
In the following example, variables are added to pass in data programatically to create the new Blog post:
This is an advanced technique and you can skip it if you want to continue learning the basics of mutations.
If you like, you can use a variable to represent the entire properties object and pass in JSON which defines all the properties at once. Why? It might save time (or not), depending on the kind of data you have available. It may also make the mutation more re-usable. Learning advanced skills like this may give you more options as a developer and you may come across a situation where it's useful.
Note how the parse_json
tag is used with literal square brackets to create a JSON array with nested objects defined by curly braces. The category_array
property is an example of how you can pull in Liquid from different sources into these properies, though this.id
would only contain a category ID in for example a category detail layout.
Note, the structure of the JSON we are passing in the previous example is similar to the structure of properties in the mutation, but it is necessary in JSON to use double quotes around the keys like name
:, while the GraphQL syntax needs no quotes.
Using explorer to turn properties into a variable is a quick way to reference the required type for the complex variable [PropertyInputType]
:
That's it! You should now be able to create Siteglide WebApp and Module items programatically using mutations.
You could experiment with the user_create
mutation to create users. Instead of a record object this will have a user
object which accepts a required email
property.
In the next tutorial, we'll look at more examples of mutations, including mutations to update and delete records.
This article shows a different use-case for the skills you've already learned- using a GET request to run a query.
So far, we've written GraphQL queries which run on Page Load. This is powerful, but wouldn't it be even more useful if you could fetch data after Page load when a User interacts with a Site- e.g. changing page on a list without refreshing the Page? Using XHR (sometimes called Ajax) requests, you can run GraphQL at any time.
This approach can take a little bit of time to set up, but can allow you to create much faster interactive experiences for your Users and opens up a huge range of possible solutions you can build.
We cannot document every way in which you can build this kind of Page, but we will show you the basics and let your imagination do the rest! If you need additional support on this topic beyond the scope of what is documented here, we recommend you speak to one of our or browse the resources we link to at the end of the Article.
An API - (Application Program Interface) is a form of communication between two services on the internet. Communication takes place between 2 or more endpoints.
An endpoint in its simplest form is a URL which allows an API access to a server or application. On Siteglide, we provide you with API endpoints we've built with our , but now you've learned GraphQL, you also have the ability to build your own endpoints when you need them.
A method defines the role of the API + Endpoint e.g. a GET method is for "getting" or "fetching" data.
JSON (JavaScript Object Notation) is a common file format for exchanging data which is efficient and human-readable. We'll use it in some of our examples. (It's also the default format in which GraphQL results are outputted on the Page.)
The first step is to create a Page on the Siteglide Admin which will become your API endpoint.
The slug you choose will be the URL via which you'll eventually access the data. It's worth naming the Page and writing a slug which reflect the fact that this Page is not a public-facing Page and should not be editable by Clients. e.g. /api/webapp_1
Using the Siteglide-CLI, pull down your Site's files to your machine and open them up in a Code Editor of your choice. Set up Siteglide-CLI sync so that changes you make will be pushed to the Site.
Open up the Page you've created in a Code Editor of your choice.
We'll be editing the yaml configuration at the top of the page. In my example, you can see the yaml settings between the triple dashes --- It's important when configuring yaml to use exactly 2 spaces instead of tabs for indenting. Your siteglide-cli sync command will alert you to any validation errors.
So far we've only learned to write GraphQL queries, so your endpoint will be handling GET requests. Set the method property of your page to get:
method: get
Optionally, you can choose to change the format of your Page. If you like, instead of HTML, you can make your Page a different format, like JSON.
format: json
Note that if you set your Page to a different format now, you'll need to append the URL with the extension later. e.g. a Page with the slug my-slug
and format JSON can be accessed at the URL /my-slug.json
.
As your endpoint Page will not be accessed by either humans or search-engine bots, it's much better to remove the Page Template, allowing you to only return the data you need.
layout: ""
Unless you're using the HTML format from 2) b), you will need to remove any
tags automatically added to the Page.
Unlike the other steps, this is not a yaml property on the Page. However, it's included here as a quick sensible step you can take.
You may wish to specify in your robots.txt
file that pages with this URL should be ignored by search engines.
My example looks like this:
In this example, I'll use the following query to fetch data from webapp_1 and change page with the page
variable:
I'll use the following Liquid to run this query when the endpoint Page is accessed:
Note- I'll be using - before and after my closing Liquid tags to remove unnecessary whitespace from the results- this is optional.
In the example, we'll pass inputs into the endpoint Page using query parameters on the end of the URL, for example, I already have the URL for accessing the endpoint Page: /api/webapp-1.json
Remember
The ".json" extension should be replaced with the "format" you chose in step 2.
I'll be storing the page I want to request from the endpoint in query parameters like so: /api/webapp-1.json?page=2&per_page=1
You can now use context.params
`to read the URL on the endpoint Page and dynamically access each query parameter. I'll store each in a variable before I feed these into the query, in case there is any type coercion to carry out first.
We can then add them to the query.
If the query expects variables to be Strings you can actually add them straight to the query without assigning as variables first:
Results are accessible via the variable name you defined in the graphql
tag, but at this point we can decide on the format in which we'll display them.
If you decided in step 2 that you didn't want to change the Page format, you should now build the required HTML structure you'd like to send back (this would probably be inserted as it is into a Page via JavaScript).
If you decided in step 2 to change the format of the Page, you'll need to use Liquid to output the content in this format.
As GraphQL already outputs in JSON format, this is easy:
For something like CSV, you'll need to use logic to output the data in the correct format -this is just an example and you may need to alter it for your use-case.
We use {%
rather than {%-
in this example, because we want to preserve new lines to make sure each row of the CSV displays correctly.
In your browser, visit the endpoint Page URL and see if the data displays as expected. Test changing the query parameters to see it change the returned data.
A successful JSON endpoint will return valid JSON in the body, as in the example here (other formats should also be checked for valid formats).
Changing the URL parameters should allow you to return different responses
Common issues:
Your URL should include the relevant file extension e.g. .json
for json format, .csv
for CSV format. If you are using HTML
format, no extension is needed. Below is an example of a 404 response from using the incorrect extension:
Your URL should contain any query parameters you need for your query. E.g. in my example, page
and per_page
are mandatory. Below is an invalid response body resulting from missing URL parameters:
Congratulations! You've built a working GET endpoint using GraphQL and Liquid!
The last two optional steps will expand upon your options for securing the Endpoint and using the data available.
Is your data sensitive and you want only logged in Users to access it? Is your data public and it doesn't need an additional authorisation step?
This step shows you some different ways to make sure your data is secure, but you can skip it if your data is not sensitive or private.
Adding a Secure Zone to your endpoint Page is a simple way to protect it from Users and bots who should not be accessing it.
A failed access will still generate a successful 2xx response code, because it will succeed in returning HTML body (the 404 message that displays to Users). This is only a problem if you're not using HTML format for your endpoint as it will cause any JavaScript which relies on parsing JSON to fail like so:
In step 9, you'll need to find a way to adapt your JavaScript logic to handle this kind of error which does not rely on the response code, but instead checks the response for the HTML tag <h1>401 - Unauthorised</h1>
. See step 9) a) i) and 9) a) ii) for examples of this logic.
You can use Siteglide-CLI and platformOS to build an authorization policy that checks the request either comes from a trusted Site or from a trusted User. The benefit of this is that it allows you to return HTTP response codes.
These tips are intended as inspiration and do not constitute complete examples. They do not require sending a query parameter over in your URL, making them easier to keep secure.
If the User has been logged in (to any Secure Zone), you can check this on the Endpoint Page Authorization policy.
To check that the request comes from an authorized Page/ Site, you can check this with context:
On any of your other Pages, you can now send requests to your new endpoint and fetch data. For this you could use JavaScript.
The JavaScript examples provided here are intended for inspiration only. Unfortunately, we cannot advise you on how to adapt these to suit individual projects. See the links at the bottom of this Article for more resources you can use to help plan and develop projects of this kind.
This basic example will request data from the example earlier and console log the response.
The if statement logic checks if a 2xx response code is received (meaning any authorization policies have passed) and that there is no HTML tag containing a 401 code from a Secure Zone check failure. See Step 8) for more details.
In this expanded example, we'll fetch the data and then append it to the HTML DOM.
Add HTML and JavaScript
An event listener targets the Form and watches for a click event
When the Form is submitted, the event triggers the function "getWebappOne".
The if statement logic checks if a 2xx response code is received (meaning any authorization policies have passed) and that there is no HTML tag containing a 401 code from a Secure Zone check failure. See Step 8) for more details.
The function requests the data from our new endpoint.
It then loops over the Items and appends each WebApp Name to the HTML DOM.
In the previous two examples, we've used an endpoint with a JSON format endpoint.
You may find it easier to build HTML on the endpoint and when it arrives in the destination Page, output it as it is.
Build HTML on the Endpoint Page
Fetch HTML on the Front End Page
Your Liquid endpoint Page will be acting as an extra Layer between your request and platformOS' own GraphQL endpoint. This extra layer is important because it allows you to run your own logic and security checks, before pOS deliver the data.
*Remembering Pagination in GraphQL *You may need to refer to , to refresh your understanding of Pagination.
Refer back to to refresh these steps.
You can learn more about this topic , as it works in the same way as displaying Collection Results in a Layout.
To figure out the correct one, you can reference this page which will show which platformOS types are used by each Siteglide type.
We covered variables in more detail in but they are just as useful in mutations!
- combining what you've learned in Tutorial 8 and 9, you should be able to create an API where the Liquid endpoint runs a mutation to create items. You could use this alongside a custom form to allow the user to enter properties which are then passed to the endpoint in the URL and then finally into the mutation via variables.
In this step, we'll be changing the settings of the Page in CLI, as there are available settings here that are not yet editable from Admin. You can learn more about pages in platformOS here: and more about the .
Add a query of your choice using the Liquid graphql
tag from and variables from
Accessing these values via the above method tends to set them as String values in the variable. For this example we'll need to change the type to integer- as that's what the query expects. You can refresh your knowledge on changing the type of variable in Liquid in
As this is custom platformOS code, it won't be covered by our support. Learn more about authorization policies on the platformOS docs:
Consider using Live Updates The SiteBuilder Live Updates API, released since this doc was first written might be a quicker alternative here. You can put your GraphQL code in a Code Snippet and follow the docs to .
SiteGurus have created the Live Updates API as part of the SiteBuilder module- designed as an incredibly flexible API endpoint for refreshing almost any Siteglide Layout with different filters- this may save you time implementing your own API endpoint:
The explains how you can get support with planning projects and writing custom code.
MDN have comprehensive documentation on the XML HTTP Request and how to use it in your Front End JavaScript Code: You can also use the modern as an alternative.
Those developers who prefer to use jQuery when writing JavaScript can read more about Ajax Requests here:
platformOS's documentation on Pages includes lots of information about setting up Pages using the yaml configuration:
A list of field types available on Siteglide and the corresponding platformOS data type applicable to them
Text (String)
input_text
string
Text (Multiline)
textarea
string
Checkbox
input_checkbox
array
Radio Button
input_radio
string
Dropdown (Single Item)
select
string
Dropdown (Multi Item)
select_multi
array
Datasource (Single Item)
datasource
integer
Datasource (Multi Item)
datasource_multi
array
Image (Single)
image
string
Image (Array)
image_array
array
File
file
string
Folder
folder
string
Date
date
integer
Number (Integer)
number_integer
integer
Number (Float)
number_float
float
Boolean
boolean
boolean
Custom Array
array_custom
array
Modules - All field types
WebApps - All field types
eCommerce Products - All field types
CRM Users - All field types
Forms - All field types except Custom Array
Custom Field Sets - All field types except Custom Array
All field types have the following metadata options:
name
string
The field name to be shown in Siteglide Admin UI
type
string
The field type in the 'Siteglide Type' column above
live
boolean
Determines whether or not the field is shown or used anywhere
hidden
boolean
Determines whether or not the field is shown in Siteglide Admin UI
order
integer
The position the field is shown in Siteglide Admin UI and Import CSVs
editable
boolean
Determines whether you can edit this metadata in the Siteglide Admin UI builder views
required
boolean
Determines whether it is required to fill in this field in Siteglide Admin UI and front-end forms
Some other metadata options are available to specific field types:
rich_text
boolean
textarea
Determines whether the Rich Text editor appears in Siteglide Admin UI for this field
options
string
input_checkbox input_radio select select_multi
A comma separated string of options to be displayed for this field in Siteglide Admin UI
datasource_id
string
datasource datasource_multi
The ID of the model you want options to show from for this field in Siteglide Admin UI. This includes the type, for example webapp_1
.
num_min
string
number_integer number_float
The minimum value this number field will allow the user to select.
num_max
string
number_integer number_float
The maximum value this number field will allow the user to select.
num_step
string
number_integer number_float
The amount the number will change by using the number scroller in Siteglide Admin UI.
num_precision
string
number_integer number_float
The amount of decimal places shown in Siteglide Admin UI.
Automations V2 - A complete rebuild of Automations using our new API (that runs from the Site directly), a new and improved UI and a new Automation type called Integrations. Integrations allow no-code connections to 3rd party Apps via SSO in a similar way to Zapier without leaving Siteglide.
Rich Text Editor V2 - An update to the Rich Text Editor that can be used in Modules and WebApps. The update includes an AI tool to write and edit content.
Pages - Fix for Agency Layouts not showing in Studio tab
Data Cleaning - Add 'Password Reset Requests' to list
Discord - Uptime status reports
Integrations - Support for Google Auth
eCommerce Orders - Support for >10k Orders to show in list view
Spam Protection - hCaptcha option on Forms
Automations - Fix for deleting and re-adding Automations to a Form
Exports - Fix for Form CSV exports not showing 'Name' field
Automations - Full release of Automations system
Discord - Add sign up links for new community Discord server
Pages - Fix to support Studio on smaller screen sizes
Pages - Fix for 'Link' button on Studio
Pages - Fix for File History misreporting 'method' value
Site usage - Show Marketplace Module usage in metrics on Subscription tab
Site Copy - Lock new sites until copy is complete
Marketplace - New 'Templates' category for Site Templates, from which people can create sites
Forms - Auto reload table data on bulk case delete
Marketplace - Fix an issue where 'All Modules' toggle wasn't working
Site Details - Fix an issue when loading Site Copy tab
Site Copy - Fix an issue with Custom Module UI when a site is copied
Tickets - Added ticket title to email notifications
Studio - Show editor on Content Sections, Code Snippets, Footers, and Headers
Studio - Include a link selector, which shows Pages, WebApp items, and Module items on the site
Studio - Improved Image selection and editing
WebApps - Fix an issue where 'default' wasn't showing as a detail view layout option
CSV Imports - Fixed an issue where you couldn't unset an array value
ALPHA - Automations
ALPHA - Studio editor updates
CLI - Fixed issue where homepages couldn't contain certain text strings
Menus - Fix for updating old menus
Public API - Fix for Zapier integration issues
Secure Zones - Fixed issue where Module items weren't shown on the Secure Zone details view
Billing - Introduce 'Automatic Upgrades' toggle in Site and Agency views
CSV Imports - Fixed issue with eCommerce external ID values
Custom Field Sets - Fixed issue when building new CFS
Secure Zones - Fixed issue where WebApp items weren't shown on the Secure Zone details view
Billing - Show 'Extras' as separate invoices in Portal
Billing - Show plan name in Site list
Marketplace - Change version control so owner always installs latest dev version, whereas end-user installs latest released version
Public API - Add currency and status data for eCommerce Orders
File Manager - Fixed issue with filtering by upper/lowercase
Reporting - Fixed issue when adding users to a Secure Zone in bulk
Site Manager - Integrations - Fix issue with updating reCaptcha keys
Tickets - Added a link to markup cheatsheet, so users can add formatting to ticket comments
FileManager - Fix for searching for files in Modules
Redirects - Fix for 'type' not being selected correctly
Billing - Allow site plan changes after payment failure
eCommerce Product Export - Fix for External ID showing module_14/product_
prefixed
Marketplace - Full release to Admin for Custom UI support
Site Details - Show Module list in same format as on Marketplace, with improved filtering and searching
Billing - Improving loading and filtering of Invoices
CLI - Fix issue with Homepage showing as 'undefined'
Code Editor - Further support for new Module file locations
General - Fix timing issue on System Emails since daylight saving change
Go Live - Add support for Discount Codes on Site Go Live
Modules/Site Create - Fix issue with Module install/update flow, and improve speed
Toolbox - Fix Content Section names on System Pages
Marketplace - Alpha support for Custom UI on Modules
Ticketing - Fix to allow Support Team to create tickets on other user's behalf
Forms - Fix for list view not loading correctly if large amount of entries
Modules - Field order now displays accurately
Redirects - Fix 'type' dropdown
Public API - Fix for Product/Order data not returning correctly
Site Usage - Rename some metric names to be accurate
Ticketing - Allow selection of Site from a dropdown, rather than typing in the Site ID manually
CRM - Force selected Secure Zones to be a unique list (i.e. no repeating Secure Zones)
Site create - Fix for System Files installation of tables (Categories etc.)
Templates - Fix to correctly show dropdown options
Toolbox - Show layouts from new Module file locations
Modules - Fix item copy functionality
Marketplace - Support for new Module file location (Code Editor, Site create, etc.)
Sign Up - UX improvements, and added new fields to sign up flow
Order Details - Change default tab on open
Ticketing - Added new filters to list view
Affiliate - Added support for new Affiliate program
Order Details - Add 'Editor' tab to allow editing of order's status and addresses
Ticketing - Release of new Ticketing Support system
eCommerce - Fix for issue in Volume Pricing
Order Details - Add error handling for when order's user cannot be found
Company Information and CFs - Fix for image selection
eCommerce Subscription - Fix for issue in item create flow
Forms - Fix for name with special characters in
Portal - Auto-extend site expiry for those on Agency Pro
Public API - Fix for User Secure Zone editing
Modules - Fix for issue where 'weighting' wasn't being handled as an integer
Order Details - Show Product ID if name isn't found
Reporting - Saveable Reports
General - Fix for issue where 'weighting' wasn't being handled as an integer
General - Added better error handling for when items (Pages, WebApp items, etc.) don't save correctly
Site Usage - Ignore 'Domains' when tracking limit status
Site Usage - Remove 'Background Jobs' metric
Site Usage - Show 'downgrade' option
CRM - Fix for issue with 'Textarea' custom fields
FileManager - Move 'select' button to start of row to help with smaller screen sizes
FileManager - Fix bug in file delete flow
Pages - Fix for trying to save item without a Name
Public API - Support for latest Order Products structure
Fix for menus that run using External ID (eid)
Updated how menu items are fetched, to improve performance and reliability of data
Updated default layouts to use Siteglide Studio (this won't overwrite existing installed layouts)
Fixed an issue where delete Menu items were still showing
Fix default layouts on new installations (target -> link_target)
Support for Siteglide Studio
Support for Automations structure
Updated default layouts to use Siteglide Studio (this won't overwrite existing installed layouts)
Add keyword search to default Blog Layout
Modernised Category output syntax on default layouts
Fix location the user is sent to on Blog date search (s_blog_date_search
)
Initial release.
In this article we'll look at how to delete a record with a GraphQL mutation, but first of all, let's look at what deleting a record means (and how to undo it!).
When we delete records with GraphQL, they are soft-deleted by default.
If you accidentally delete data, it may have been "soft deleted", and you may be able to recover it if you act quickly.
Think of soft-deletion as being a bit like a recycle bin:
Records are given a deleted_at property with a date in 30 days time in platformOS's datetime format (ISO 8601)
When the date is reached, the record will be permanently deleted.
They are removed from the results of all queries by default (this includes all Siteglide tags)
You can get ordinary records
queries to display soft-deleted records (only), see below:
The results will be the same as in a normal query; it's helpful to add deleted_at to the results so you can see when they will be permanently deleted:
If a record has been soft-deleted by mistake, and has not yet been permanently deleted, you can recover it by setting the deleted_at property to null. Make sure to use the query above to find the ID of the record you want to recover and pass it in as a variable to the mutation below.
After changing deleted_at
to null, the record becomes an ordinary record. It appears in queries and is no longer scheduled to be deleted. The mutation results should confirm that deleted_at
is no longer set:
If you want to extend the amount of time the record stays in soft-deleted state, you can change the deleted_at property to set the deletion date to be further in the future (but this is an advanced method we won't cover here).
Use another query to find the ID.
A successful deletion may look like this:
You've now learned how to perform all four CRUD operations using GraphQL:
Create
Read (query)
Update
Delete
If you wish to programatically create, update or delete multiple records at once, it may be more efficient to use the following mutation types instead of looping:
records_create_all
records_update_all
records_delete_all
Be very careful with those and make sure you test with data which is backed up. We recommend using any_table: false
as a precaution.
In these mutation types, you use a filter
to determine which records should be affected instead of only passing id
. You need to add count
to the results.
Next time we'll look at how you can use a query to access data from multiple relational database tables, or in other words, view data from Siteglide datasources.
In this tutorial we're going to show you how you can use a single query to get not only results in a single table, but at the same time return related results from another table.
For example:
Products may be related to categories- and each category may be related to some help articles.
Blog Articles may each be related to an Author, and that Author may have a relationship with some Secure Zones.
Using related_records is powerful because:
It allows you to build more complex applications - giving you complete control over getting the data you need.
It's flexible - if you've stored enough data, you can define relationships in your query without changing any settings.
Combining multiple queries into one will give you much better performance than any other way of getting this data, e.g. nesting Siteglide include tags inside each other.
Here are a few of the terms you may come across in this topic:
relational database
A relational database describes a database comprised of tables, where there may be predefined relationships between records in different tables. platformOS's database is a kind of relational database.
join
In many query languages e.g. SQL, a join defines how two tables are linked together. In platformOS, a join on property is used to define which field should be used to find other related_records.
tables
In platformOS, as in many other databases, a table is a set of data which contains records of a certain type, with a certain set of properties.
records
In platformOS, as in many other databases, a record is a single entry of data in a database.
related_records
In platformOS, records which share a relationship. It can be single:single, many:many or single:many. This is effectively the same concept as a datasource.
datasource
In Siteglide, a datasource is where there is a relationship between records in the same table or in a different table, and data can be "sourced" from that other table. It can be single:single, many:many or single:many. This is effectively the same concept as platformOS's related_records.
datasource and datasource_multi field types
foreign
In platformOS, a foreign property refers to a property outside of the current record. The foreign property is matched with the join on property in order to fetch related records which share a relationship.
data graph
In computing a data graph describes the relationships between different nodes of data. Think of a node like a city and the relationships like roads. One of the reasons GraphQL is called GraphQL is that it is trying to give queries an intuitive graph-like structure- we define the relationships in the query itself, and the results return with the same relationship structure.
The great thing about related records being as flexible as they are is that there are a lot of examples we could choose from. Our first example though will try to keep things simple by fetching Blog posts with their associated authors.
We've already covered how to write a records query and filter it so it contains only blog posts. Here's an example:
Since these two modules - the Blog and Authors Module - are both created by Siteglide, they already store the information needed to join them inside their properties. We only need to look at the existing properties in detail to get the information we need to build our query.
There are several ways to do this. One of the easiest to do on an everyday basis is to use Introducing Siteglide CLI to pull
your site, then to look in marketplace_builder/form_configurations e.g. 'marketplace_builder/form_configurations/forms/form_1.liquid' or 'marketplace_builder/form_configurations/modules/module_3.liquid':
For this exercise, we'd be looking at module_3
for blog and module_6
for authors.
In Blog, scroll down or use ctrl-f to search for author
The form configuration will contain both the human-friendly name and the Siteglide ID for each field:
Great! It's a datasource field, which is pefect, because it will already be set up to contain IDs of Author records related to each Blog record. We don't need to look at the Author record now to know that the module_field_3_4
property of the Blog and the id
of the Author should match. Sometimes, you'll need to look at both.
Since this is a GraphQL tutorial- here's an alternative way to check the form-configurations- using a query (see how we use filter to look for only the Blog and Author configurations)!
In the Siteglide Admin, we can check that some of the Blogs already have authors set in the datasource
field, in this case this Blog item has an Author ID of 100
in the field:
To start with, look inside results in explorer: related_record
and related_records
appear as possible results. By including these special objects inside the results object, we can define a branching tree of related results.
The two options are similar but have one key difference:
related_record - Use this to define a 1:1 or a many:1 relationship. It will return a single record as an object. This may give you better performance, if you know for example there's only one author.
related_records - Use this to define a 1:many or a many:many relationship. It will return multiple records as an array.
The main reason to pay attention to which you choose is that it will change the way you structure your Liquid to access the data- remember if there is an array in the data you may need to loop over it in order to access it.
For now, let's use related_record, as we have a datasource
field to join with, and only one Author per Blog record
:
Remember, we use a string with no spaces and a colon to "rename" things in GraphQL. It's a good idea to rename this related_record to describe what it will return. In this case, it describes a single author.
This will make it easier to understand the results and allow you to add other related_records
in future (it won't let you if names clash).
As mentioned in the glossary, the join_on_property
is used to define the property in the current result record which will be used to match with a related record. In step 3 we worked out it was module_field_3_4
.
We don't need to write the value of the module_field_3_4 field, just the Siteglide field ID.
you also don't need to add properties
before the field ID, as you may when filtering a query; here, platformOS works this out automatically
this goes inside the curly brackets as an argument
The foreign property is the counterpart to the join_on_property, but it refers to the property in the record we are looking for, in this case the Author record is the record, and the property is id
.
Note the syntax is the same, even though module_field_3_4
is a custom property and id
is a core property in platformOS.
table
here is a filter, despite not being inside a filter object. It must be set to describe the table we should look in for these related records. In this case, the ID of the Authors module: module_6
We've already defined which results we want for Blog items, and that we want to return a related author per blog item, but we also need to define which authors properties should be returned.
We could return the whole properties object, but where possible it's worth being extra efficient when working with relationships. There is more work for the query to do, and it may run more slowly. Maybe we just need the author's name and an image (I use the information we looked at in step 2 to find the module_6 image field ID)?
The results go in the new object under related_record
after the arguments; no results
key is needed:
That's the query itself done!
The results in JSON may look like the below (we've minimised Blog properties which aren't useful to the example):
As always, when outputting in Liquid, you can use dot notation (see Liquid Dot Notation or Tutorial 5 - Using Liquid to run GraphQL queries on your Site) to access the results, until you get to an array. Since we only asked for a single author, we can use dot notation inside the blog record to access the author. We still need to loop over the blog results as always:
What if you need this to fetch information the other way around, e.g. you are on a page which displays information about an author and you wish to display a list of the Author's Blog Posts? An additional aspect to this is that this is a 1:many relationship- it's no problem- we'll use related_records
plural instead of related_record
to return an array instead of an object.
Starting with the query above, lets make some changes:
Next, you could experiment with some of these options:
using filters to further filter related records e.g. Authors with Blog posts which are enabled
using related_users
an alternative to related_records
which fetches CRM users with a relationship to your record. You don't need to specify a table, but join and foreign properties work the same.
Additional nesting. Inside your related_records results, you can define related_records again. This allows you to build a complex results tree containing as many layers of related results as you like, for example adding to our example above- you could return the categories of each Blog the Author had published- and display a list of category names.
This section is for developers that want to build Templates and Modules for the Marketplace.
When working with Zapier, adding data to arrays needs some extra JavaScript to convert the data. Zapier calls arrays "Line Items" and formats them like so, [123,456,789]
whereas Siteglide API expects a JavaScript formatted array such as, ["123","456","789"]
To convert these two data types, use the screenshots and code below. In this example we are getting a pre-existing user and their Secure Zones, then adding in a new item.
The above javascript code and flow can be used for anywhere that you need to add an item to Line Items within Zapier
Before submitting your Module for approval, you should check that your GitHub Repository is ready.
See the following checklist to confirm it is ready for submission:
Now that you have created your module, you will need to update the Module item that you made in Admin earlier.
You will need to edit the item with the following information:
Menu Name - If applicable, the name to show in the left hand menu when viewing a Site Admin: Modules > My Module.
GitHub Repo Account - The name of the GitHub account that your Module’s repository is in.
GitHub Repo Name - The name of the GitHub repository that your Module’s code is in
Installation Notes - Any notes on installation - appears in ! icon in ‘action’ column on the Module installation page.
Changelog- A link to your Module’s changelog documentation, this will display within the Marketplace and next to the “Install” button.
Public - Do you want this Module to be visible within the marketplace?
You can also find these notes in the tooltips on each field.
Once you have clicked "Save" with the above fields populated, your module will be submitted to the Siteglide team for review.
Once you’ve submitted your Module for approval you’ll need to give us access to see the Module. This is needed for the initial approval, but also for ongoing access to be able to install the latest version of the Module.
To provide us with access you need to invite Siteglide API (api@siteglide.com) as a collaborator for the GitHub Repository. You can do this in your repository settings.
After accepting the invitation we will review your module. This includes reading the code, installing the module onto a site and testing some of its functionality. We will create a ticket within our Support Tickets area so that you are kept up to date with progress. Once your Module is approved by us then we will allow it to be shown within the Siteglide Marketplace so any user can see and install the Module on their sites
Here we will outline the process involved in creating, building, submitting, and maintaining a Module in the following series of docs.
We will use the Siteglide Theme Demo as an example of a pre-built Module which is available on the Marketplace which you can install on your own staging site to view.
With that in mind, anywhere in this documentation where you see text wrapped in <>
are placeholders. For example <module_name>
would be module_76
with the Siteglide Theme Demo module (more on this later!).
The first step to building your module is to create a listing for it in Siteglide. Within your Portal from the left-hand menu, select “Custom Modules” and then click the blue “+ Add New Module” button in the top right-hand corner.
Next, fill in the Module Details form. For now, you only need to provide the following basic information:
Name: The name of your module shown in the Marketplace and Siteglide Admin.
Version: A version number following the Semantic Versioning standard. Usually this would start as 1.0.0.
Description: Small text description of what the Module is - appears in ? icon in ‘name’ column on the Module installation page.
Type: Which category you would put your module into.
Show Menu Item: Does your module need to be within the sites menu under “Modules”? For example for a theme that has no items then this would be set to No.
We will come back later to enter information into the remaining fields, so for now click the blue “Save” button in the bottom right-hand corner to save your new module. Your module will only be visible to yourself at this point as it is not marked as “Public” and has not been approved for the Marketplace.
Now that you have created your new module, when you view it you will see that it has a “Vanity ID” field. Make a note of this number for later as it will be used within the Module.
Here I will outline key tips and information in maintaing your existing module once it has been created.
When anyone (yourself or someone else) installs your module, it will automatically take a copy of anything currently within the master branch of your Git Repo.
If you would like to work on updates or new additions to your module, it is strongly recommended that you create a new branch in your repository so that it does not impact what is installed until your are ready.
Create a new branch and call staging
for example. From now on, send your initial commits to staging while you are testing. When you are ready to release an update to your module, merge into the master
branch in Git.
Once you have committed a new version to your master
branch in Git, edit your module in Siteglide Portal to update the version number and let people know there is a new version available to install.
A Module can contain any code that will run on Siteglide, but that code does need to be split into the relevant folders (notifications, views, etc.) and folder structures. Below, we'll take a look at how to do just that along with all the various options available to you, depending on what you would like to build.
The Module name is written in the following format: module_<vanity_id>
. Replace vanity_id with the Vanity ID generated in your Module listing in Portal.
For example, with our Siteglide Theme Demo Module this would generate a name of module_76
. Your module name (based on your generated Vanity ID) should be used anywhere the tag <module_name>
is referenced in this documentation.
Create a new staging site within your agency to build your module on. Ideally you'll want to use a blank site, so pick the "Build a Custom Site" option on creation. Only you will see what your site is called, so you can call it anything you like.
Once you have successfully created your staging site, create a project folder on your machine to work within, connect to your site via CLI and then pull the site down onto your local machine so that you are ready to begin building your module.
When you begin building a Module, there are two top level folders that should be created alongside the marketplace_builder
folder of your staging site. The top level module folders are:
modules/<module_name>/private
modules/<module_name>/public
Any information that is stored in the private
folder will not be accessible to users within the Siteglide Site Admin, CLI and GraphQL. Here you should store any logic that you don’t want anyone to be able to see or edit. If you are following our example Siteglide Theme Demo Module, as it is a theme we do not have any private files and so this folder can be ignored.
Any information stored in the public
folder will be accessible to users within the Siteglide Site Admin, CLI, and GraphQL. This folder should be used for any content that you would like to be visible and editable to the user.
Under each top level folder you have the option to create any relevant folders for the information you are wanting to create and use, such as assets
, views
, notifications
etc.
You can view and download this full folder structure from the example directory-structure Git Repo. Alternatively, run the init
command in CLI to automatically create the structure within the marketplace_builder
folder and then move them into your module.
https://documentation.platformos.com/developer-guide/platformos-workflow/codebase
Directory/file
Explanation
** Learn more**
Assets
Used to store any assets (Images, Files, CSS etc) that you would like to ensure are accessible when your module is installed.
Views
Contains all layouts/partials/pages/templates visible from Admin & Front-end of a site the module is installed on.
Notifications
Email and API notifications
GraphQL
GraphQL Queries and other data handling
Beyond the standard site files that will be in your Module (GraphQL, Liquid, partials etc), the Module installation process will look for 3 other files in the root folder of your Module Project (alongside /modules/
).
The setup.json file contains information about your module, including any tables (data) you want to create when installing your Module to a site. You can view an example of this file here.
Files generated from this JSON file:
Model - <module_name>.yml
stored at modules/<module_name>/public/custom_model_types/modules/<module_name>.yml
Form Configuration - <module_name>.liquid
stored at modules/<module_name>/public/form_configurations/modules/<module_name>.liquid
Detail Page (if applicable) - <module_name>.liquid
stored at modules/<module_name>/public/views/pages/modules/<module_name>.liquid
You can find details on field types in this document
This file should contain a list of files you don’t want to be overwritten on sites when updating to a new version of your Module. Typically these would be any layout or asset files in your Module that a user will have edited in the last version.
Each array’s key should be the version they are created at. For example, if you want a file to be ignored when updating to any version above 1.0.0, set the key as 1.0.0
.
You can see an example structure here
In this example, an update above 1.0.1
will ignore all 6 files in the list.
The install process file will run a Siteglide created process while the module is installed on the site. A list of all of the scripts that are relevant for each module type can be found here ::create and link::
In this example we will need a page to be set as the homepage of the site after installing the module. This is done using the set_homepage
process. We will create a file with the version number of our module and set_homepage
as our process as seen here.
Templates are whole sites which have been saved so that you and other users can easily create copies of it moving forward. They are excellent for creating turnkey solutions for specific industries and client types, allowing you to sell a theme and then customise to each client on top.
Build out as much of a site as you’d like on a Trial site, then turn it into a template on the marketplace, making it publicly available to be installed during the creation of new sites.
First, find a template you’d like to use for a new site in the . You can use the filter category at the top of the Marketplace page to filter ‘Templates’ only to find options more quickly.
Click on a template to view the popup for more information and images. If you would like to use this template, then continue to the next step below.
Once the template popup appears, you can create a new trial site using this template by selecting an owner in the “Site Owner” field, and then entering a name for your new site in the “Site Name” field.
Click the blue 'Create Site from Template' button, and then wait for the template copying process to complete.
Once you receive your email notification to tell you the site is ready, your new template site will appear in your sites list. From here you can edit the site just like any other, by clicking the 'Admin' button.
Have you created a site that you’d like to turn into a reusable template?
Select the trial site you want to convert to a Template Module using the “Site” dropdown field displayed below the Name, Category & Description fields.
Note: Only trial sites can be converted to a Template Module.
Once you have created your Template Module, you can either keep it for internal use within your team, or allow the template to be publicly viewable and installable.
If a template is both publicly viewable and installable, then the master trial site will be locked for editing (with a status of “Locked - Template”). The site is locked to prevent other users making copies of a site that has any ongoing work.
If the site were not locked, then the copy process could be triggered whilst there are unfinished changes from the managing development team. If you wish to make edits to the master trial site, at any time you can remove the template from the Marketplace by toggling either the 'Publicly viewable' or 'Publicly installable' values to 'No'.
The master trial site will then be editable again until you toggle both of those values back to 'Yes'.
In this example we’re going walk through, step by step, how to create a Module with a Custom UI that could either be used as a private module for your agency or shared publicly in the marketplace to deliver turnkey site solutions to your clients and more.
It is recommended that you download our example so that you have all of the code and asset files available at each step of this guide and can easily follow along to and have your module end up looking exactly the same.
:::hint{type="info"} If developing a Custom UI then you will have to supply all elements of the Module, including but not limited to tables, GraphQL, data processing etc. :::
Custom UI modules open up the ability for complete flexibiltiy within Siteglide Admin and allows for truly unique experiences for your customers.
A module with a Custom UI will securely load a page within a frame in Siteglide Admin. This page can be developed in any language that can run on a Siteglide site.
A Custom UI Modules will follow the same folder setup as other Modules, except when you come to build the UI itself to display in Siteglide Admin. The UI will be kept in the private
folder of the module as we do not want it to be discoverable outside of the frame within Siteglide Admin.
To ensure that the Custom UI is only being accessed by logging in users of Siteglide Admin, we require authentication to be added to each page that will be used within the Custom UI. This is stored in the YAML of the pages and is as follows:
The response_headers
YML allows Siteglide Admin to view the content of the file when it is loaded. The authorization_policies
YML will run a check to ensure that the user has an active session within Siteglide Admin, if not then it will display an error page.
As well as the YAML, any links within your Custom UI has to include a Liquid tag to apply the authencation string on the link. For example if you are linking from your Custom UI's index page to the add new item page, your link would be as follows:
This include will create a hash onto the end of the URL that is then used in the above authorization policy to decide whether to show the page. If the include is missing then following the link will throw an error within Siteglide Admin.
You can also control access to certain areas of a page with the module_is_in_admin
function:
Once your module is created, you will need to tell Siteglide Admin to load your Custom UI. You will need to take the slug of the Custom UI's homepage and enter that into your Module Detials within Portal. When editing the details about your module, there is a field called "Custom UI Path", entering in the slug there will change the menu item for your module to then load your Custom UI instead of the default Siteglide module UI. In our example the path for our Custom UI homepage is module_72/module_iframe/index
In this example we're going walk through, step by step, how to create a Website Theme Module that could either be used as a private module for your agency or shared publicly in the marketplace to deliver turnkey site solutions to your clients and more.
It is recommended that you download our example so that you have all of the code and asset files available at each step of this guide and can easily follow along to and have your module end up looking exactly the same.
The first step to building your module is to create a listing for it in Siteglide. Within your Portal from the left-hand menu, select "Custom Modules" and then click the blue "+ Add New Module" button in the top right-hand corner.
Remember to note down your newly generated Vanity ID.
Second, create a folder for your project on your local machine. Working within your new project folder, connect to your new staging site via CLI to pull the initial site files down onto your computer.
Within the public folder, we want to add in the core assets our Theme Module will use. There are three folders we want to copy in to our own Module project folder:
bootstrap5-plain-assets
- Core Bootstrap 5 image assets which our Theme pages will display.
js
- Core Bootstrap 5 JS files along with a custom JS file which our Theme pages will run using.
scss
- Core Bootstrap 5 CSS files along with a custom CSS file which will Style our Theme pages.
Open the Module_Siteglide_ThemeDemo
project folder you downloaded earlier and navigate into modules/<module_name>/public/assets
. From here, drag and drop all three bootstrap5-plain-assets
, js
& scss
folders into your own Module project assets folder.
Next we’re going to add in various core elements such as Pages, a Page Template, Header & Footer.
First, within your modules/<module_name>/public
folder, create a new folder called views
. Inside the views folder, we’ll be creating several new folder structures to house the various files we’d like to include. Below I’ll list each of these directories and give an explanation as to what they will be used for:
layouts/templates
- A Page Template file used to wrap all of our theme pages.
pages
- Several Pages we would like to include in our module and display on the site.
partials/includes/header
- Page Header file used to store the Header including main navigation.
partials/includes/footer
- Page Footer file used to store the Footer including secondary navigation.
Open the Module_Siteglide_ThemeDemo
project folder you downloaded earlier and navigate into modules/<module_name>/public/views
. From here, drag and drop all three layouts
, pages
& partials
folders into your own Module project views folder.
As we’ve been copying files from the Theme Demo Module, we’ll need to update the module name in some paths written in the files. Open up your IDE and bulk find/replace module_76
with your <module_name>
.
Next, we want to create one of the setup file options available: install-process.json.
Add the following Code Snippet to your newly created Install Process file:
Adding this line of code to the install-process.json file will ensure that when a user installs our module, the home/start page is automatically applied as part of the installation. Otherwise, the existing home/start page on a site will be honoured.
Now that we have added all of the core assets and views to our module, let’s see it in action!
Open your staging site to view your work both front-end and back end.
If you’re happy everything looks as it should, continue to the final step. If not, check back along the steps above to make sure you’ve not missed anything.
First, delete the marketplace_builder
folder from your project folder on your local machine. We don’t want to include this to avoid overwriting any pre-existing content on sites which install our module.
Follow the checklist to confirm your Theme Module is ready for submission:
Here is what your project folder should now look like:
Now that we have prepared our files, if you haven’t already create a new GitHub Repository and commit your project folder to it.
Please ensure:
In general there are two main types of folder structure for Modules, though within that, there will be variation on the types of file available, so check each individual module.
The form directory stores the form layout for Module create/ edit Forms.
Most Siteglide published Modules will have a folder structure a little like this:
The private folder will exist, but will not be possible to pull using CLI or view in the Code Editor UI. It is for storing functional code which will be used by the Module behind the scenes.
You can set your Module up to require payment before a user can install it.
All payments are handled through your Stripe account.
Follow the steps below to add this requirement:
You need to link your Stripe account to your Agency in order to take payments. Go to your Agency edit view, and click the 'Marketplace Payment Details' tab. Read the details shown on this screen and then enter your Stripe Secret Key ()
Go to the Module edit view, and click the 'Payment Details' tab. Here you can toggle 'Take Payment?' to 'Yes' if it is required.
Enter the Stripe Product ID for your Module. This Product will need a Price attached to it in Stripe.
Select the Access Type you want to grant. There's 2 options:
User only - This will grant access to the paying User
Agency-wide - This will grant access to the entire Agency of the paying User
You can manually manage User/Agency IDs in the 'Access List' field if you need to do so. This field will auto-update when a User pays for your Module.
That's it! Now, when a User sees your Module in the Marketplace they'll be required to pay before they can install the Module.
Added support for Rollout front-end Automations (Form submissions, and WebApp item create/update/delete)
Add more logging to Form Submissions to support debugging
Add an alert box warning when a user tries to navigate off the page during a Form Submission
WebApps/Modules - Added a new sort type for list output - 'item_ids'. This can be used to output items in order of IDs provided to the 'item_ids' parameter. This is especially useful for outputting DataSource Multi fields in the same order the items were selected/ordered in Admin - -
Security - In order to improve security of the platform, we have removed some scripts that were in place to support Internet Explorer 11. As ever, we recommend using the latest version of your chosen web browser, as this will ensure you have up to date security features. We understand however that you cannot control what browser people use to navigate to your websites, but Internet Explorer accounts for only 0.5% of web traffic now so we have elected for security over support in this case. We have updated our 'Browser Support' document to reflect this change here -
Config - Added a default site config for new sites, to ensure the right platformOS features remain active
Marketplace authorisation - Fixed an issue in the authorisation process used by Marketplace Modules
Forms - Fixed an issue where the wrong field could be highlighted as an error
Site Search - Fixed an issue where you couldn't have multiple different Site Search inputs on a page
Forms - Fixed an issue with malformed filenames on file upload fields when some special characters are used
Forms - Fixed an issue where Billing and Shipping address weren't being handled correctly for eCommerce Orders
Forms - Fixed an issue when uploading multiple images
Module Forms - Added support for Marketplace Modules
Added consistency to error message format on Form submissions
WebApp/Module forms - secure_zone_array is now correctly set a 'empty' for filtering.
WebApp/Module forms - Before this change 'slug' value was always auto-generated when creating a WebApp/Module item using a front-end form. Now, if you set a value yourself, it won't be replaced by the auto-generated version by the system.
Patch to fix pagination on Category output - 'category_items'
Patch to fix front-end Module edit forms when using the 'Anyone can edit' option
Fix an issue on forms with boolean fields that blocked them from submitting correctly
Fix an issue where you couldn't unset checkbox fields for front-end WebApp items on Forms
Added 'use_wrapper' param on WebApps to allow them to follow a similar output structure to Modules
Added 'module_is_in_admin' authorisation check as an include, where it was previously only an Authorisation Policy. This allows for more control over what shows on a page in Custom UI for Modules.
Sitemap XML - Update lastmod to use same 'Last Edited' value as shown in Siteglide Admin. Before this change the value only changed on page content update, and not on change of metadata or page URL
WebApps/Modules - Better 404 responses for search engines
Forms - Add better error handling on hCaptcha validation. Automatically highlight the box in red, like other fields.
WebApp Forms - Support for "Anyone can edit" option
Forms - Fix to make custom JS form validation work seamlessly with hCaptcha spam protection
Automations - Support for 'enabled' option
Added hCaptcha as a Spam Protection option (default) on Forms
Added support for Google Auth in Integrations
Fix an issue with number fields in site search
Support for Automations structure
Fix an issue with hyphens (-) in site search keyword
Fix an issue where some WebApp/Module items would show in Sitemap even when they have the detail view turned off
Fix an issue where you couldn't unset checkbox fields for CRM fields on Forms
Security patch for Form submissions
Fix for Marketplace Module data output
Fix for og:url field output on WebApp/Modules
Support for new Marketplace Module file paths
Minor patch to support new field types
Image (Array)
Folder
Number (Integer)
Number (Float)
Boolean
Minor patch to fix output of Module collections
Minor patch to add support for Module caching
Modules - Front-end item submission
You can now insert Module Item Forms from Toolbox in Siteglide, and have users submit items (Blog, Events, Products, etc.) themselves.If an old version of a Module is missing the necessary layout for this, then you can reinstall the Module to set this up. Alternatively, edit the Module structure and simply 'Save' what is already there.
Site Search - Updated query to now search slug and metadata as well as the rendered content
WebApps - Cache - Added support for URL parameters so this feature now works with search
WebApps - Category item output - When asking for items in a category you can now make sure it only looks in that category, and not any sub-categories. To do this, use show_all_sub_items: 'false'
Patch to fix a conflict in CRM custom fields and Address fields on some Forms
Patch for Category detail views still showing when Category is disabled
Patch for pagination issue on Blog list views
Fix for compatibility between eCommerce and Custom Field Sets
Added support for s_redirect
on standard Forms and front-end WebApp item Forms, to allow for custom redirects after submission
Fixed an issue where reCaptcha failures weren't reported correctly
Fixed an issue where Categories were still showing even after being deleted
Support for the latest version of Bootstrap (5.0.1) for Studio
Support for CRM Company data on Forms
Support for CRM User Address data on Forms
Patch for custom CRM field data not updating on Form submission
Patch to stop blank SEO fields outputting on WebApp/Module items
Patch for eCommerce Products used as a DataSource
Output eCommerce Products in Sitemap XML
Patch for WebApp search for compatibility with the previous update to records
An upgrade for all WebApp and Module data output to improve performance and stability (customizations
-> records
)
Bug - Fix to allow "
in all form field values
Bug - Add support for Products and Subscriptions to Site Search
Forms - Bug fix to support '=' in form field values
Improve page load speed by adding caching to Category fetching (most effective on sites with large amount of Categories).
Minor restructuring of Categories to support Import/Export
Support for Studio with Bootstrap 5
Added filtering/sorting support for eCommerce
Added a new flag to the category_items
include as an option to fetch Categories differently - show_all_sub_items
- When set to 'true' all items from within sub-Categories will be output, as well as the items within the specified Category
Added another layer of Form validation, to remove reliance on the .required
class. If this class is missing, submissions will be validated server-side, and any errors fed back to the front-end before further progressing the submission.
Support for the new 'Custom Array' field type
Fix for WebApp location searching
Made CRM Custom Field output easier by giving you access to field names (e.g. this['User Field XYZ']
)
Support for CRM Custom Fields on front-end Forms
Image fields on Categories
Location filtering on Modules
Secure Module items
Fixed a bug where checkboxes and multi select boxes weren't working on Forms
Minor field changes ready for upcoming Module Custom Field updates
Patched an issue with Form Submission when fields were used which submit multiple values e.g. Checkboxes
Forms - Updated the submission process to reduce site usage costs
Note: This is includes a change to all FormConfiguration files for Forms and WebApps. Any use of CLI without first pulling the latest file could revert the change back to a broken state. To manually fix, change resource: Customization
to resource: form_1
(that is an example; it should match the FormConfiguration name)
WebApps - You can now add a button so front-end submitted items can be deleted by the person that submitted them
Track the steps of a Form Submission so you can add a progress bar
Added a new helper function to make it easier to write custom error functions for Form submissions. The helper function will format all errors to Strings, helping you focus on displaying them to your Users. We've also added a new example here
Support for upcoming Siteglide Studio release
WebApp location coordinates - There was a mistake in our release that caused the coordinate values to be flipped (latlong instead of longlat). This has now been fixed.
All docs have been updated accordingly, so please re-read and update your layouts:
You will need to update all WebApp items to this new format. Simply re-search for the location, and select again from the dropdown, or you can swap the coordinate values manually. If you have a large amount of data to migrate to this new format please get in touch with support, and we can handle the conversion.
WebApp location searching
Support for Secure WebApp items
Verify response of reCAPTCHA v2
Fix Category slug output for some sites
Minor fix for including a list of WebApp items on an eCommerce Product page
Fix for og:image on Module detail pages
Performance upgrade for sites with a large amount of categories
Fix to allow multiple File Upload fields in a Form
Added feature for previewing Images when a file is uploaded front end
Sitemap generation
Fix for multiple reCAPTCHA Forms on a Page
Bug fix for WebApps showing more than 1 item on their detail view
Pagination update to support upcoming Modules (Events, Media Downloads)
Performance improvements on Categories. Mainly noticeable on sites with a very large amount of Categories.
Fixed a bug with multiple Custom Field Sets on a form
Set a default layout (of 'default.liquid') for custom pagination that's included outside the scope of a WebApp list view
Front-end file upload is now direct-to-S3
Fix for CFS updating on form submissions
Stop overwriting sitemap.xml and robots.txt on each update
Update FontAwesome to v5 in locations missed in v2.4.2.1
Site Search - Allow WebApp items with no detail view to show in results.
Categories - Big performance upgrade, with no action required by users to take advantage of this.
Fix for recaptcha after unpublished changes from Google
Updated FontAwesome to version 5
Auto-inserted a meta viewport tag which is required for our layouts
Browser Support updates
Minor patch on previous update
Forms - Fix an issue with some form submissions in Microsoft's Edge browser
Add more logging to Form Submissions to support debugging
Fix for sessions not tracking correctly on first time visit to a site
Fix for an issue with inventory not calculating correctly in some rare cases
Turn off PayPal item breakdown if it throws an error, and just send over the total price, rather than blocking payment entirely
Improved process of Discount Code checker on Cart pages
Discounts - New option to choose when a percentage discount is applied - before, or after tax calculations - Default is 'after'
Cart - Remove items that are expired or not yet released
Updated security as outlined in
Settings - Added a 'Pricing Accuracy' setting to allow you to switch between 2 decimal places and 4 decimal places on pricing for Products, Attributes, and Shipping (as well as showing those values in Order views)
Multiple Tax Rates - Can now set multiple tax codes against a currency
Order Details - This view in Siteglide has been updated for any new Orders to show more data
Settings - Fix for eCommerce Settings not loading correctly
Settings - Allow you to set a pre-defined list of Order Status Options that will then appear as a dropdown on the Order Edit view. If no options are set, the field will continue to be free-text
Attribute Options - Add Image Array field
PayPal - Fixed an issue where products with `"` in the name would crash the order create process
Product Feed - Fixed an issue where HTML entities would break XML generation
Stripe - Improve payment flow to accommodate for recent updates to Stripe payment handling and 3D Secure
Fixed an issue where owner data wasn't being fetched correctly for Products
Patch to fix Payment Methods not being stored correctly
Patch to fix rounding issue with Volume Pricing
Patch to better handle special characters in Form Names when sending to Stripe
Show Form name in transaction description in Stripe. For example:
"Payment Form" -> "Example-Form-Name (Basic Payment Form)"
"Checkout Order ID: 123" -> "Example-Form-Name (Checkout - Order ID: 123)"
Fix for quote forms where no price is set against the product
Fix for hCaptcha with PayPal Checkouts
Added hCaptcha as a Spam Protection option (default) on Forms
Support for Automations structure
Fixed an issue where products can remain hidden in a user's cart after the product has been disabled.
Patch for price rounding issue on Product Attributes where decimal tax percentages are in place (introduced in v1.10.11).
Patch for Subscriptions where no specific Payment Gateway ID is provided.
Patch to fix issue when Product Inventory quantity is set as '0' when type isn't 'Global'.
Patch to fix edge-case issue when changing Product Inventory type.
Patch to fix issue with Product Inventory not hiding/showing Products correctly.
Patch to fix issue with Order Detail view when multiple Products in the Order.
Patch to fix a recursion issue on Order Detail fetching.
Patch to improve the consistency of price output in some rare situations on Subscriptions.
Patch to fix Product and Attribute data not capturing correctly in Orders.
Image (Array)
Folder
Number (Integer)
Number (Float)
Boolean
Allow defined Payment Gateway on Subscriptions, rather than just using the most recently update Payment Gateway
Patched order_details output to fix Product+Attribute price calculation (only affected output, not capture or charges)
Added remove_default_css
option to Cart output, which allows you to remove the siteglide_example.css
file from output
Structural changes to the Orders database to improve performance and reduce usage.
This change is safe to apply unless you have custom code reliant on the old structure being in place that used the module_14/order_product
or module_14/order_product_attribute
tables.
Patch to fix checkout timeouts on sites with large amount of Product Attributes
Added support for output of more tax breakdowns:
Final Item Price - price_total_item_cost - The total of all Products in the Cart, with any applicable Tax added
Final Total Tax Amount - price_total_tax_amount - The total Tax amount applied to any Products or Shipping Option
Final Total Price Before Tax - price_total_before_tax - The total price of Products and the selected Shipping Option, before any Tax has been applied
Patch to support inventory checking against Attributes on Cart.
Product Attributes - Added Inventory control
Product Attributes - Pricing of Product Attributes is now controlled per currency, rather than 1 charge for all currencies
Product Attributes - CSV Import/Export is now available from the Product List view
Added the ability to use custom parameters with PayPal
We've opened up our eCommerce Order flow, so you can add custom functions before and after payment is successfully taken. More information to follow...
Patch to support 'Custom Array' field types in eCommerce
Patch for Subscription Stripe Webhooks to fix an issue where they would always return as 'Failed'
Support for CRM User Addresses to be used as Shipping & Billing data
Patch for Products used as a DataSource
Patch to support HTML and special characters in Product Descriptions stored against Quotes.
Bug - Fix to allow "
in Attribute/Option name
Added a snapshot of Product Description to Order Products model
Fix unhandled PayPal error
Patch for spam protection bug (due to platform cookie name change) which was causing an 'Unauthorised' error on payment forms.
Discount Codes on Subscriptions - You can now set up Discount Codes to be used with Subscriptions. For example, you can say "50% off for 3 months" or even use it as a free-trial type code of "100% off for 1 month"
XML Product Feed - A new System Page that outputs Product data in XML format for RSS feeds
Sorting and Filtering by Price
Shipping Options - Added 'display only' price.
Updated default layouts to use Siteglide Studio (this won't overwrite existing installed layouts)
Allow Shipping Option changes on Checkout Forms
Minor fix for some applications of Discount Codes with 'live reload'
Minor fix to get rid of a console warning when updating Pricing in a Cart
Fix for Add to Cart buttons
Fix for when Order value is equal to a Discount Code's minimum spend
Added console warnings on some Discount Code implementation to help developers debug issues. Warnings only appear when a potential issue has occurred.
Fix for some further issues when displaying Cart and Checkout layouts on the same Page
Fix for empty Discount Codes on Basic Payment Forms
Basic Payment Forms - Added the ability to use Discount Codes on Basic Payment Forms
Orders - Added the ability to add a previous Order to your Cart
Cart - Added a validation function to check that the contents of a Cart are valid before passing the data to the Checkout. Note that this validation was performed server-side before payment, but this now allows for more Cart layout feedback/customisation. For example, checking that there enough inventory to cover the Order
Shipping Options - The page refresh upon option selection is now optional
Product Attributes - Provide more readable property naming on output (e.g. .image
rather than .properties['module_field_14/product_attribute_option_5']
)
Fix to block Discount Codes attempting to force an Order to a negative value
Fix for a bug where PayPal Discount Codes would be have their 'uses' value reduced even when the payment errors
Fix for a bug where a random Discount Code could be applied when entering an empty string
Blocked disabled Attributes from showing on Product list/detail views
Fix for displaying Cart and Checkout layouts on the same Page
Support for eCommerce Product location filtering and Custom Fields
Image and Display-only Price fields on Attributes
Patch for PayPal live mode issues
Minor field changes ready for upcoming Module Custom Field updates
Basic Payment Forms - Allow access to the Payment amount in autoresponder and workflow emails
Basic Payment Forms - Allow access to the 'minimum payment' value on Page
Cart - The 'update quantity' field can now apply updates on change, rather than needing to press an 'update cart' button
Buy now - Support for sending the user straight to a payment from, rather than simply adding the item to the basket
Discount Codes - Invalid codes (expired or no uses remaining) can now be removed from your cart
Minor patch to cover Pricing field type change from text to integer
Fix for issue where setting Product Inventory to "none" prevented Orders being created for that Product.
Fix for conflict between recent database changes and PayPal Checkout
Fix for bug in Stripe Subscription Cancellation
PayPal Payment Gateway
Stripe - Store the Siteglide Order ID against the order in Stripe as metadata
Structural changes to Pricing and Inventory databases in order to improve performance, lower usage costs, and allow for easier filtering/sorting on this data.
All Pricing and Inventory data is now stored directly against the Product, rather than in separate database tables.
Any custom extensions of the existing database structure will require you to change to the new structure before updating your Module. All data will be migrated to these new fields when you update your Module.
Stripe Basic Payment Form Submissions now display the associated Stripe Charge ID next to the Payment Intent ID in the Admin.
Fixed a bug where the Add to Cart button would sometimes add extra items to the Cart that were previously added and removed.
Support for structural changes introduced in Secure Zones 1.1.0
Fixed a bug with Discount Codes where some combinations of Products would cause the preview of the discounted amount to be incorrect (there was no problem with the actual discount applied) .
Fixed a bug with Quote generation Forms.
With the addition of Subscriptions, we complete the first release of Siteglide eCommerce.
Upgrading from 0.14.1 for Sites which use Subscriptions
If you were using the Beta version of eCommerce Subscriptions (versions 0.14.1 and lower) and you have not yet upgraded your eCommerce Module, your Sites will continue to work as normal.
However, after upgrading to the eCommerce Module 1.0.0, Stripe webhooks must be set up.
You should also make sure that your Secure Zones Module is up to date.
Bug fix for Checkout sometimes displaying logs.
Output CFS data on Order Detail views (and in emails)
Show Cart total price on Checkout views
Spam protection for Stripe endpoints
Support for 'Add to cart' button on Product list views
Order details in Workflow and Autoresponder emails
Performance updates for Product output - You should find list views loading far quicker than before this update
Discount Codes
Cart Live Updating
Fix for Custom Field Set output on Product layouts
Store Shipping Method name against Order rather that just the ID and cost
Browser Support updates
Allow '+' in email addresses used on payment forms
Stripe - Check if stored customer exists before processing them
Shipping Options
Quotes
\
In this section, we'll add reference code which is relevant across Modules. Specific Modules may have further relevant reference material in their own sections of the docs.
These Fields are available to all standard modules:
Usually this is not outputted directly. Instead, a detail page is dynamically generated for you by the Siteglide Admin at the chosen slug, however, it can be useful in some situations to output manually!
id
- the Module's ID
item_ids
- output one or more module items, comma separated
category_ids
- output all items in one or more categories, comma separated
layout
- default is /default/ - 'layout' values are relative to the folder: layouts/modules/Blog (module_3)/[layout name]
per_page
- defines the number of items outputted on the page
show_pagination
- default is true - defines if items should be paginated when the per_page is met.
sort_type
- defines the type by which items are ordered
properties.name
- name of the Module item (alphabetical)
created_at
- date the Module item was created
updated_at
- date the Module item was last edited
properties.weighting
- weighting of the Module item
properties.release_date
- date the item is set to be released
properties.module_field_3_1
- Sort by a core or custom field
sort_order
- defines the order in which the type is sorted asc - sort items in ascending order desc - sort items in descending order
collection
- default is 'false' - If you set it as collection: 'true' then any layout is suppressed.Data is accessible via {{context.exports.webapp_1.data}}. For Example, name would be: {{context.exports.webapp_1.data.result.items[0]['name']}}
use_search
- Allows the Module to be searched by keyword parameter in URL
use_adv_search
- Allows the Module to be filtered by core/custom field IDs in URL parameters
datasource
- true
/false
- When outputting a "nested" module inside another, the inner module tag can be given this parameter to prevent it from inheriting parameters which would change its page etc.
If you nest any more Module or WebApp layouts inside this Module Layout, they will inherit the type parameter. This means if you want to input a nested list layout, you may need to reset the type parameter back to list with type: 'list'
.
To get the most recently "released" item, you can use the sort_type
parameter to sort by properties.release_date
. You can alternatively use created_at
to sort by the Item you most recently added to the Admin.
`
`
Then just output one post- to get the first Item. To do this, set per_page
to 1
.
Use the sort_order
to control whether you get the first or last item. To get the latest Item by date, the date will have a higher value, so use 'desc'
(starts with highest number) rather then 'asc'
.
Building Modules could be the perfect way to keep your workflow "DRY" (don't repeat yourself)! If you find a common requirement on more than one site, and no-one is currently offering a solution, or you think you can build a better one, building Modules might be for you.
This documentation section is a work in progress. If you have any questions in the meantime, please don't hesitate to get in touch and we'd be happy to help!
For some types of Module, anyone can have a go, for example building a Site Template could be done by a Designer with a little bit of HTML and CSS knowledge:
For other kinds of Module, we recommend getting hold of a developer. If you don't have one, check out Sitegurus who can provide this service.
One way to start building Modules is to build them as an internal tool for your Agency. This doesn't require any approval from Siteglide.
Or, you can publish your Module on the marketplace. This requires Siteglide approval so we can check the module is transparent about the kind of code it runs. You can either:
Make the Module Open-Source
You can either all Siteglide users access, or require them to contact you before you decide whether to give their organisation access
You can optionally allow others to contribute to your Github repository
or Accept Payments
In Siteglide, some fields can be given the datasource and datasource_multi field types: These are designed to store IDs of other records to make joining easy. However, you can also in GraphQL join other types of fields.
Head over to Marketplace and click the blue . Next, follow the usual Module creation process, but be sure to select the “Template” category from “Category” the dropdown field in the Module Details tab.
Within our private
folder we can store any files that Siteglide natively supports, such as GraphQL, Liquid, Assets etc. More information about folder structure can be found at .
You only need to fill in basic information into the core fields. Checkout the doc for more information.
First, create a fresh staging site for your module. Checkout : for more information on this step.
Next, create a top level folder called modules/<module_name>/public
within your project folder. Because we are creating a basic theme Module, we don’t need to create the private top level folder. Checkout for more info.
Setting Pages up with appropriate Template, Header & Footer files allows us to only write the code once and apply it consistently across all of our theme pages. It also makes it easier to update later if we’d like to. For more information on page structure checkout: .
Create a file called install-process.json on the root folder of your Module Project (alongside /modules/). Checkout for more info.
Using CLI run the to send all of the files within your project folder up to your staging site.
Your site should now look and behave like this front-end: .
Your Module is in a branch named master in your GitHub Repository. This is the only branch Siteglide will read from. Note that Github may name your branch main by default. If that happens you can change that
Next we will need to update the Module item that you made in Admin earlier to include some extra information. Checkout the doc for more information.
Once you’ve submitted your Module for approval you’ll need to give us access to see the Module. This is needed for the initial approval, but also for ongoing access to be able to install the latest version of the Module. To provide us with access you need to invite Siteglide API ( ) as a collaborator for the GitHub Repository. Checkout the doc for more information.
There are a couple of key things you should be aware of when managing and updating your module moving forward. Checkout this doc for more info: .
Read more about Module Directory Structure on platformOS:
Allow constants such as Company Information to be used in email notifications -
Added support for custom success functions to be used with Forms. Default action will remain as a redirect to your chosen URL -
Swap the order of 404 response and include for WebApp/Module list views -
New 'match_type' option on WebApp/Module filtering.
Minor patch to add support for
Sitemap XML - Updated homepage to use root URL, rather than the page slug (e.g. /home) -
Fix to allow multiple site searches on a page -
Support for structural changes introduced in
WebApp Edit Forms -
Form confirmation Pages -
Official release of an update to support forms on shared devices. This has been in place for some time as a trial -
Further performance updates for
Custom Pagination layouts - You can now define the layout for pagination.
Datasource performance updates - We've greatly improved performance of Datasource output.
Site Search - Added support for buttons to submit the search, rather than relying on keyboard controls -
Site Search - Fixed an issue where Pages were showing in search results, even though 'Visible to search' was turned off -
reCAPTCHA Security upgrade -
Support for Blog Archive feature -
Tax Rounding - Can now change how the tax system rounds prices. System default is 'Round on item', and you can change this to 'Round on row' or 'Round on total' -
Add custom callback support for and -
Now checks if a custom empty cart layout exists, and if it doesn't we fallback to the default layout, rather than displaying an error message -
Basic Payments - Allow setting of Payment Gateway using include parameters -
Support for decimal tax percentages - . It is a good idea to test this update using your own Siteglide Demo Site in order to make sure calculations are working as you would expect for your project.
Minor patch to support new field types -
Find the full list
You can now add multiple payment method options to a checkout layout ->
- This allows you to set which Tax Codes apply to a Shipping Option, and display prices inc/ex Tax on Cart and Invoice layouts.
An upgrade to Product output in line with
Tax Code system -
Volume Pricing - You can now set prices to change depending on how many items are purchased by the user. For example, you might say "buy 1 for $10, or 3 for $8 each" -
Added support for the s_e_update_price() function on Product List View Pages. Roadmap:
You can learn more about the new features and how to implement Subscriptions on your sites here:
Field Name
Liquid Tag
Description
Item Name
{{ this['name'] }}
name of the Blog Post
Item Slug
{{ this['slug'] }}
item URL
Weighting
{{ this['weighting'] }}
weight of item, used for sorting
Release Date
{{ this['release_date'] }}
release date of the item
Expiry Date
{{ this['expiry_date'] }}
expiry date of the item
Enabled
{{ this['enabled'] }}
enable/disable the item
Support for Automations structure
Updated default layouts to use Siteglide Studio (this won't overwrite existing installed layouts)
Fixed a bug where double quotes in Event names would cause invalid JSON when using default Calendar Layout. This fix will only apply to new Sites so as to not overwrite Layouts you may be using.
To fix manually on existing Sites, replace the following line in your item.liquid
file:
"title": "{{this.name}}",
...with:
"title": {{this.name | json }},
UX improvements to Default Detail Event Layouts.
New installs of the Events Module will have improved default Detail Layouts. Previously you had to click through to the Product Detail Page to buy tickets, but this can now be done straight from the Events Detail Page. This should mean a simpler UX experience.
For existing Events and eCommerce Module users, you can easily add this functionality, should you wish to upgrade.
Add keyword search to default Events List Layout
Initial release
Add more logging to Form Submissions to support debugging
User Form Submissions - Expose human-friendly names for fields - Roadmap
Updated security as outlined in System Files update v2.8.2.4
Added Form ID to password reset Form to better handle error messages
Support for Automations structure
Patch for slug on User Orders output
Add support for new eCommerce Order structure on User Orders output via order_products_flat
Fix for Password Reset on previously deleted users
Access to CRM Company data on User Details output
Wording update on 'Add to Favourites' alert boxes
Access to CRM User Address data on User Details output
Add support to user_orders
for sorting and pagination
Updated default layouts to use Siteglide Studio (this won't overwrite existing installed layouts)
Updates to User Orders query to fetch Ordered Products
Made CRM Custom Field output easier by giving you access to field names (e.g. this['User Field XYZ']
)
Minor field changes ready for upcoming Module Custom Field updates
Important: Security update for Secure Zones
Our latest Secure Zone Module update fixes a security vulnerability in Sign Up Forms and is a recommended update for all Sites.
For most of our partners, no change in your code will be needed. Simply install the updated Module version 1.2.1. However, if your Site uses custom code to add Secure Zones not currently attached to the Form, you will now need to attach them to the Form.
Further Details:
It has been possible to use Front End code to change which Secure Zone a Sign Up Form will give Users access to. There were legitimate uses for this, however, if a malicious User with knowledge of JavaScript was able to guess a Secure Zones ID, they would have been able to sign themselves up to that Secure Zone.
After this update, only Secure Zones attached to a specific Form in Admin will be allowed when Front End code changes the active Secure Zone of a Form. Any other Secure Zones will be rejected by the server.
We have worked quickly to close this vulnerability after discovering it internally and thank you for your understanding.
Favourites - You can now add a button to WebApp/ Module layouts to allow logged in users to store items as 'favourite'
Email/Password edit - Users can now edit their Email Address and Password
User Secure Zones - This data array can now be accessed in Templates as well as Pages
Structural changes to improve performance and usage costs.
CRM Secure Zone data is now stored as User Properties rather than as User Profiles. Any custom extensions of this database will require you to change to the new field before updating your Module. All data is migrated to the new field on update.
Accessing data before: session.current_user._user_.properties.secure_zones
Now: session.current_user.properties.secure_zones
If you apply this update, then your eCommerce Module should be updated to at least v1.0.4 in order to fully support this change.
Support for Secure WebApp items
User Subscriptions View updated to include new Subscriptions functionality.
CRM - You can output Custom Field Set data with the rest of User Details
Forms - Slight improvement to performance on Secure Zone signup forms, by combining 2 system level calls into 1
Fix for missing name in Password Reset emails
Fix for Password Reset emails not sending if user was previously deleted
Browser Support updates
Bug fix - Secure Zones blocked signup -
Initial report here -> https://roadmap.siteglide.com/bugs/p/secure-zones-second-signup-with-same-email
If someone submitted a basic contact form, and then a Secure Zone signup form with the same email address, they'd see a "Invalid email or password" error, even though they'd never set a password before.
Allow custom redirects after a Password Reset request has been submitted
Added support for older browsers
Fix a broken layout (missing '{')
Support for Automations structure
Added easier support for multiple Sliders of the same Layout to be added to the same Page using the Liquid parameter: uniq_slider_id
to provide each instance of a Layout with a unique ID that will be selected by the JavaScript.
Added logic to the Slider Layouts to make sure the Layout contents are not loaded when no Slider Items are available in the Module (after filters are applied). This fixes a bug where if there were no available items, the JavaScript would experience an unhandled error.
Slider Module is released. - Add images and content to your Slides in Admin and display on a Site either using our custom Layouts or creating your own.
SiteBuilder is the quickest way to get started with Siteglide