Skip to content

Commit

Permalink
Fixed compile-time AA's
Browse files Browse the repository at this point in the history
Compile-time AA's are now fixed and compiles with the latest version of DMD.

Also implemented new functions for views to render, caching, as well redirect functionality for controllers.
  • Loading branch information
bausshf committed Oct 13, 2017
1 parent 1c98cfe commit 83e8f61
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 32 deletions.
28 changes: 28 additions & 0 deletions src/controllers/controller.d
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,20 @@ version (WebServer) {
return Status.end;
}

/**
* Redirects the response to a specific url.
* Params:
* url = The url to redirect to.
* status = The status of the redirection. (Default is HTTPStatus.Found)
* Returns:
* The status required for the redirection to work properly. (Status.end)
*/
Status redirectTo(string url, HTTPStatus status = HTTPStatus.Found) {
_view.response.redirect(url, status);

return Status.end;
}

/**
* Handles the view's current controller action.
* Returns:
Expand Down Expand Up @@ -181,6 +195,20 @@ else version (WebService) {
return Status.end;
}

/**
* Redirects the response to a specific url.
* Params:
* url = The url to redirect to.
* status = The status of the redirection. (Default is HTTPStatus.Found)
* Returns:
* The status required for the redirection to work properly. (Status.end)
*/
Status redirectTo(string url, HTTPStatus status = HTTPStatus.Found) {
response.redirect(url, status);

return Status.end;
}

/**
* Handles the view's current controller action.
* Returns:
Expand Down
2 changes: 1 addition & 1 deletion src/controllers/status.d
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ enum Status {
notFound,
/**
* Indicates the response should end after executing the actions.
* This is useful if you respond with a different type of data than html such as json etc.
* This is useful if you're redirecting or responding with a different type of data than html such as json etc.
*/
end
}
40 changes: 22 additions & 18 deletions src/templates/parser.d
Original file line number Diff line number Diff line change
Expand Up @@ -10,48 +10,52 @@ import diamond.templates.characterincludemode;
import diamond.templates.part;

private {
enum grammars = [
'[' : new Grammar(
// HACK: to make AA's with classes work at compile-time.
@property grammars() {
Grammar[char] aa;
aa['['] = new Grammar(
"metadata", '[', ']',
ContentMode.metaContent, CharacterIncludeMode.none, false, false
),
);

'<' : new Grammar(
aa['<'] = new Grammar(
"placeHolder", '<', '>',
ContentMode.appendContent, CharacterIncludeMode.both, true, false
),
);

'{' : new Grammar(
aa['{'] = new Grammar(
"code", '{', '}',
ContentMode.mixinContent, CharacterIncludeMode.none, false, false
),
);

':' : new Grammar(
aa[':'] = new Grammar(
"expression", ':', '\n',
ContentMode.mixinContent, CharacterIncludeMode.none, false, true
),
);

'=' : new Grammar(
aa['='] = new Grammar(
"expressionValue", '=', ';',
ContentMode.appendContent, CharacterIncludeMode.none, false, true
),
);

'(' : new Grammar(
aa['('] = new Grammar(
"escapedValue", '(', ')',
ContentMode.appendContent, CharacterIncludeMode.none, false, false
),
);

'$' : new Grammar(
aa['$'] = new Grammar(
"expressionEscaped", '$', ';',
ContentMode.appendContent, CharacterIncludeMode.none, false, false,
'=' // Character that must follow the first character after @
),
);

'*' : new Grammar(
aa['*'] = new Grammar(
"comment", '*', '*',
ContentMode.discardContent, CharacterIncludeMode.none, false, true
)
];
);

return aa;
}
}

/**
Expand Down
116 changes: 115 additions & 1 deletion src/views/view.d
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ else {
version = Not_WebService;
}

private size_t _pageId;

version (Not_WebService) {
import std.string : format, strip;
import std.array : join, replace, split, array;
Expand Down Expand Up @@ -42,6 +44,8 @@ version (Not_WebService) {
/// The routes
string[] _result;

string _rootPath;

protected:
version (WebServer) {
/**
Expand Down Expand Up @@ -112,6 +116,10 @@ version (Not_WebService) {
* Note: Calling this property might be expensive, so caching the value is recommended.
*/
auto rootPath() {
if (_rootPath) {
return _rootPath;
}

// This makes sure that it's not retrieving the page's route, but the requests.
// It's useful in terms of a view redirecting to another view internally.
// Since the redirected view will have the route of the redirection and not the request.
Expand Down Expand Up @@ -152,7 +160,8 @@ version (Not_WebService) {
layoutResult = layoutResult.replace("@<head>", _placeHolders["head"]);
}

result = layoutResult.replace("@<view>", result);
_pageId++;
result = layoutResult.replace("@<view>", result.replace("@<pageId>", to!string(_pageId)));
}
}

