Do you want to work on this issue?
You can request for a bounty in order to promote it!
Saber Functions #183
egoist posted onGitHub
<!-- Please ask questions via following several ways. -->
<!-- https://chat.saber.land/ -->
<!-- https://stackoverflow.com/questions/ask?tags=saberjs -->
RFC: Saber Functions
functions
folder
Functions are used to fetch data that you can inject to pages at build time, let's say you have a posts.js
inside functions
folder:
exports.handler = async ({ type }) => {
const posts = await getAllPostsFromApi()
return posts.filter(post => post.type === type)
}
<small>Since we need to get the return value before running webpack, you can only write JavaScript with features supported by your system's Node version.</small>
Then a function called posts
will be available and you can use it like this in a page:
<script>
export const config = {
injectProps: {
drafts: {
function: 'posts',
options: {
type: 'draft'
}
}
}
}
export default {
props: ['drafts']
}
</script>
By using injectProps
here Saber will call the function at build time and inline result in your JavaScript bundle.
Pagination
We can create pagination based on injected props:
<script>
export const config = {
paginate: {
prop: 'drafts',
perPage: 30
},
injectProps: {
drafts: {
function: 'posts',
options: {
type: 'draft'
}
}
}
}
export default {
props: ['drafts']
}
</script>
Exporting function
A function can be exported as a page just like a normal page, only thing you need to do is setting config.export
option to true
:
// functions/atom.xml.js
const getPosts = require('../get-posts')
exports.handler = async () => {
const posts = await getPosts({ type: 'public' })
const xml = generateXMLFeed(posts)
return xml
}
exports.config = {
export: true
}
When export
is true
, Saber automatically infers the actual link from its filename, in this case it would be /atom.xml
. You can also set it to a string
to use whatever permalink you want, e.g. /subscribe/rss.xml
.
When export
is true
, the function's argument would be undefined
unless you use dynamic parameter in its filename, for example functions/pages/[slug].json.js
:
exports.handler = ({ slug }) => {
return getPageBySlug(slug)
}
exports.config = {
export: true
}
exports.getStaticPaths = () => {
return [
{ slug: 'hello-world' },
{ slug: 'another-page' }
]
}
Because the path is dynamic you also need getStaticPaths
to define a list of paths that need to be rendered at build time.
Now when you visit /pages/hello-world.json
, then function argument will be { slug: 'hello-world' }
Adding a function from plugins
saber.functions.add(FunctionObject)