RejectedSoftware Forums

Sign up

Adding a Filter

Ahoy

I am trying to add another filter to a diet template so that instead of

   :javascript
      test();

I want to add something for doing WebGL programming, so my diet template would look like

   :shaderfs
       test();

I have tried merely replicating the javascript blocks in http.server.d like

static string filterShaderFS(I)(I text, size_t indent = 0)
{
	// added a simple return string here
	return "<script id=\"shader-fs\" type=\"x-shader/x-fragment\">" ~ '\t' 
		~ "precision mediump float;" ~ '\t' ~ "</script>";
}
...
static this()
{
	filters["css"] = (input, scope output) { output(filterCss(input)); };
	filters["javascript"] = (input, scope output) { output(filterJavascript(input)); };
	filters["markdown"] =(input,scope output) { output(filterMarkdown(cast(string)input)); };
	filters["htmlescape"] = (input, scope output) { output(filterHtmlescape(input)); };
	// added this in
	filters["shaderfs"] = (input, scope output) { output(filterShaderFS(input)); };
}

Also in vibe.templ.diet.d

static this()
{
	registerDietTextFilter("css", &filterCSS);
	registerDietTextFilter("javascript", &filterJavaScript);
	registerDietTextFilter("markdown", &filterMarkdown);
	registerDietTextFilter("htmlescape", &filterHtmlEscape);
	registerDietTextFilter("shaderfs", &filterShaderFS); // added this in
}
...
foreach_reverse( f; filters ){
	bool found = true;
	switch(f){
		default: found = false; break;//break filter_loop;
		case "css": content = filterCSS(content, out_indent); break;
		case "javascript": content = filterJavaScript(content, out_indent); break;
		case "markdown": content = filterMarkdown(content, out_indent); break;
		case "htmlescape": content = filterHtmlEscape(content, out_indent); break;
 // added this in
		case "shaderfs": content = filterShaderFS(content, out_indent); break; 
	}
	if (found) filters.length = filters.length-1;
	else break;
...

static string filterShaderFS(string text, size_t indent)
{
	return "<script id=\"shader-fs\" type=\"x-shader/x-fragment\">" ~ '\t' 
		~ "precision mediump float;" ~ '\t' ~ "</script>"; 
}

I can't see any other locations that javascript is mentioned that is worth changing.

The code that implements the filters seems to my simple brain to be quite convoluted.

If I create a simple working app, then add in the shaderfs line

doctype 5
html(lang="en")
	head
		title Uploader

		:shaderfs
			test();

		:css
			.test

I get the following

[lots of log stuff]
...
webserver ~master: building configuration "application"...
Compiling Diet HTML template studio.dt...
studio.dt(7,20): Error: function vibe.http.server.staticTemplate!"studio.dt".staticTemplate.__lambda1.filter!(req, DefaultFilters).filter (const(char[]) input, string filte
r, void delegate(const(char[])) nothrow @safe output) is not callable using argument types (string, string, void)
../../../../../.dub/packages/diet-ng-1.1.3/diet-ng/source/diet/html.d(91,7): Error: template instance vibe.http.server.staticTemplate!"studio.dt".staticTemplate.__lambda1.c
ompileHTMLDietFile!("studio.dt", req, DefaultFilters).exec!(StreamOutputRange!(OutputStream)) error instantiating
../../../../../.dub/packages/vibe-d-0.8.0-beta.2/vibe-d/http/vibe/http/server.d(240,63):        instantiated from here: compileHTMLDietFile!(StreamOutputRange!(OutputStream
))
../../../../../.dub/packages/vibe-d-0.8.0-beta.2/vibe-d/http/vibe/http/server.d(163,6):        instantiated from here: render!("studio.dt", req)
source/webserver.d(25,13):        instantiated from here: staticTemplate!"studio.dt"
dmd failed with exit code 1.

Any pointers towards where I could look to get something like this working?
Are there other files I need to be considering?

Thanks in advance.
B

Re: Adding a Filter

Any takers?

I believe the main change needs to be in the server.d code. Do I need to alter anything from the diet.d file or diet-ng package ?
Are the other files I should be considering aswell, or is the parsing of the filters contained within these?

Thanks.
B

Re: Adding a Filter

Am 01.03.2017 um 08:51 schrieb infinityplusb:

Any takers?

I believe the main change needs to be in the server.d code. Do I need to alter anything from the diet.d file or diet-ng package ?
Are the other files I should be considering aswell, or is the parsing of the filters contained within these?

Thanks.
B

The error message looks strange and from a first look I also couldn't
see where it went wrong. I hope I'll be able to have a deeper look
tomorrow or maybe the day after. There is still a time consuming bug on
my table, which is mainly why I couldn't give an answer yet.

Re: Adding a Filter

Am 01.03.2017 um 18:28 schrieb Sönke Ludwig:

Am 01.03.2017 um 08:51 schrieb infinityplusb:

Any takers?

I believe the main change needs to be in the server.d code. Do I
need to alter anything from the diet.d file or diet-ng package ?
Are the other files I should be considering aswell, or is the parsing
of the filters contained within these?

Thanks.
B

The error message looks strange and from a first look I also couldn't
see where it went wrong. I hope I'll be able to have a deeper look
tomorrow or maybe the day after. There is still a time consuming bug on
my table, which is mainly why I couldn't give an answer yet.

Forgot to mention, server.d is the only place that is needed to change
this centrally. You can alternatively also define a @dietTraits struct
in your own code and pass it to render.

Re: Adding a Filter

On Wed, 1 Mar 2017 18:28:43 +0100, Sönke Ludwig wrote:

The error message looks strange and from a first look I also couldn't
see where it went wrong.

Excellent! At least it's not something obvious, that makes me feel better. :D

Forgot to mention, server.d is the only place that is needed to change

I'll have a poke around and change everything in there then.

You can alternatively also define a @dietTraits struct

I have no idea what that is :P

Re: Adding a Filter

On Thu, 02 Mar 2017 07:09:20 GMT, infinityplusb wrote:

On Wed, 1 Mar 2017 18:28:43 +0100, Sönke Ludwig wrote:

The error message looks strange and from a first look I also couldn't
see where it went wrong.

Excellent! At least it's not something obvious, that makes me feel better. :D

Forgot to mention, server.d is the only place that is needed to change
I'll have a poke around and change everything in there then.

You can alternatively also define a @dietTraits struct
I have no idea what that is :P

Okay, turned out to be rather simple, although certainly not obvious. The function must be named filterShaderfs instead of filterShaderFS, or the filter invocation must be :filterFS instead of filterfs. I'll see what I can do to improve the error message.

Regarding the traits struct, it would look something like this:

@dietTaits struct CustomTraits {
    static string filterShaderfs(I)(I text)
    {
        return "<script id=\"shader-fs\" type=\"x-shader/x-fragment\">" ~ '\t' 
            ~ "precision mediump float;" ~ '\t' ~ "</script>";
    }
    static FilterCallback[string] filters;

    static this()
    {
        filters["shaderfs"] = (input, scope output) { output(filterShaderfs(input)); };
    }
}

void handleRequest(HTTPServerRequest req, HTTPServerResponse res)
{
    // Just pass it to any render() call and the filter will be available
    res.render!("test.dt", CustomTraits);
}