Expand Down Expand Up @@ -246,6 +255,17 @@ version (Not_WebService) {
* Returns:
* The view.
*/
auto viewSpecialized(string name)(bool checkRoute = false) {
mixin("import diamondapp : getView, view_" ~ name ~ ";"); // To retrieve views ...

version (WebServer) {
mixin("return cast(view_" ~ name ~ ")getView(this.request, this.response, [name], checkRoute);");
}
else {
mixin("return cast(view_" ~ name ~ ")getView(name);");
}
}

auto view(string name, bool checkRoute = false) {
import diamondapp : getView; // To retrieve views ...

Expand Down Expand Up @@ -277,6 +297,100 @@ version (Not_WebService) {
void render(string name) {
append(retrieve(name));
}

/**
* Will render a layout view of anothr view into this one.
* Params:
* name = The name of the layout view.
* id = The id of the rendered content. This uses the @<id> placeholder.
* placeHolder = The name of the placeholder in the layout view.
* view = The name of the view.
*/
void render(string name, string id, string placeHolder, string view) {
auto layoutView = retrieve(name);
layoutView = layoutView.replace("@<id>", id);
auto contentView = retrieve(view);
layoutView = layoutView.replace("@<" ~ placeHolder ~ ">", contentView);

append(layoutView);
}

/**
* Retrieves the generated html of a view.
* This should generally only be used to render partial views into another view.
* Params:
* name = The name of the view to generate the html of.
* Returns:
* A string qeuivalent to the generated html.
*/
string retrieve(string name)() {
return viewSpecialized!name.generate();
}

/**
* Will render another view into this one.
* Params:
* name = The name of the view to render.
*/
void render(string name)() {
append(retrieve!name);
}

/**
* Will render a layout view of anothr view into this one.
* Params:
* name = The name of the layout view.
* id = The id of the rendered content. This uses the @<id> placeholder.
* placeHolder = The name of the placeholder in the layout view.
* view = The name of the view.
*/
void render(string name)(string id, string placeHolder, string view) {
auto layoutView = retrieve!name;
layoutView = layoutView.replace("@<id>", id);
auto contentView = retrieve(view);
layoutView = layoutView.replace("@<" ~ placeHolder ~ ">", contentView);

append(layoutView);
}

//
/**
* Retrieves the generated html of a view.
* This should generally only be used to render partial views into another view.
* Params:
* name = The name of the view to generate the html of.
* Returns:
* A string qeuivalent to the generated html.
*/
string retrieve(string name, TModel)(TModel model) {
return viewSpecialized!name.generate(model);
}

/**
* Will render another view into this one.
* Params:
* name = The name of the view to render.
*/
void render(string name, TModel)(TModel model) {
append(retrieve!(name, TModel)(model));
}

/**
* Will render a layout view of anothr view into this one.
* Params:
* name = The name of the layout view.
* id = The id of the rendered content. This uses the @<id> placeholder.
* placeHolder = The name of the placeholder in the layout view.
* view = The name of the view.
*/
void render(string view, TModel)(string name, string id, string placeHolder, TModel model) {
auto layoutView = retrieve(name);
layoutView = layoutView.replace("@<id>", id);
auto contentView = retrieve!(view,TModel)(model);
layoutView = layoutView.replace("@<" ~ placeHolder ~ ">", contentView);

append(layoutView);
}
}

/**
Expand Down
16 changes: 8 additions & 8 deletions src/views/viewgeneration.d
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ version (Not_WebService) {
/// Generates all the views into classes.
mixin template ViewGeneration() {
auto generateViews() {
auto routableViewsMixin = "private enum routableViews = [";
bool hasRoutes = false;
auto routableViewsMixin = "private static __gshared string[string] _routableViews; private @property routableViews() { if (_routableViews && _routableViews.length) return _routableViews; string[string] aa;\r\n";
// bool hasRoutes = false;

version (WebServer) {
enum pageClassFormat = q{
Expand Down Expand Up @@ -175,8 +175,8 @@ version (Not_WebService) {
version (WebServer) {
case "route": {
auto stripped = value.strip().replace("\n", "");
routableViewsMixin ~= format("\"%s\" : \"%s\",", stripped, pageName);
hasRoutes = true;
routableViewsMixin ~= format("aa[\"%s\"] = \"%s\";\r\n", stripped, pageName);
//hasRoutes = true;
break;
}
}
Expand Down Expand Up @@ -246,11 +246,11 @@ version (Not_WebService) {
);
}

if (hasRoutes) {
routableViewsMixin.length -= 1;
}
// if (hasRoutes) {
// routableViewsMixin.length -= 1;
// }

routableViewsMixin ~= "];";
routableViewsMixin ~= "_routableViews = aa; return _routableViews; }";
viewMixin ~= routableViewsMixin;

return viewMixin;
Expand Down
7 changes: 3 additions & 4 deletions src/views/viewimports.d
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,14 @@ version (Not_WebService) {
/// Generates the collection of views and imports their content
mixin template ViewImports() {
auto generateViewImports() {
auto viewFormat = "\"%s\" : import(\"%s\"),";
auto viewsResult = "private enum viewInitCollection = [";
auto viewFormat = "aa[\"%s\"] = import(\"%s\");";
auto viewsResult = "private @property auto viewInitCollection() { string[string] aa;";

foreach (pageName,pageContent; views) {
viewsResult ~= viewFormat.format(pageName,pageContent);
}

viewsResult.length -= 1;
viewsResult ~= "];";
viewsResult ~= "return aa; }";

return viewsResult;
}
Expand Down

0 comments on commit 83e8f61

Please sign in to comment.