Skip to content

Commit

Permalink
Add new API request /api/v1/source/CHAPTER/SECTION which returns the …
Browse files Browse the repository at this point in the history
…source code for that section.

The tour controller now fetches the source through this API call. That way the
source code is always correctly escaped and we just set the initial source
in the controller init function. This eliminates the ugly source code setting
within the DIET template. And it later on enabled restoring user's changed
source editor content.
  • Loading branch information
stonemaster committed Jan 29, 2016
1 parent 05129b8 commit f49a8c6
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 8 deletions.
1 change: 1 addition & 0 deletions public/content/en/welcome.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ features.

import std.stdio;

// Let's get going!
void main() {
writeln("Hello World!");
}
Expand Down
7 changes: 7 additions & 0 deletions public/static/js/tour-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ dlangTourApp.controller('DlangTourAppCtrl', [ '$scope', '$http', function($scope
theme: "elegant"
};

$scope.init = function(chapterId, section) {
$http.get('/api/v1/source/' + chapterId + "/" + section)
.success(function(data) {
$scope.sourceCode = $scope.resetCode = data.sourceCode;
});
}

$scope.programOutput = "";

$scope.run = function() {
Expand Down
2 changes: 1 addition & 1 deletion source/app.d
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ shared static this()
fsettings.serverPathPrefix = "/static";
urlRouter
.registerWebInterface(new WebInterface(contentProvider))
.registerRestInterface(new ApiV1(execProvider))
.registerRestInterface(new ApiV1(execProvider, contentProvider))
.get("/static/*", serveStaticFiles(config.publicDir ~ "/static/", fsettings));

listenHTTP(settings, urlRouter);
Expand Down
17 changes: 16 additions & 1 deletion source/rest/apiv1.d
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
module rest.apiv1;

import vibe.d;
import rest.iapiv1;
import exec.iexecprovider;
import contentprovider;

class ApiV1: IApiV1
{
private IExecProvider execProvider_;
private ContentProvider contentProvider_;

this(IExecProvider execProvider)
this(IExecProvider execProvider, ContentProvider contentProvider)
{
this.execProvider_ = execProvider;
this.contentProvider_ = contentProvider;
}

RunOutput run(string source)
Expand All @@ -21,4 +25,15 @@ class ApiV1: IApiV1
auto result = execProvider_.compileAndExecute(source);
return RunOutput(result.output, result.success);
}

SourceOutput getSource(string _chapter, int _section)
{
auto tourData = contentProvider_.getContent("en", _chapter, _section);
if (tourData.content == null) {
throw new HTTPStatusException(404,
"Couldn't find tour data for chapter '%s', section %d".format(_chapter, _section));
}

return SourceOutput(tourData.content.sourceCode);
}
}
32 changes: 31 additions & 1 deletion source/rest/iapiv1.d
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,43 @@ import vibe.d;
+/
interface IApiV1
{
/+
POST /api/v1/run
{
source: "..."
}
Returns: output of compiled D program with success
flag.
{
output: "Program Output",
success: true/false
}
+/
struct RunOutput
{
string output;
bool success;
}

@method(HTTPMethod.POST)
@path("/api/v1/run")
RunOutput run(string source);

/+
GET /api/v1/source/CHAPTER/SECTION
Returns: source code (or empty if none) for the given
chapter and section. Also returns changed source code
if user switched between sections.
{
sourceCode: "..."
}
+/
struct SourceOutput
{
string sourceCode;
}
@method(HTTPMethod.GET)
@path("/api/v1/source/:chapter/:section")
SourceOutput getSource(string _chapter, int _section);
}
6 changes: 3 additions & 3 deletions source/webinterface.d
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,15 @@ class WebInterface
}

auto htmlContent = tourData.content.html;
auto sourceCode = tourData.content.sourceCode;
auto chapterId = _chapter;
auto hasSourceCode = !tourData.content.sourceCode.empty;
auto section = _section;
auto sectionCount = tourData.sectionCount;
auto toc = &toc_;
auto previousLink = previousSectionLink(_chapter, _section);
auto nextLink = nextSectionLink(_chapter, _section);
render!("tour.dt", htmlContent, sourceCode, section,
sectionCount, chapterId,
render!("tour.dt", htmlContent, section,
sectionCount, chapterId, hasSourceCode,
nextLink, previousLink,
toc)();
}
Expand Down
4 changes: 2 additions & 2 deletions views/tour.dt
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ block head
link(rel="stylesheet", href="/static/css/tour.css")

block content
#content(ng-controller="DlangTourAppCtrl as ctrl", ng-init="sourceCode = resetCode = '#{sourceCode}'")
#content(ng-controller="DlangTourAppCtrl as ctrl", ng-init="init('#{chapterId}', #{section})")
.row
.col-md-6
- if (!sourceCode.empty)
- if (hasSourceCode)
#code-box
ui-codemirror(ui-codemirror-opts="editorOptions", ng-model="sourceCode")
.text-right#command-box
Expand Down

0 comments on commit f49a8c6

Please sign in to comment.