PageRenderTime 54ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/libs/cgi/example/cgi/stencil/main.cpp

http://github.com/darrengarvey/cgi
C++ | 185 lines | 113 code | 31 blank | 41 comment | 7 complexity | bd3104cc72afdb3e5fc6b5d4571552cd MD5 | raw file
  1. // -- main.hpp --
  2. //
  3. // Copyright (c) Darren Garvey 2007-2009.
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //
  8. ////////////////////////////////////////////////////////////////
  9. //
  10. //[cgi_stencil_headers
  11. #include <iostream>
  12. #include <boost/cgi/cgi.hpp>
  13. #include <boost/cgi/utility/stencil.hpp>
  14. //]
  15. //[cgi_stencil_main
  16. namespace cgi = boost::cgi;
  17. int handle_request(cgi::request& req)
  18. {
  19. req.load(cgi::parse_all);
  20. // Construct a response that uses Google cTemplate. Also sets the root
  21. // directory where the stencils are found.
  22. cgi::stencil resp("../stencils/");
  23. //// Test 1.
  24. // This is a minimal response. The content_type(...) may go before or after
  25. // the response text.
  26. // The content of the response - which is everything streamed to it - is
  27. // added to a {{content}} field in the stencil.
  28. resp<< cgi::content_type("text/html")
  29. << "Hello there, universe!";
  30. //// Test 2.
  31. // Set some fields.
  32. resp.set("script_name", req.script_name()); // Populates {{script_name}}.
  33. resp.set("some_string", req.get["string"]); // Populates {{some_string}}.
  34. // set() supports any type that Boost.Lexical_cast does.
  35. resp.set("short_bits", 8 * sizeof(short)); // Populates {{short_bits}}.
  36. if (req.get.count("short"))
  37. {
  38. // Almost any type is supported by pick<>
  39. // (ie. any type supported by Boost.Lexical_cast.).
  40. short some_short = req.get.pick<short>("short", -1);
  41. resp.set("some_short", some_short);
  42. }
  43. //// Test 3.
  44. // Show a section, conditionally.
  45. // Use the "show" GET variable, or default to the string "show" if not set.
  46. cgi::request::string_type show = req.get.pick("show", "show");
  47. resp.set("show", show == "show" ? "hide" : "show");
  48. if (show == "show")
  49. resp.show("some_section"); // Shows {{#some_section}}...{{/some_section}}.
  50. //// Test 4.
  51. int num = req.get.pick("count", 0);
  52. if (num < 0) num = 0;
  53. resp.set("show_less", num ? num - 1 : 0);
  54. resp.set("show_more", num + 1);
  55. cgi::section sec("section_with_variable");
  56. for (int i(0); i < num; ++i)
  57. {
  58. // We can show a section and set one field in it in one go.
  59. resp.set("some_section_variable", i + 1, sec);
  60. }
  61. //// Test 5.
  62. cgi::dictionary test5 = resp.add("test5");
  63. test5.add("input")
  64. .set("type", "text")
  65. .set("name", "text")
  66. .set("value", req.form["text"])
  67. .show("label", "Text");
  68. test5.add("input")
  69. .set("type", "checkbox")
  70. .set("name", "check")
  71. .set("value", "one")
  72. .show("label", "One")
  73. .show(req.post.matches("check", "one") ? "checked" : "");
  74. test5.add("input")
  75. .set("type", "checkbox")
  76. .set("name", "check")
  77. .set("value", "two")
  78. .show("label", "Two")
  79. .show(req.post.matches("check", "two") ? "checked" : "");
  80. test5.add("input")
  81. .set("type", "checkbox")
  82. .set("name", "check")
  83. .set("value", "six")
  84. .show("label", "Six")
  85. .show(req.post.matches("check", "six") ? "checked" : "");
  86. test5.add("input")
  87. .set("type", "checkbox")
  88. .set("name", "check")
  89. .set("value", "ten")
  90. .show("label", "Ten")
  91. .show(req.post.matches("check", "ten") ? "checked" : "");
  92. test5.add("input")
  93. .set("type", "radio")
  94. .set("name", "radio")
  95. .set("value", "yes")
  96. .show("label", "Yes")
  97. .show(req.post.matches("radio", "yes") ? "checked" : "");
  98. test5.add("input")
  99. .set("type", "radio")
  100. .set("name", "radio")
  101. .set("value", "no")
  102. .show("label", "No")
  103. .show(req.post.matches("radio", "no") ? "checked " : "");
  104. test5.add("input")
  105. .set("type", "submit")
  106. .set("value", "Submit");
  107. //// Test 6.
  108. resp.add(cgi::section("embedded")).set("test", "passed");
  109. cgi::dictionary dict = resp.add("embedded");
  110. dict.add("subsection") // returns a new sub-dictionary.
  111. .set("test", "passed again")
  112. .set("other", "(another field)");
  113. dict.set("test", "passed yet again", cgi::section("subsection"));
  114. //// Test 7.
  115. // Include another stencil into this one at marker {{>include}}.
  116. resp.include(
  117. cgi::section(
  118. "include",
  119. "stencil.include.html"
  120. )
  121. );
  122. // Short-cut for stencil includes.
  123. resp.include("include", "stencil.include.html");
  124. // Set a session cookie, which expires when the user closes their browser.
  125. resp<< cgi::cookie("name", "value");
  126. /// End Tests.
  127. // Expand the response using the specified template.
  128. // cTemplate has a cache internally, which we can choose to
  129. // ignore.
  130. resp.expand("stencil.html");
  131. // Send the response and close the request.
  132. return cgi::commit(req, resp);
  133. }
  134. int main()
  135. {
  136. try {
  137. cgi::request req;
  138. if (handle_request(req))
  139. std::cerr<< "Error returned from handling request." << std::endl;
  140. else
  141. std::cerr<< "Successfully handled request." << std::endl;
  142. return 0;
  143. } catch(std::exception& e) {
  144. using namespace std;
  145. cout<< "Content-type: text/plain\r\n\r\n"
  146. << "Error: " << e.what() << endl;
  147. } catch(...) {
  148. using namespace std;
  149. cout<< "Content-type: text/plain\r\n\r\n"
  150. << "Unexpected exception." << endl;
  151. }
  152. return 1;
  153. }
  154. //]