this is docs to be filled
#define LOG_LEVEL 4
#include "peanut_butter.h"
ROUTED(home){
if(is_method("GET")){
return render_html("/htmls/index.html");
}
return render_html("/htmls/method_not_allowed.html");
}
ROUTED(about){
return render_html("htmls/about.html");
}
URL_VAR_ROUTED(user_home){
TEMPLATE_INIT();
if(URL_VAR_INDEX(0,d)==123){
QUERY_INIT();
for (int i = 0; i < QUERY_LENGTH(); ++i){
TEMPLATE_ASSIGN(QUERY_INDEX(i).name,QUERY_INDEX(i).value,s);
}
return render_template("htmls/template.html");;
}
if(URL_VAR_INDEX(0,d) < 123){
return render_html("htmls/index.html");
}
return redirect("/",302);
}
int server(){
URL("/",home);
URL("/about",about);
VAR_URL("/%d/%d/%s/home",user_home);
return server_run("8080");
}
int main(void){
return server();
}
-
URL(route_string,view_callback):-
URL
is a macro that added the route to global RouteTable -
VAR_URL(route_string,view_callback_args):-
It is same asURL
with a catch, you can add string formator as a place holder ; allowing us to make a dynamic url, taking the above example route ="/%d/%c/%s/home"
it matches following case scenarios 1./1/a/a string/home
2./2/b/b string/home
...- in place of
%d
you can have any integer - in place of
%c
you can have any character - in place of
%s
you can have any string as long as it doesnot contains/
, if you want/
you can urlencode it - you can also combine them as
/%d%c%d%s/home
and many more - !! NOTE !!,
%s
is greedy, meaning,%s
should be used at last or solo as it consume everything until/
, so these will not work as expected/%s%d/
/%s%s/
...
- in place of
-
server_run(port_string):- take port number as string, and intializes the server,
server_run
should be last funciton to be called from main funciton, as it will start the server loop and anything after it will only execute after server is closed.
⚠️ ⚠️ NOTE⚠️ ⚠️ ,URL(x,y)
should be beforeserver_run
, otherwise routes wont be added to server RouteTable, when server runs. -
render_html(request,html_file_path):- As name suggests
this function returns html file to be displayed. -
render_template(request,html_file_path,TEMP_VAR()):-
this function is same asrender_html
with a additional argument,TemplateVars
, this is usefull when you want to use template html file with place holders that can be dynamically replaced . html_file_example<!-- template.html---> <div> Hello {{name}}, How Are You. Your Role is {{role}}. </div>
Here ,
{{template_name}}
is a place holder, that can be replaced dynamically. example_pb_code for above htmlvoid user_home(Request request){ TEMP_INIT(); //template should be initialized before using it TEMP_VAL("name","Leyuskc",s); TEMP_VAL("role","admin",s); return render_template(request,"template.html",TEMP_VAR()); }
ViewCallback = func(Request request);
// ViewCallback are functions that take Request as first parameter
void home(Request req); // ✅ valid
void about(Request req,int abc); // ❌ invalid
// ViewCallback must only take requests as parameter
ViewCallbackArgs = func(Request request,UrlVariables url_variables);
// ViewCallbackArgs are functions that take
// 1. Request as first parameter
// 2. UrlVaribales as second arguments
void user_home(Request request,UrlVariables urlags); // ✅ valid
void about(Request req,UrlVariables urlags,int abc); // ❌ invalid
// ViewCallbackArgs must only take requests and UrlVaribales as parameter
UrlVariables = {
union value;
uvar_type type;
};
UrlVariable urlvar;
urlvar.value ; // value direct is the base to access any value their is
// to be specific you can add prefix accordingly
/*
urlvar.i_value -> for integer
urlvar.s_value -> for char* or string
urlvar.c_value -> for char
urlvar.f_value -> for float
urlvar.d_value -> for double
*/
urlvar.type; // type determines what the value holds, it can be
// char,char*,int,float,double
UrlVariables = {
UrlVariable *args;
uint8_t length;
};
UrlVariables urlvar;
urlvar.args ; // args is the list of UrlVariable
urlvar.length; // length is how many elements are their in args
TemplateVar = { char *name; UrlVariable value; }
TemplateVars = { TemplateVar *templ; uint8_t length; } ;
typedef struct{
char *name; // tempalte name
UrlVariable value; //template value, read UrlVaribale for more info
}TemplateVar;
typedef struct{
TemplateVar *templ; // list of TemplateVar, read above
uint8_t length; // total template count
} TemplateVars;
- it has three main
macros
TEMP_INIT()
:- this must be called before using templatesTEMP_VAL(template_name,template_value,template_type)
:--
template_name: a string
-
template_value : it can be any of these data type, int,char,char*,float,double
-
template_type:- its a single character defining type of template_value
s
->string/char*
i
->int
f
->float
d
->double
c
->char
!! Note !! this is compile time constant, so it is not character/string, its a direct symbol code example
-
TEMP_VAL("name","Leyuskc",s); // ✅ valid
TEMP_VAL("name","Leyuskc",'s'); // ❌ invalid
TEMP_VAL("name","Leyuskc","s"); // ❌ invalid
look at the s
its like a expression it self not a value, so
template type should be determined during the compile time
TEMP_VAR()
:- invoke this macro where ever it calls for TemplateVars in your code, but remember to invokeTEMP_INIT()
first.
Any error will be detected during compile time and it will break. So don't worry about it slipping in production. The errors will look wired for now