Merge pull request #5 from an-tao/add_drogon_template

1. Add DrTemplate class to make views. 
2. Add support for view nesting.
This commit is contained in:
an-tao 2018-10-17 13:51:18 +08:00 committed by GitHub
commit 3ccb1490a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 171 additions and 59 deletions

View File

@ -1,5 +1,19 @@
/**
*
* create_project.cc
* An Tao
* @section LICENSE
*
* Copyright 2018, An Tao. All rights reserved.
* Use of this source code is governed by a MIT license
* that can be found in the License file.
*
* @section DESCRIPTION
*
*/
#include "create_project.h"
#include <drogon/HttpResponse.h>
#include <drogon/DrTemplateBase.h>
#include <iostream>
#include <sys/stat.h>
#include <sys/types.h>
@ -22,29 +36,29 @@ static void newCmakeFile(std::ofstream &cmakeFile, const std::string &projectNam
{
HttpViewData data;
data.insert("ProjectName",projectName);
auto resp=HttpResponse::newHttpViewResponse("cmake.csp",data);
cmakeFile << resp->getBody();
auto templ=DrTemplateBase::newTemplate("cmake.csp");
cmakeFile << templ->genText(data);
}
static void newMainFile(std::ofstream &mainFile)
{
auto resp=HttpResponse::newHttpViewResponse("demoMain");
mainFile << resp->getBody();
auto templ=DrTemplateBase::newTemplate("demoMain");
mainFile << templ->genText();
}
static void newGitIgFile(std::ofstream &gitFile)
{
auto resp=HttpResponse::newHttpViewResponse("gitignore.csp");
gitFile << resp->getBody();
auto templ=DrTemplateBase::newTemplate("gitignore.csp");
gitFile << templ->genText();
}
static void newJsonFindFile(std::ofstream &jsonFile)
{
auto resp=HttpResponse::newHttpViewResponse("FindJsoncpp.csp");
jsonFile << resp->getBody();
auto templ=DrTemplateBase::newTemplate("FindJsoncpp.csp");
jsonFile << templ->genText();
}
static void newConfigFile(std::ofstream &configFile)
{
auto resp=HttpResponse::newHttpViewResponse("config",drogon::HttpViewData());
configFile << resp->getBody();
auto templ=DrTemplateBase::newTemplate("config");
configFile << templ->genText();
}
void create_project::createProject(const std::string &projectName)
{

View File

@ -1,7 +1,7 @@
/**
*
* @file
* @author An Tao
* create_project.h
* An Tao
* @section LICENSE
*
* Copyright 2018, An Tao. All rights reserved.

View File

@ -1,7 +1,7 @@
/**
*
* @file
* @author An Tao
* create_view.cc
* An Tao
* @section LICENSE
*
* Copyright 2018, An Tao. All rights reserved.
@ -25,6 +25,8 @@ static const std::string cxx_view_data = "@@";
static const std::string cxx_output = "$$";
static const std::string cxx_val_start = "{{";
static const std::string cxx_val_end = "}}";
static const std::string sub_view_start = "<%view";
static const std::string sub_view_end = "%>";
using namespace drogon_ctl;
@ -69,6 +71,17 @@ static void outputVal(std::ofstream &oSrcFile, const std::string &streamName, co
oSrcFile << " }\n";
oSrcFile << "}\n";
}
static void outputSubView(std::ofstream &oSrcFile, const std::string &streamName, const std::string &viewDataName, const std::string &keyName)
{
oSrcFile << "{\n";
oSrcFile << " auto templ=DrTemplateBase::newTemplate(\""<<keyName<<"\");\n";
oSrcFile << " if(templ){\n";
oSrcFile << " "<<streamName<<"<< templ->genText("<<viewDataName<<");\n";
oSrcFile << " }\n";
oSrcFile << "}\n";
}
static void parseLine(std::ofstream &oSrcFile, std::string &line, const std::string &streamName, const std::string &viewDataName, int &cxx_flag, int returnFlag = 1)
{
std::string::size_type pos(0);
@ -118,6 +131,31 @@ static void parseLine(std::ofstream &oSrcFile, std::string &line, const std::str
exit(1);
}
}
else if ((pos = line.find(sub_view_start)) != std::string::npos)
{
std::string oldLine = line.substr(0, pos);
parseLine(oSrcFile, oldLine, streamName, viewDataName, cxx_flag, 0);
std::string newLine = line.substr(pos + sub_view_start.length());
if ((pos = newLine.find(sub_view_end)) != std::string::npos)
{
std::string keyName = newLine.substr(0, pos);
auto iter = keyName.begin();
while (iter != keyName.end() && *iter == ' ')
iter++;
auto iterEnd = iter;
while (iterEnd != keyName.end() && *iterEnd != ' ')
iterEnd++;
keyName = std::string(iter, iterEnd);
outputSubView(oSrcFile, streamName, viewDataName, keyName);
std::string tailLine = newLine.substr(pos + sub_view_end.length());
parseLine(oSrcFile, tailLine, streamName, viewDataName, cxx_flag, returnFlag);
}
else
{
std::cerr << "format err!" << std::endl;
exit(1);
}
}
else
{
if (line.length() > 0)
@ -216,11 +254,12 @@ int create_view::createViewFile(const std::string &script_filename)
void create_view::newViewHeaderFile(std::ofstream &file, const std::string &className)
{
file << "//this file is generated by program automatically,don't modify it!\n";
file << "#include <drogon/HttpView.h>\n";
file << "#include <drogon/DrTemplate.h>\n";
file << "using namespace drogon;\n";
file << "class " << className << ":public HttpView<" << className << ">\n";
file << "{\npublic:\n\t" << className << "(){};\n\tvirtual ~" << className << "(){};\nprotected:\n\t"
"virtual HttpResponsePtr genHttpResponse(const HttpViewData&) override;\n};";
file << "class " << className << ":public DrTemplate<" << className << ">\n";
file << "{\npublic:\n\t" << className << "(){};\n\tvirtual ~"
<< className << "(){};\n\t"
"virtual std::string genText(const DrTemplateData &) override;\n};";
}
void create_view::newViewSourceFile(std::ofstream &file, const std::string &className, std::ifstream &infile)
@ -304,7 +343,8 @@ void create_view::newViewSourceFile(std::ofstream &file, const std::string &clas
//std::cout<<"file pos:"<<infile.tellg()<<std::endl;
std::string viewDataName = className + "_view_data";
file << "HttpResponsePtr " << className << "::genHttpResponse(const HttpViewData& " << viewDataName << ")\n{\n";
//virtual std::string genText(const DrTemplateData &)
file << "std::string " << className << "::genText(const DrTemplateData& " << viewDataName << ")\n{\n";
//std::string bodyName=className+"_bodystr";
std::string streamName = className + "_tmp_stream";
@ -317,12 +357,5 @@ void create_view::newViewSourceFile(std::ofstream &file, const std::string &clas
parseLine(file, buffer, streamName, viewDataName, cxx_flag);
}
file << "\tauto res = HttpResponse::newHttpResponse();\n";
file << "\tres->setStatusCode(HttpResponse::k200OK);\n";
file << "#ifdef CONTENT_TYPE\n";
file << "\tres->setContentTypeCode(CONTENT_TYPE);\n";
file << "#else\n";
file << "\tres->setContentTypeCode(CT_TEXT_HTML);\n";
file << "#endif\n";
file << "\tres->setBody(" << streamName << ".str());\n\treturn res;\n}\n";
file << "return " << streamName << ".str();\n}\n";
}

View File

@ -8,6 +8,7 @@
<title>{{ title }}</title>
</head>
<body>
<%view header %>
<%c++ if(para.size()>0){%>
<H1>Parameters</H1>
<table border="1">

View File

@ -0,0 +1 @@
<img src="https://github.com/an-tao/drogon/wiki/images/drogon-white.jpg"/>

View File

@ -1,7 +1,7 @@
/**
*
* @file
* @author An Tao
* DrTemplate.h
* An Tao
* @section LICENSE
*
* Copyright 2018, An Tao. All rights reserved.
@ -15,15 +15,13 @@
#pragma once
#include <drogon/DrObject.h>
#include <drogon/HttpResponse.h>
#include <drogon/HttpRequest.h>
#include <drogon/HttpViewBase.h>
#include <drogon/DrTemplateBase.h>
namespace drogon
{
template <typename T>
class HttpView : public DrObject<T>, public HttpViewBase
class DrTemplate : public DrObject<T>, public DrTemplateBase
{
protected:
HttpView() {}
DrTemplate() {}
};
} // namespace drogon

33
lib/inc/drogon/DrTemplateBase.h Executable file
View File

@ -0,0 +1,33 @@
/**
*
* DrTemplateBase.h
* An Tao
* @section LICENSE
*
* Copyright 2018, An Tao. All rights reserved.
* Use of this source code is governed by a MIT license
* that can be found in the License file.
*
* @section DESCRIPTION
*
*/
#pragma once
#include <drogon/DrObject.h>
#include <drogon/HttpViewData.h>
#include <string>
#include <memory>
namespace drogon
{
typedef HttpViewData DrTemplateData;
class DrTemplateBase : virtual public DrObjectBase
{
public:
static std::shared_ptr<DrTemplateBase> newTemplate(std::string templateName);
virtual std::string genText(const DrTemplateData &data = DrTemplateData()) = 0;
virtual ~DrTemplateBase(){};
DrTemplateBase(){};
};
} // namespace drogon

View File

@ -1,12 +1,10 @@
//this file is generated by program automatically,don't modify it!
#include <drogon/HttpView.h>
#include <drogon/DrTemplate.h>
using namespace drogon;
class NotFound : public HttpView<NotFound>
class NotFound : public DrTemplate<NotFound>
{
public:
NotFound(){};
virtual ~NotFound(){};
protected:
HttpResponsePtr genHttpResponse(const HttpViewData &) override;
virtual std::string genText(const HttpViewData &) override;
};

38
lib/src/DrTemplateBase.cc Executable file
View File

@ -0,0 +1,38 @@
/**
*
* DrTemplateBase.cc
* An Tao
* @section LICENSE
*
* Copyright 2018, An Tao. All rights reserved.
* Use of this source code is governed by a MIT license
* that can be found in the License file.
*
* @section DESCRIPTION
*
*/
#include <drogon/DrTemplateBase.h>
#include <drogon/DrClassMap.h>
#include <trantor/utils/Logger.h>
#include <memory>
using namespace drogon;
std::shared_ptr<DrTemplateBase> DrTemplateBase::newTemplate(std::string templateName)
{
LOG_TRACE << "http view name=" << templateName;
auto pos = templateName.find(".csp");
if (pos != std::string::npos)
{
if (pos == templateName.length() - 4)
{
templateName = templateName.substr(0, pos);
}
}
auto obj = std::shared_ptr<DrObjectBase>(drogon::DrClassMap::newObject(templateName));
if (obj)
{
return std::dynamic_pointer_cast<DrTemplateBase>(obj);
}
return nullptr;
}

View File

@ -1,7 +1,7 @@
/**
*
* @file
* @author An Tao
* HttpViewBase.h
* An Tao
* @section LICENSE
*
* Copyright 2018, An Tao. All rights reserved.
@ -13,6 +13,8 @@
*/
#include <drogon/HttpViewBase.h>
#include <drogon/DrClassMap.h>
#include <drogon/DrTemplateBase.h>
#include <trantor/utils/Logger.h>
#include <memory>
using namespace drogon;
@ -27,14 +29,16 @@ HttpResponsePtr HttpViewBase::genHttpResponse(std::string viewName, const HttpVi
viewName = viewName.substr(0, pos);
}
}
auto obj = std::shared_ptr<DrObjectBase>(drogon::DrClassMap::newObject(viewName));
if (obj)
auto templ = DrTemplateBase::newTemplate(viewName);
if (templ)
{
auto view = std::dynamic_pointer_cast<HttpViewBase>(obj);
if (view)
{
return view->genHttpResponse(data);
}
auto res = HttpResponse::newHttpResponse();
res->setStatusCode(HttpResponse::k200OK);
res->setContentTypeCode(CT_TEXT_HTML);
res->setBody(templ->genText(data));
return res;
}
return drogon::HttpResponse::newNotFoundResponse();
}

View File

@ -6,7 +6,7 @@
#include <vector>
#include <set>
using namespace std;
HttpResponsePtr NotFound::genHttpResponse(const HttpViewData &NotFound_view_data)
std::string NotFound::genText(const HttpViewData &NotFound_view_data)
{
std::stringstream NotFound_tmp_stream;
NotFound_tmp_stream << "<html>\n";
@ -24,13 +24,5 @@ HttpResponsePtr NotFound::genHttpResponse(const HttpViewData &NotFound_view_data
NotFound_tmp_stream << "<!-- a padding to disable MSIE and Chrome friendly error page -->\n";
NotFound_tmp_stream << "<!-- a padding to disable MSIE and Chrome friendly error page -->\n";
NotFound_tmp_stream << "<!-- a padding to disable MSIE and Chrome friendly error page -->\n";
auto res = HttpResponse::newHttpResponse();
res->setStatusCode(HttpResponse::k200OK);
#ifdef CONTENT_TYPE
res->setContentTypeCode(CONTENT_TYPE);
#else
res->setContentTypeCode(CT_TEXT_HTML);
#endif
res->setBody(NotFound_tmp_stream.str().c_str());
return res;
return NotFound_tmp_stream.str();
}