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

http://github.com/darrengarvey/cgi · C++ · 145 lines · 73 code · 27 blank · 45 comment · 8 complexity · 6832218adf30b360be09624d0bb2a657 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
  11. //
  12. #include <iostream>
  13. #include <boost/cgi/fcgi.hpp>
  14. #include <boost/cgi/utility/stencil.hpp>
  15. using namespace boost::fcgi;
  16. int handle_request(request& req)
  17. {
  18. req.load(parse_all);
  19. // Construct a response that uses Google cTemplate. Also sets the root
  20. // directory where the stencils are found.
  21. stencil resp("stencils/");
  22. //// Test 1.
  23. // This is a minimal response. The content_type(...) may go before or after
  24. // the response text.
  25. // The content of the response - which is everything streamed to it - is
  26. // added to a {{content}} field in the stencil.
  27. resp<< content_type("text/html")
  28. << "Hello there, universe!";
  29. //// Test 2.
  30. // Set some fields.
  31. resp.set("script_name", req.script_name()); // Populates {{script_name}}.
  32. resp.set("some_string", req.get["string"]); // Populates {{some_string}}.
  33. // set() supports any type that Boost.Lexical_cast does.
  34. resp.set("short_bits", 8 * sizeof(short)); // Populates {{short_bits}}.
  35. if (req.get.count("short"))
  36. {
  37. // Almost any type is supported by pick<>
  38. // (ie. any type supported by Boost.Lexical_cast.).
  39. // This is equivalent to request::as<>, but returns the second parameter
  40. // iff there is no item in the map and / or the value could not be
  41. // cast to the specified type. In this case, we shall explicitly cast
  42. // to a `short`. In general, however, the default type that the value is
  43. // cast to is inferred from the type of the second parameter.
  44. short some_short = req.get.pick<short>("short", -1);
  45. resp.set("some_short", some_short);
  46. }
  47. //// Test 3.
  48. // Show a section, conditionally.
  49. // Use the "show" GET variable, or default to the string "show" if not set.
  50. request::string_type show = req.get.pick("show", "show");
  51. resp.set("show", show == "show" ? "hide" : "show");
  52. if (show == "show")
  53. resp.show("some_section"); // Shows {{#some_section}}...{{/some_section}}.
  54. //// Test 4.
  55. int num = req.get.pick("count", 0);
  56. if (num < 0) num = 0;
  57. resp.set("show_less", num ? num - 1 : 0);
  58. resp.set("show_more", num + 1);
  59. stencil::section sec("section_with_variable");
  60. for (int i(0); i < num; ++i)
  61. {
  62. // We can show a section and set one field in it in one go.
  63. resp.set("some_section_variable", i + 1, sec);
  64. }
  65. //// Test 5.
  66. resp.add(stencil::section("embedded")).set("test", "passed");
  67. stencil::dictionary dict = resp.add("embedded");
  68. dict.add("subsection") // returns a new sub-dictionary.
  69. .set("test", "passed again")
  70. .set("other", "(another field)");
  71. dict.set("test", "passed yet again", stencil::section("subsection"));
  72. //// Test 6.
  73. // Include another stencil into this one at marker {{>include}}.
  74. resp.include(
  75. stencil::section(
  76. "include",
  77. "stencil.include.html"
  78. )
  79. );
  80. // Short-cut for stencil includes.
  81. resp.include("include", "stencil.include.html");
  82. resp<< cookie("name", "value");
  83. /// End Tests.
  84. // Expand the response using the specified template.
  85. // cTemplate has a cache internally, which we can choose to
  86. // ignore.
  87. resp.expand("stencil.html", stencil::lazy_reload);
  88. // Send the response and close the request.
  89. return commit(req, resp);
  90. }
  91. int main()
  92. {
  93. try {
  94. service s;
  95. acceptor a(s);
  96. // Handle requests (one at a time) until the counter overflows.
  97. for(unsigned count(1);count;++count)
  98. {
  99. if (a.accept(&handle_request))
  100. std::cerr<< "Error returned from handling request #" << count << std::endl;
  101. else
  102. std::cerr<< "Successfully handled request #" << count << std::endl;
  103. }
  104. return 0;
  105. } catch(std::exception& e) {
  106. using namespace std;
  107. cerr<< "Error: " << e.what() << endl;
  108. } catch(...) {
  109. using namespace std;
  110. cerr<< "Unexpected exception." << endl;
  111. }
  112. // Control only reaches here if an exception has been caught.
  113. using namespace std;
  114. cerr<< "Press enter to close console window..." << endl;
  115. cin.get();
  116. return 1;
  117. }
  118. //]