box(Str) -> {'div',[{class,"box"}], {pre, [], yaws_api:htmlize(Str)}}. tbox(T) -> box(lists:flatten(io_lib:format("~p",[T]))). ssi(File) -> {'div',[{class,"box"}], {pre,[], {ssi, File,[],[]}}}. out(A) -> [{ssi, "TAB.inc", "%%",[{"dynamic", "choosen"}]}, {ehtml, [{'div', [{id, "entry"}], [ {h1, [],"Generating Dynamic Content"}, {p,[], ["Yaws has very nice support for generating dynamic content on the fly. " "We use embedded erlang code to generate the content. The Erlang code " "is separated from the HTML code by ", {tt, [], "<erl>"}, " and ", {tt, [], "\</erl>"}, " markers. For example: "]}, box(" Foobar
\out(Arg) -> {html, \"Funky Stuff\"}. \ Baz
"), {p,[], ["Is a very small example where we have a HTML document with embedded " "erlang code. A file which contains embedded erlang code must have the file " "suffix ", {tt, [], ".yaws"}]}, {br,[],[]}, {p, [], "The embedded erlang code can return the different values which will " " trigger the yaws webserver to do different things. We list some of the simple " " return values here: "}, {ul, [], [{li,[], [{p, [], [{tt,[],"{html, DeepCharOrBinaryList}"}, " Which will make the value of ", {tt, [],"DeepCharOrBinaryList"}, " be substituted into the HTML document."]}]}, {li,[], {p,[], [{tt,[],"{ehtml, ErlangTermStructure}"}]}}]}, {p, [], ["It is often more convenient to return " "erlang terms which are then transformed to HTML instead " "of returning plain HTML in string form using the ", {tt,[], "html"}, " tag "]}, {p,[], ["Using the ehtml return value, we can return deep structured " " erlang terms that correspond directly to HTML code. For example: "]}, box(" {table, [{bgcolor, \"tan\"}], {tr, [], [{td, [{width, \"70%\"}], {p, [{class, \"foo\"}], \"Hi there\"}}]}} "), {p, [], "Corresponds to the following HTML code: "}, box(""), {ul, [], [{li,[], {p,[], [{tt,[], "{header, Header}"}, " If a " , {tt, [], "header"}, " structure is returned, an additional header is inserted among the HTTP headers generated by yaws. " "This is used to insert for example Set-Cookie headers. The ", {tt,[], "Header"}, " variable must not be newline terminated."]}}, {li,[], {p,[], [{tt,[], "{allheaders, Header}"}, " If an ", {tt, [], "allheaders"}, " structure is returned, all previous headers that have been generated, including those " "default hedaers generated by yaws itself are erased, and replaced by " "the headers in ", {tt, [], "Headers"}, ". The variable ", {tt,[], "Headers"}, " must be a list of ", {tt, [], "{header, Str}"}, " tuples. The ", {tt, [], "Str"}, " must not be newline terminated. "]}}, {li,[], {p,[], [{tt, [], "{status, StatusCodeInt} "}, "Is used to force yaws to return a different status code than the " " default 200 code."]}}, {li,[], {p,[], [{tt, [], "ok"}, " Do nothing."]}}, {li,[], {p,[], [{tt, [], "{content, MimeType, Content} "}, "Sets the mime type, that is " "the Content-Type: header to be ", {tt, [], "MimeType"}, " The default value is of course \"text/html\", but applications that " "generate i.e wml or pdf, must set the Content-Type. " " A pdf generating application can for example return the " "tuple ", {tt, [], " {content, \"application/pdf\", PdfContentData} "}]}}, {li,[], {p,[], [{tt, [], "{redirect, URL} "}," a redirect is issued to the location in ", {tt, [], " URL "}]}}, {li,[], {p,[], [{tt, [], "{redirect_local, Path} "}," a redirect is issued to the local " "server using the same method (http or https) as the incoming request " " and the path part of the location header to the value in ", {tt, [], " Path "},"."]}}, {li,[], {p,[], [{tt, [], "{'EXIT', normal}"}," which will terminate the " " client connection in an uncontrolled way. "]}}, {li,[], {p,[], [{tt, [], "{ssi, File, Delimiter, Bindings}"}, " Using this construct, we can deep inside a ehtml structure, " " return (ssi) Server Side Include content from a file. " "This construct is further described in ", {a, [{href, "ssi.yaws"}], "ssi.yaws"}, "."]}} ]}, {p,[],["The embedded erlang code can also return a list of the " " above values. For example the following value "]}, box(" [{status, 303}, {allheaders, [{header, [\"Location: \",\"https://www.funky.org/\"]}, {header, [\"Set-Cookie: \",\"namn=ruler;\"]} ]}, {html,\" Redirected to funky.org \"} "), {p,[],"Can be returned if we want to issue a redirect and set a cookie " "at the same time."}, {p,[],["All possible return values from the out/1 function are documented in " "the man page for ", {a, [{href, "yman.yaws?page=yaws_api"}], ["", {tt, [], "yaws_api (5)"}]}]}, {p,[],"It can also be instructive to look at the actual source " "for the pages we are viewing at this very moment. Here are some of them"}, {ul, [], [ {li,[], [{p,[], [{a, [{href, "index.yaws"}], "The top page, index.yaws"}, " and then the ", {a, [{href, "code.yaws?file=/index.yaws"}], "corresponding source"}]}]}, {li,[], [{p,[], [{a, [{href, "dynamic.yaws"}], "This page, dynamic.yaws"}, " and then the ", {a, [{href, "code.yaws?file=/dynamic.yaws"}], "corresponding source"}]}]} ]}, {h2,[],"The argument "}, {p,[],["The ", {tt, [], "out/1"}," function is supplied with a record argument. The " "definition of that record is automatically included in the embedded erlang code " "and the record definition is: "]}, ssi("ssi/dynamic.2"), {p,[], "And some of the refered records are defined as:"}, ssi("ssi/dynamic.3"), {p, [], "Each chunk of erlang code will be compiled into a separate module. " "The module names are automatically generated. If we have functions inside the " "erlang chunks that we want to call from other chunks or modules, it is possible " " to explicitly name the modue that will be used as in: "}, box(" \
Hi there
out(A) -> io:format('This is the foobar module',[]). func() -> i_am_exported_from_foobar. \ ") ]}]}].out(A) -> {ssi, "END2",[],[]}.