An app for Force to build a website
This library requires Force library.
This website
function cannot be called just the way it is, because the first parameter is app
object from Force.app
instance.
The app
object must contains method init
and app
property, as Force's Manual
This app
will generate globals readonly object ForceWebsite
, to help its plugins, themes and kitchen to relate to it.
Create tag script to store the configuration, with type application/json
.
<script type="application/json" id="website-config"></script>
Don't forget to put some ID, so that next going to be easy to get the text content.
And the sample of the text content as the following.
{
"force": {
"file": "https://9r3i.github.io/force/force.min.js",
"cache": {
"age": 2592e5,
"description": "3 days in mili second = 3*24*60*60*1000",
"default": 864e5
}
},
"data": {
"host": "https://sabunjelly.com/api/force/",
"base": "foxtrot",
"driver": "ForceData"
},
"site": {
"name": "9r3i",
"description": "The sly eagle doesn't kill at whim",
"keywords": "9r3i, Force, Foxtrot",
"robots": "follow, index",
"date": {
"year": "2022",
"full": "2022-11-13 05:35:44"
},
"data": {}
},
"kitchen": {
"namespace": "kitchen",
"host": "https://9r3i.github.io/force-kitchen",
"key": "kitchen"
},
"theme": {
"namespace": "foxtrot",
"host": "https://9r3i.github.io/foxtrot-theme",
"config": {
"data": {
"limit": 8,
"foot": 55
}
}
},
"plugins": [
["configuration",false,
"https://9r3i.github.io/force-website-plugins"
],
["menu",[
{
"href": "?home",
"text": "Home"
},
{
"href": "?p=tulisan-pertama",
"text": "Tulisan Pertama"
},
{
"href": "?search",
"text": "Search"
},
{
"href": "?kitchen",
"text": "Login"
}
],
"https://9r3i.github.io/force-website-plugins"
],
["site",false,"https://9r3i.github.io/force-website-plugins"],
["grid",false,"https://9r3i.github.io/force-website-plugins"],
["timeago","id_ID",
"https://9r3i.github.io/force-website-plugins"
],
["visitor",false,"https://9r3i.github.io/force-website-plugins"],
["locode",false,"https://9r3i.github.io/force-website-plugins"],
["arabic","arabic",
"https://9r3i.github.io/force-website-plugins"
],
["link",false,"https://9r3i.github.io/force-website-plugins"],
["social",[
"sharer",
"like",
"qrcode"
],
"https://9r3i.github.io/force-website-plugins"
],
["search",{
"id": "body",
"holder": "Search...",
"key": "search"
},
"https://9r3i.github.io/force-website-plugins"
],
["land",false,"https://9r3i.github.io/force-website-plugins"],
["slider",{
"id": "body",
"images": [56,57,58,59]
},
"https://9r3i.github.io/force-website-plugins"
]
],
"coverLoader": false
}
The config above, I use for configuration of my website, https://9r3i.web.id/, visit it if you wish.
Read more about website
app configuration detail in Force's Website Sample
Create tag script to store the configuration, without attribute src
.
<script id="force-script"></script>
Don't forget to put some ID, so that next going to be easy to get the text content.
Next is the calling of the app.
(async function(n,h,cnf,f){
var ctag=document.getElementById(c), // script tag of website configuration, see configuration section
ftag=document.getElementById(f), // script tag to load force script
fname='force/virtual/force.js', // virtual path
fscript=localStorage.getItem(fname), // get the force script if it's already stored in virtual file
cnf=JSON.parse(ctag.textContent); // parse the config
if(!fscript){ // check if it's not stored yet
fscript=await fetch(cnf.force.file).then(r=>r.text()); // fetch the force.js file
localStorage.setItem(fname,fscript); // store the force script into virtual file, so next time it won't be loaded anymore
}
ftag.textContent=fscript; // load the force script, immedietly executed by the browser
const app=(new Force).app(n,h,cnf); // prepare the app using Force app instance
await app.init(); // initialize the app
console.log("A Force app has been loaded, namespace: "
+app.namespace);
})(
'website', // website app namespace
'https://9r3i.github.io/force-website', // host of ForceWebsite
'website-config', // from configuration section
'force-script' // script tag where to store the force.js script
);
Force
inherited object of Force (readonly)version
string of this website app (readonly)root
string of website rootconfig
object of website configapp
inherited object of given parameterapp
theme
object of prepared themekitchen
object of prepared kitchenquery
object of parsed url querydata
object of loaded data, index to the slugsbulkRaw
array of loaded raw dataplug
object of registered and prepared plugins, beforeinit
plugLoaded
int of number of loaded pluginspkey
string of privilage keykkey
string of kitchen key
The methods below is part of the app that has auto-call to proceed on it.
init
async function of initialization, this method is required byForce.app
to initialize the app, auto-callloadPage
async function to load a page uponpopstate
event, auto-callfetchConfig
async function to loadsite.data
config from server, auto-callfetchAllData
async function to load all data from server without values of contents, and parsed toForceWebsite.data
, auto-call except for kitchen in the first load.themePrepare
function to prepare a theme or kitchen, auto-callfinishing
function to let the app finish the rest of works, including plugins initialization and anchors initialization, auto-call except when the kitchen or theme exit in the middle of processfillPageData
function to fill page with data, this method is auto-call, but can be recall if necessary, parameters:content
string of content to filldata
object of data input
anchorInit
function to initialize all anchors, it's called byloadPage
, means it's auto-call, but i think it won't be conflict if it's called twiceanchorExec
function of event callback from initialization ofanchorInit
, means it's auto-callkitchenSet
function of kitchen set, auto-call, inner method onlyslideHeadLoader
function to show progress of loading, auto-call while preparing pluginsheadLoader
function of head loader, auto-call fromslideHeadLoader
loadProgress
function of progress callback, auto-call formfetch
if turn it on
These methods are inner method but also used to be a helper
setTitle
function to set title, it's also auto-call but there won't be conflict if it's called again, parameters:txt
string of titleasHTML
bool of put as html usinginnerHTML
instead ofinnerText
; default:false
setMeta
function to set html meta data, parameters:name
string of meta namecontent
string of contentkey
string of meta key; default: name
findDataSpace
function to find chain of namespaces splitted by dot, parameters:n
string of data namespacesdata
object of data spacesao
bool of object as output; default:false
go
function to jump the history statement where thelocation.href
is popped in statement, it's being auto-call byloadPage
andanchorExec
, but it will help much for kitchen, theme and plugins, parameters:href
string of url to attach inlocation.href
as statement, and it's not gonna work ifhref
is the same aslocation.href
fetch
function to fetch data from ForceServer using methodGET
, it's been set to database name and host, parameters:mt
string of force method (NOT request method)cb
function of callback, return argument of mixed datadt
object of data to be merged to the url query, so DO NOT put something secret on it
request
function to fetch data from ForceServer using methodPOST
, mostly it's used in Kitchen page, parameters:mt
string of force method (NOT request method)cb
function of callback, return argument of mixed datadt
object of data to be merged intoPOST
data query
upload
function to upload TEMPORARY content to the server, parameters:file
blob of file; *requirecb
function of return callback, return: string of temporary data ID or structure.ul
function of upload progress callback
loadFile
function to load a file path or url, from virtual file if exists or load then save into virtual file, parameters:f
string of file path or urlcb
function of callback, return a string of file content
getFileContent
function to get file content from virtual file if exists or load then save into virtual file, return string of file content, parameters:f
string of file path or urll
bool of force to load even it exists
These methods are used to be helper
contentURL
function to generate content url of a data, parameters:id
number of data IDrand
bool of use random query to prevent browser cache
imageURL
function to generate image url of a data, parameters:id
number of data IDrand
bool of use random query to prevent browser cache
call
function to help call inner function; it's auto-call infillPageData
, but it will be necessary for plugins to execute some operational, parameters:fn
function to applyargs
array of arguments
onContentReady
function of ready state of content element detected usingdocument.getElementById('content')
, return intocallback
function, object the content element orfalse
if failed, parameters:cb
function of callbacki
int of counter; auto-generate
kitchenFormHelper
function to help form onsubmit
, parameters:e
object of submit event of thr form- This will return an object with properties and methods:
data
object of data, key asdata.name
and value asdata.value
submitter
object element of submittertarget
inherited object fromevent.target
web
object of global ForceWebsitedisable
function to disable all inputs in range of the formenable
function to enable all inputs in range of the formsend
function to send data to the server usingForceWebsite.request
, parameters:mtd
string of force methodcb
function of callback, after request sent, argument is result from the serverbb
function of callback, before request, argument isthis
object
This auto-call
means no need to be worried, because it's only worked inside the app, and no plugin, no theme and no kitchen will use this method.
That's all there is to it. Alhamdulillaah...