mirror of
https://github.com/CrowCpp/Crow.git
synced 2024-06-07 21:10:44 +00:00
Merge branch 'master' into ws_close
This commit is contained in:
commit
f3c9306a95
@ -20,7 +20,6 @@ steps:
|
|||||||
- export COVERALLS_PULL_REQUEST=$DRONE_PULL_REQUEST
|
- export COVERALLS_PULL_REQUEST=$DRONE_PULL_REQUEST
|
||||||
- apt-get -y update
|
- apt-get -y update
|
||||||
- apt-get -y install libboost-all-dev doxygen mkdocs graphviz zlib1g-dev gcc clang make cmake python3 python3-pip git openssl libssl-dev
|
- apt-get -y install libboost-all-dev doxygen mkdocs graphviz zlib1g-dev gcc clang make cmake python3 python3-pip git openssl libssl-dev
|
||||||
- pip3 install mkdocs-material mkdocs-redirects pyyaml --no-input
|
|
||||||
- git clone https://github.com/CrowCpp/cpp-coveralls.git
|
- git clone https://github.com/CrowCpp/cpp-coveralls.git
|
||||||
- cd cpp-coveralls
|
- cd cpp-coveralls
|
||||||
- pip3 install . --no-input
|
- pip3 install . --no-input
|
||||||
@ -114,7 +113,7 @@ steps:
|
|||||||
- export TRAVIS_JOB_ID=$DRONE_BUILD_NUMBER
|
- export TRAVIS_JOB_ID=$DRONE_BUILD_NUMBER
|
||||||
- apt-get -y update
|
- apt-get -y update
|
||||||
- apt-get -y install libboost-all-dev doxygen mkdocs graphviz zlib1g-dev gcc clang make cmake python3 python3-pip git openssl libssl-dev
|
- apt-get -y install libboost-all-dev doxygen mkdocs graphviz zlib1g-dev gcc clang make cmake python3 python3-pip git openssl libssl-dev
|
||||||
- pip3 install mkdocs-material mkdocs-redirects pyyaml --no-input
|
- pip3 install mkdocs-material mkdocs-redirects pyyaml mkdocs-meta-descriptions-plugin --no-input
|
||||||
- git clone https://github.com/CrowCpp/cpp-coveralls.git
|
- git clone https://github.com/CrowCpp/cpp-coveralls.git
|
||||||
- cd cpp-coveralls
|
- cd cpp-coveralls
|
||||||
- pip3 install . --no-input
|
- pip3 install . --no-input
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
Here's how you can install Crow on your favorite GNU/Linux distro.
|
Here's how you can install Crow on your favorite GNU/Linux distro.
|
||||||
# Getting Crow
|
## Getting Crow
|
||||||
|
|
||||||
## Requirements
|
### Requirements
|
||||||
- C++ compiler with at least C++11 support.
|
- C++ compiler with at least C++11 support.
|
||||||
- boost library & development headers (1.64 or later).
|
- boost library & development headers (1.64 or later).
|
||||||
- **(optional)** ZLib for HTTP Compression.
|
- **(optional)** ZLib for HTTP Compression.
|
||||||
@ -14,7 +14,7 @@ Here's how you can install Crow on your favorite GNU/Linux distro.
|
|||||||
|
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
## Using a package Manager
|
### Using a package Manager
|
||||||
You can install Crow on GNU/Linux as a pre-made package
|
You can install Crow on GNU/Linux as a pre-made package
|
||||||
=== "Debian/Ubuntu"
|
=== "Debian/Ubuntu"
|
||||||
|
|
||||||
@ -26,12 +26,12 @@ You can install Crow on GNU/Linux as a pre-made package
|
|||||||
|
|
||||||
|
|
||||||
<br><br>
|
<br><br>
|
||||||
## Release package
|
### Release package
|
||||||
Crow provides an archive containing the framework and CMake files, just copy the `include` folder to `/usr/local/include` and `lib` folder to `/usr/local/lib`.<br><br>
|
Crow provides an archive containing the framework and CMake files, just copy the `include` folder to `/usr/local/include` and `lib` folder to `/usr/local/lib`.<br><br>
|
||||||
You can also download the `crow_all.h` file and simply include that into your project.
|
You can also download the `crow_all.h` file and simply include that into your project.
|
||||||
<br><br>
|
<br><br>
|
||||||
## Installing from source
|
### Installing from source
|
||||||
### Using CMake
|
#### Using CMake
|
||||||
1. Download Crow's source code (Either through github's UI or by using<br> `git clone https://github.com/CrowCpp/Crow.git`).
|
1. Download Crow's source code (Either through github's UI or by using<br> `git clone https://github.com/CrowCpp/Crow.git`).
|
||||||
2. Run `mkdir build` inside of crow's source directory.
|
2. Run `mkdir build` inside of crow's source directory.
|
||||||
3. Navigate to the new "build" directory and run the following:<br>
|
3. Navigate to the new "build" directory and run the following:<br>
|
||||||
@ -41,9 +41,9 @@ You can also download the `crow_all.h` file and simply include that into your pr
|
|||||||
|
|
||||||
You can ignore `-DCROW_BUILD_EXAMPLES=OFF -DCROW_BUILD_TESTS=OFF` if you want to build the Examples and Unit Tests.
|
You can ignore `-DCROW_BUILD_EXAMPLES=OFF -DCROW_BUILD_TESTS=OFF` if you want to build the Examples and Unit Tests.
|
||||||
<br>
|
<br>
|
||||||
### Manually
|
#### Manually
|
||||||
Crow can be installed manually on your Linux computer.
|
Crow can be installed manually on your Linux computer.
|
||||||
#### Multiple header files
|
##### Multiple header files
|
||||||
=== "Project Only"
|
=== "Project Only"
|
||||||
|
|
||||||
Copy Crow's `include` directory to your project's `include` directory.
|
Copy Crow's `include` directory to your project's `include` directory.
|
||||||
@ -52,7 +52,7 @@ Crow can be installed manually on your Linux computer.
|
|||||||
|
|
||||||
Copy Crow's `include` directory to the `/usr/local/include` directory.
|
Copy Crow's `include` directory to the `/usr/local/include` directory.
|
||||||
|
|
||||||
#### Single header (crow_all.h)
|
##### Single header (crow_all.h)
|
||||||
!!!warning
|
!!!warning
|
||||||
|
|
||||||
`crow_all.h` is recommended only for small, possibly single source file projects, and ideally should not be installed on your system.
|
`crow_all.h` is recommended only for small, possibly single source file projects, and ideally should not be installed on your system.
|
||||||
@ -60,15 +60,15 @@ navigate to the `scripts` directory and run `./merge_all.py ../include crow_all.
|
|||||||
!!!note
|
!!!note
|
||||||
|
|
||||||
You can also include or exclude middlewares from your `crow_all.h` by using `-i` or `-e` followed by the middleware header file names separated by a comma (e.g. `merge_all.py ../include crow_all.h -e cookie_parser` to exclude the cookie parser middleware).
|
You can also include or exclude middlewares from your `crow_all.h` by using `-i` or `-e` followed by the middleware header file names separated by a comma (e.g. `merge_all.py ../include crow_all.h -e cookie_parser` to exclude the cookie parser middleware).
|
||||||
# Compiling your project
|
## Compiling your project
|
||||||
## Using CMake
|
### Using CMake
|
||||||
In order to get your CMake project to work with Crow, all you need are the following lines in your CMakeLists.txt:
|
In order to get your CMake project to work with Crow, all you need are the following lines in your CMakeLists.txt:
|
||||||
```
|
```
|
||||||
find_package(Crow)
|
find_package(Crow)
|
||||||
target_link_libraries(your_project PUBLIC Crow::Crow)
|
target_link_libraries(your_project PUBLIC Crow::Crow)
|
||||||
```
|
```
|
||||||
From there CMake should handle compiling and linking your project.
|
From there CMake should handle compiling and linking your project.
|
||||||
## Directly using a compiler
|
### Directly using a compiler
|
||||||
All you need to do is run the following command:
|
All you need to do is run the following command:
|
||||||
```
|
```
|
||||||
g++ main.cpp -lpthread
|
g++ main.cpp -lpthread
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
Here's how you can install Crow on your Mac.
|
Here's how you can install Crow on your Mac.
|
||||||
# Getting Crow
|
## Getting Crow
|
||||||
## From a [release](https://github.com/CrowCpp/Crow/releases)
|
### From a [release](https://github.com/CrowCpp/Crow/releases)
|
||||||
### Archive
|
#### Archive
|
||||||
Crow provides an archive containing the framework and CMake files, You will only need the `include` folder inside that archive.
|
Crow provides an archive containing the framework and CMake files, You will only need the `include` folder inside that archive.
|
||||||
### Single header file
|
#### Single header file
|
||||||
You can also download the `crow_all.h` file which replaces the `include` folder.
|
You can also download the `crow_all.h` file which replaces the `include` folder.
|
||||||
|
|
||||||
## From Source
|
### From Source
|
||||||
To get Crow from source, you only need to download the repository (as a `.zip` or through `git clone https://github.com/CrowCpp/Crow.git`).
|
To get Crow from source, you only need to download the repository (as a `.zip` or through `git clone https://github.com/CrowCpp/Crow.git`).
|
||||||
### include folder
|
#### include folder
|
||||||
Once you've downloaded Crow's source code, you only need to take the `include` folder.
|
Once you've downloaded Crow's source code, you only need to take the `include` folder.
|
||||||
### Single header file
|
#### Single header file
|
||||||
You can generate your own single header file by using navigating to the `scripts` folder with your terminal and running the following command:
|
You can generate your own single header file by navigating to the `scripts` folder with your terminal and running the following command:
|
||||||
```
|
```
|
||||||
python3 merge_all.py ../include crow_all.h
|
python3 merge_all.py ../include crow_all.h
|
||||||
```
|
```
|
||||||
@ -21,8 +21,8 @@ This will generate a `crow_all.h` file which you can use in the following steps
|
|||||||
`crow_all.h` is recommended only for small, possibly single source file projects. For larger projects, it is advised to use the multi-header version.
|
`crow_all.h` is recommended only for small, possibly single source file projects. For larger projects, it is advised to use the multi-header version.
|
||||||
|
|
||||||
|
|
||||||
# Setting up your Crow project
|
## Setting up your Crow project
|
||||||
## Using XCode
|
### Using XCode
|
||||||
1. Download and install [Homebrew](https://brew.sh).
|
1. Download and install [Homebrew](https://brew.sh).
|
||||||
2. Run `brew install boost` in your terminal.
|
2. Run `brew install boost` in your terminal.
|
||||||
3. Create a new XCode project (macOS -> Command Line Tool).
|
3. Create a new XCode project (macOS -> Command Line Tool).
|
||||||
@ -35,7 +35,7 @@ This will generate a `crow_all.h` file which you can use in the following steps
|
|||||||
|
|
||||||
=== "Single Header"
|
=== "Single Header"
|
||||||
|
|
||||||
1. Place `crow_all.h` inside your project folder and add it to the project in XCode (you need to use the File -> )
|
1. Place `crow_all.h` inside your project folder and add it to the project in XCode (you need to use File -> Add files to "project_name")
|
||||||
2. Add header search paths for boost's folder (`/usr/local/include`, and `/usr/local/Cellar/boost/include`)
|
2. Add header search paths for boost's folder (`/usr/local/include`, and `/usr/local/Cellar/boost/include`)
|
||||||
3. Add linker flags (`-lpthread` and `-lboost_system` if you're running an old version of boost)
|
3. Add linker flags (`-lpthread` and `-lboost_system` if you're running an old version of boost)
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ This will generate a `crow_all.h` file which you can use in the following steps
|
|||||||
6. Press `▶` to compile and run your Crow application.
|
6. Press `▶` to compile and run your Crow application.
|
||||||
|
|
||||||
|
|
||||||
# Building Crow's tests/examples
|
## Building Crow's tests/examples
|
||||||
1. Download and install [Homebrew](https://brew.sh).
|
1. Download and install [Homebrew](https://brew.sh).
|
||||||
2. Run `brew install cmake boost` in your terminal.
|
2. Run `brew install cmake boost` in your terminal.
|
||||||
3. Get Crow's source code (the entire source code).
|
3. Get Crow's source code (the entire source code).
|
||||||
@ -54,4 +54,4 @@ This will generate a `crow_all.h` file which you can use in the following steps
|
|||||||
4. `make -j12`
|
4. `make -j12`
|
||||||
!!!note
|
!!!note
|
||||||
|
|
||||||
You can add options like `-DCROW_ENABLE_SSL`, `-DCROW_ENABLE_COMPRESSION`, or `-DCROW_AMALGAMATE` to `3.c` to build their tests/examples.
|
You can add options like `-DCROW_ENABLE_SSL`, `-DCROW_ENABLE_COMPRESSION`, or `-DCROW_AMALGAMATE` to `3.c` to build their tests/examples.
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
Here's how you can install Crow on your Windows machine.
|
Here's how you can install Crow on your Windows machine.
|
||||||
# Getting and Compiling Crow
|
## Getting and Compiling Crow
|
||||||
## Using A package manager
|
### Using A package manager
|
||||||
### VCPKG
|
#### VCPKG
|
||||||
Crow can be simply installed through VCPKG using the command `vcpkg install crow`
|
Crow can be simply installed through VCPKG using the command `vcpkg install crow`
|
||||||
|
|
||||||
## Manually (source or release)
|
### Manually (source or release)
|
||||||
### Microsoft Visual Studio 2019 and VCPKG
|
#### Microsoft Visual Studio 2019 and VCPKG
|
||||||
The following guide will use `example_with_all.cpp` as the Crow application for demonstration purposes. VCPKG will be used only to install Crow's dependencies.
|
The following guide will use `example_with_all.cpp` as the Crow application for demonstration purposes. VCPKG will be used only to install Crow's dependencies.
|
||||||
|
|
||||||
1. Generate `crow_all.h` by navigating to the `scripts` folder and running `python3 merge_all.py ..\include crow_all.h`.
|
1. Generate `crow_all.h` by navigating to the `scripts` folder and running `python3 merge_all.py ..\include crow_all.h`.
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
This page shows how you can get started with a simple hello world application.
|
This page shows how you can get started with a simple hello world application.
|
||||||
|
|
||||||
##1. Include
|
## 1. Include
|
||||||
Starting with an empty `main.cpp` file, first add `#!cpp #define CROW_MAIN` then `#!cpp #include "crow.h"` or `#!cpp #include "crow_all.h"` if you're using the single header file.
|
Starting with an empty `main.cpp` file, first add `#!cpp #define CROW_MAIN` then `#!cpp #include "crow.h"` or `#!cpp #include "crow_all.h"` if you're using the single header file.
|
||||||
|
|
||||||
!!! note
|
!!! note
|
||||||
|
|
||||||
If you're using multiple C++ source files make sure to have `CROW_MAIN` defined only in your main source file.
|
If you're using multiple C++ source files make sure to have `CROW_MAIN` defined only in your main source file.
|
||||||
|
|
||||||
##2. App declaration
|
## 2. App declaration
|
||||||
Next Create a `main()` and declare a `#!cpp crow::SimpleApp` inside, your code should look like this
|
Next Create a `main()` and declare a `#!cpp crow::SimpleApp` inside, your code should look like this
|
||||||
``` cpp
|
``` cpp
|
||||||
int main()
|
int main()
|
||||||
@ -18,7 +18,7 @@ int main()
|
|||||||
The App (or SimpleApp) class organizes all the different parts of Crow and provides the developer (you) a simple interface to interact with these parts.
|
The App (or SimpleApp) class organizes all the different parts of Crow and provides the developer (you) a simple interface to interact with these parts.
|
||||||
For more information, please go [here](../../guides/app).
|
For more information, please go [here](../../guides/app).
|
||||||
|
|
||||||
##3. Adding routes
|
## 3. Adding routes
|
||||||
Once you have your app, the next step is to add routes (or endpoints). You can do so with the `CROW_ROUTE` macro.
|
Once you have your app, the next step is to add routes (or endpoints). You can do so with the `CROW_ROUTE` macro.
|
||||||
``` cpp
|
``` cpp
|
||||||
CROW_ROUTE(app, "/")([](){
|
CROW_ROUTE(app, "/")([](){
|
||||||
@ -27,14 +27,14 @@ CROW_ROUTE(app, "/")([](){
|
|||||||
```
|
```
|
||||||
For more details on routes, please go [here](../../guides/routes).
|
For more details on routes, please go [here](../../guides/routes).
|
||||||
|
|
||||||
#4. Running the app
|
## 4. Running the app
|
||||||
Once you're happy with how you defined all your routes, you're going to want to instruct Crow to run your app. This is done using the `run()` method.
|
Once you're happy with how you defined all your routes, you're going to want to instruct Crow to run your app. This is done using the `run()` method.
|
||||||
``` cpp
|
``` cpp
|
||||||
app.port(18080).multithreaded().run();
|
app.port(18080).multithreaded().run();
|
||||||
```
|
```
|
||||||
Please note that the `port()` and `multithreaded()` methods aren't needed, Though not using `port()` will cause the default port (`80`) to be used.<br>
|
Please note that the `port()` and `multithreaded()` methods aren't needed, Though not using `port()` will cause the default port (`80`) to be used.<br>
|
||||||
|
|
||||||
##Putting it all together
|
## Putting it all together
|
||||||
|
|
||||||
Once you've followed all the steps above, your code should look similar to this
|
Once you've followed all the steps above, your code should look similar to this
|
||||||
|
|
||||||
|
@ -3,13 +3,13 @@ An app allows access to the http server (for handling connections), router (for
|
|||||||
|
|
||||||
Crow has 2 different app types:
|
Crow has 2 different app types:
|
||||||
|
|
||||||
##SimpleApp
|
## SimpleApp
|
||||||
Has no middlewares.
|
Has no middlewares.
|
||||||
|
|
||||||
##App<m1, m2, ...>
|
## App<m1, m2, ...>
|
||||||
Has middlewares.
|
Has middlewares.
|
||||||
|
|
||||||
##Using the app
|
## Using the app
|
||||||
To use a Crow app, simply define `#!cpp crow::SimpleApp` or `#!cpp crow::App<m1, m2 ...>` if you're using middlewares.<br>
|
To use a Crow app, simply define `#!cpp crow::SimpleApp` or `#!cpp crow::App<m1, m2 ...>` if you're using middlewares.<br>
|
||||||
The methods of an app can be chained. That means that you can configure and run your app in the same code line.
|
The methods of an app can be chained. That means that you can configure and run your app in the same code line.
|
||||||
``` cpp
|
``` cpp
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
Crow has built in support for JSON data.<br><br>
|
Crow has built in support for JSON data.<br><br>
|
||||||
|
|
||||||
##type
|
## type
|
||||||
The types of values that `rvalue and wvalue` can take are as follows:<br>
|
The types of values that `rvalue and wvalue` can take are as follows:<br>
|
||||||
|
|
||||||
- `False`: from type `bool`.
|
- `False`: from type `bool`.
|
||||||
@ -14,7 +14,7 @@ The types of values that `rvalue and wvalue` can take are as follows:<br>
|
|||||||
- `Object`: from type `crow::json::wvalue or crow::json::rvalue`.<br>
|
- `Object`: from type `crow::json::wvalue or crow::json::rvalue`.<br>
|
||||||
This last type means that `rvalue or wvalue` can have keys.
|
This last type means that `rvalue or wvalue` can have keys.
|
||||||
|
|
||||||
##rvalue
|
## rvalue
|
||||||
JSON read value, used for taking a JSON string and parsing it into `crow::json`.<br><br>
|
JSON read value, used for taking a JSON string and parsing it into `crow::json`.<br><br>
|
||||||
|
|
||||||
You can read individual items of the rvalue, but you cannot add items to it.<br>
|
You can read individual items of the rvalue, but you cannot add items to it.<br>
|
||||||
@ -22,7 +22,7 @@ To do that, you need to convert it to a `wvalue`, which can be done by simply wr
|
|||||||
|
|
||||||
For more info on read values go [here](/reference/classcrow_1_1json_1_1rvalue.html).<br><br>
|
For more info on read values go [here](/reference/classcrow_1_1json_1_1rvalue.html).<br><br>
|
||||||
|
|
||||||
#wvalue
|
## wvalue
|
||||||
JSON write value, used for creating, editing and converting JSON to a string.<br><br>
|
JSON write value, used for creating, editing and converting JSON to a string.<br><br>
|
||||||
|
|
||||||
!!!note
|
!!!note
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
Crow comes with a simple and easy to use logging system.<br><br>
|
Crow comes with a simple and easy to use logging system.<br><br>
|
||||||
|
|
||||||
##Setting up logging level
|
## Setting up logging level
|
||||||
You can set up the level at which crow displays logs by using the app's `loglevel(crow::LogLevel)` method.<br><br>
|
You can set up the level at which crow displays logs by using the app's `loglevel(crow::LogLevel)` method.<br><br>
|
||||||
|
|
||||||
The available log levels are as follows (please not that setting a level will also display all logs below this level):
|
The available log levels are as follows (please not that setting a level will also display all logs below this level):
|
||||||
@ -16,5 +16,5 @@ To set a logLevel, just use `#!cpp app.loglevel(crow::LogLevel::Warning)`, This
|
|||||||
|
|
||||||
Please note that setting the Macro `CROW_ENABLE_DEBUG` during compilation will also set the log level to `Debug`.
|
Please note that setting the Macro `CROW_ENABLE_DEBUG` during compilation will also set the log level to `Debug`.
|
||||||
|
|
||||||
##Writing a log
|
## Writing a log
|
||||||
Writing a log is as simple as `#!cpp CROW_LOG_<LOG LEVEL> << "Hello";` (replace<LOG LEVEL> with the actual level in all caps, so you have `CROW_LOG_WARNING`).
|
Writing a log is as simple as `#!cpp CROW_LOG_<LOG LEVEL> << "Hello";` (replace<LOG LEVEL> with the actual level in all caps, so you have `CROW_LOG_WARNING`).
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
Any middleware requires following 3 members:
|
Any middleware requires following 3 members:
|
||||||
##struct context
|
## struct context
|
||||||
Storing data for the middleware; can be read from another middleware or handlers
|
Storing data for the middleware; can be read from another middleware or handlers
|
||||||
|
|
||||||
|
|
||||||
##before_handle
|
## before_handle
|
||||||
Called before handling the request.<br>
|
Called before handling the request.<br>
|
||||||
If `res.end()` is called, the operation is halted. (`after_handle` will still be called)<br>
|
If `res.end()` is called, the operation is halted. (`after_handle` will still be called)<br>
|
||||||
2 signatures:<br>
|
2 signatures:<br>
|
||||||
@ -17,7 +17,7 @@ You can access other middlewares' context by calling `#!cpp all_ctx.template get
|
|||||||
`#!cpp ctx == all_ctx.template get<CurrentMiddleware>()`
|
`#!cpp ctx == all_ctx.template get<CurrentMiddleware>()`
|
||||||
|
|
||||||
|
|
||||||
##after_handle
|
## after_handle
|
||||||
Called after handling the request.<br>
|
Called after handling the request.<br>
|
||||||
|
|
||||||
`#!cpp void after_handle(request& req, response& res, context& ctx)`
|
`#!cpp void after_handle(request& req, response& res, context& ctx)`
|
||||||
@ -26,4 +26,4 @@ template <typename AllContext>
|
|||||||
void after_handle(request& req, response& res, context& ctx, AllContext& all_ctx)
|
void after_handle(request& req, response& res, context& ctx, AllContext& all_ctx)
|
||||||
```
|
```
|
||||||
<br><br>
|
<br><br>
|
||||||
This was pulled from `cookie_parser.h`. Further Editing required, possibly use parts of [@ipkn's wiki page](https://github.com/ipkn/crow/wiki/Middleware).
|
This was pulled from `cookie_parser.h`. Further Editing required, possibly use parts of [@ipkn's wiki page](https://github.com/ipkn/crow/wiki/Middleware).
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
**Introduced in: `v0.2`**<br><br>
|
**Introduced in: `v0.2`**<br><br>
|
||||||
Multipart is a way of forming HTTP requests or responses to contain multiple distinct parts.<br>
|
Multipart is a way of forming HTTP requests or responses to contain multiple distinct parts.<br>
|
||||||
|
|
||||||
Such an approach allows a request to contain multiple different pieces of data with potentially conflicting data types in a single response payload.<br>
|
Such an approach allows a request to contain multiple different pieces of data with potentially conflicting data types in a single response payload.<br>
|
||||||
It is typically used either in html forms, or when uploading multiple files.<br><br>
|
It is typically used either in html forms, or when uploading multiple files.<br><br>
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ We advise that you set crow up behind some form of reverse proxy if you plan on
|
|||||||
|
|
||||||
When using a proxy, make sure that you **do not** compile Crow with SSL enabled. SSL should be handled by the proxy.
|
When using a proxy, make sure that you **do not** compile Crow with SSL enabled. SSL should be handled by the proxy.
|
||||||
|
|
||||||
##Apache2
|
## Apache2
|
||||||
|
|
||||||
Assuming you have both Apache2 and the modules [proxy](https://httpd.apache.org/docs/2.4/mod/mod_proxy.html), [proxy_http](https://httpd.apache.org/docs/2.4/mod/mod_proxy_http.html), [proxy_html](https://httpd.apache.org/docs/2.4/mod/mod_proxy_html.html) (if you plan on serving html pages), and [proxy_wstunnel](https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html) (if you plan on using websockets). You will need to enable those modules, which you can do using the following commands:
|
Assuming you have both Apache2 and the modules [proxy](https://httpd.apache.org/docs/2.4/mod/mod_proxy.html), [proxy_http](https://httpd.apache.org/docs/2.4/mod/mod_proxy_http.html), [proxy_html](https://httpd.apache.org/docs/2.4/mod/mod_proxy_html.html) (if you plan on serving html pages), and [proxy_wstunnel](https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html) (if you plan on using websockets). You will need to enable those modules, which you can do using the following commands:
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ If you want crow to run in a subdirectory (such as `domain.abc/crow`) you can us
|
|||||||
|
|
||||||
If you're using an Arch Linux based OS. You will have to access `/etc/httpd/conf/httpd.conf` to enable modules and change configuration.
|
If you're using an Arch Linux based OS. You will have to access `/etc/httpd/conf/httpd.conf` to enable modules and change configuration.
|
||||||
|
|
||||||
##Nginx
|
## Nginx
|
||||||
|
|
||||||
Setting Nginx up is slightly simpler than Apache, all you need is the Nginx package itself. Once you've installed it, go to the configuration file (usually a `.conf` file located in `/etc/nginx`) and add the following lines to your server section (replace `localhost` and `40080` with the address and port you defined for your Crow App):
|
Setting Nginx up is slightly simpler than Apache, all you need is the Nginx package itself. Once you've installed it, go to the configuration file (usually a `.conf` file located in `/etc/nginx`) and add the following lines to your server section (replace `localhost` and `40080` with the address and port you defined for your Crow App):
|
||||||
|
|
||||||
|
@ -2,26 +2,26 @@ A query string is the part of the url that comes after a `?` character, it is us
|
|||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
Crow supports query strings through `crow::request::url_params`. The object is of type `crow::query_string` and can has the following functions:<br>
|
Crow supports query strings through `crow::request::url_params`. The object is of type `crow::query_string` and can has the following functions:<br>
|
||||||
##get(name)
|
## get(name)
|
||||||
Returns the value (as char*) based on the given key (or name). Returns `nullptr` if the key is not found.
|
Returns the value (as char*) based on the given key (or name). Returns `nullptr` if the key is not found.
|
||||||
##pop(name)
|
## pop(name)
|
||||||
**Introduced in: `v0.3`**<br><br>
|
**Introduced in: `v0.3`**<br><br>
|
||||||
Works the same as `get`, but removes the returned value.
|
Works the same as `get`, but removes the returned value.
|
||||||
!!! note
|
!!! note
|
||||||
|
|
||||||
`crow::request::url_params` is a const value, therefore for pop (also pop_list and pop_dict) to work, a copy needs to be made.
|
`crow::request::url_params` is a const value, therefore for pop (also pop_list and pop_dict) to work, a copy needs to be made.
|
||||||
|
|
||||||
##get_list(name)
|
## get_list(name)
|
||||||
A url can be `http://example.com?key[]=value1&key[]=value2&key[]=value3`. Using `get_list("key")` on such a url returns an `std::vector<std::string>` containing `[value1, value2, value3]`.<br><br>
|
A url can be `http://example.com?key[]=value1&key[]=value2&key[]=value3`. Using `get_list("key")` on such a url returns an `std::vector<std::string>` containing `[value1, value2, value3]`.<br><br>
|
||||||
|
|
||||||
`#!cpp get_list("key", false)` can be used to parse `http://example.com?key=value1&key=value2&key=value3`
|
`#!cpp get_list("key", false)` can be used to parse `http://example.com?key=value1&key=value2&key=value3`
|
||||||
##pop_list(name)
|
## pop_list(name)
|
||||||
**Introduced in: `v0.3`**<br><br>
|
**Introduced in: `v0.3`**<br><br>
|
||||||
Works the same as `get_list` but removes all instances of values having the given key (`use_brackets` is also available here).
|
Works the same as `get_list` but removes all instances of values having the given key (`use_brackets` is also available here).
|
||||||
##get_dict(name)
|
## get_dict(name)
|
||||||
Returns an `std::unordered_map<std::string, std::string>` from a query string such as `?key[sub_key1]=value1&key[sub_key2]=value2&key[sub_key3]=value3`.<br>
|
Returns an `std::unordered_map<std::string, std::string>` from a query string such as `?key[sub_key1]=value1&key[sub_key2]=value2&key[sub_key3]=value3`.<br>
|
||||||
The key in the map is what's in the brackets (`sub_key1` for example), and the value being what's after the `=` sign (`value1`). The name passed to the function is not part of the returned value.
|
The key in the map is what's in the brackets (`sub_key1` for example), and the value being what's after the `=` sign (`value1`). The name passed to the function is not part of the returned value.
|
||||||
##pop_dict(name)
|
## pop_dict(name)
|
||||||
**Introduced in: `v0.3`**<br><br>
|
**Introduced in: `v0.3`**<br><br>
|
||||||
Works the same as `get_dict` but removing the values from the query string.
|
Works the same as `get_dict` but removing the values from the query string.
|
||||||
!!!warning
|
!!!warning
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
Routes define what happens when your client connects to a certain URL.<br>
|
Routes define what happens when your client connects to a certain URL.<br>
|
||||||
|
|
||||||
##Macro
|
## Macro
|
||||||
`CROW_ROUTE(app, url)`<br>
|
`CROW_ROUTE(app, url)`<br>
|
||||||
Can be replaced with `#!cpp app.route<crow::black_magick::get_parameter_tag(url)>(url)` or `#!cpp app.route_dynamic(url)` if you're using VS2013 or want runtime url evaluation. Although this usage is **NOT** recommended.
|
Can be replaced with `#!cpp app.route<crow::black_magick::get_parameter_tag(url)>(url)` or `#!cpp app.route_dynamic(url)` if you're using VS2013 or want runtime url evaluation. Although this usage is **NOT** recommended.
|
||||||
##App
|
## App
|
||||||
Which app class to assign the route to.
|
Which app class to assign the route to.
|
||||||
##Path (URL)
|
## Path (URL)
|
||||||
Which relative path is assigned to the route.<br>
|
Which relative path is assigned to the route.<br>
|
||||||
Using `/hello` means the client will need to access `http://example.com/hello` in order to access the route.<br>
|
Using `/hello` means the client will need to access `http://example.com/hello` in order to access the route.<br>
|
||||||
A path can have parameters, for example `/hello/<int>` will allow a client to input an int into the url which will be in the handler (something like `http://example.com/hello/42`).<br>
|
A path can have parameters, for example `/hello/<int>` will allow a client to input an int into the url which will be in the handler (something like `http://example.com/hello/42`).<br>
|
||||||
@ -20,24 +20,24 @@ CROW_ROUTE(app, "/add/<int>/<int>")
|
|||||||
```
|
```
|
||||||
you can see the first `<int>` is defined as `a` and the second as `b`. If you were to run this and call `http://example.com/add/1/2`, the result would be a page with `3`. Exciting!
|
you can see the first `<int>` is defined as `a` and the second as `b`. If you were to run this and call `http://example.com/add/1/2`, the result would be a page with `3`. Exciting!
|
||||||
|
|
||||||
##Methods
|
## Methods
|
||||||
You can change the HTTP methods the route uses from just the default `GET` by using `method()`, your route macro should look like `CROW_ROUTE(app, "/add/<int>/<int>").methods(crow::HTTPMethod::GET, crow::HTTPMethod::PATCH)` or `CROW_ROUTE(app, "/add/<int>/<int>").methods("GET"_method, "PATCH"_method)`.
|
You can change the HTTP methods the route uses from just the default `GET` by using `method()`, your route macro should look like `CROW_ROUTE(app, "/add/<int>/<int>").methods(crow::HTTPMethod::GET, crow::HTTPMethod::PATCH)` or `CROW_ROUTE(app, "/add/<int>/<int>").methods("GET"_method, "PATCH"_method)`.
|
||||||
|
|
||||||
!!! note
|
!!! note
|
||||||
|
|
||||||
Crow handles `HEAD` and `OPTIONS` methods automatically. So adding those to your handler has no effect.
|
Crow handles `HEAD` and `OPTIONS` methods automatically. So adding those to your handler has no effect.
|
||||||
|
|
||||||
##Handler
|
## Handler
|
||||||
Basically a piece of code that gets executed whenever the client calls the associated route, usually in the form of a [lambda expression](https://en.cppreference.com/w/cpp/language/lambda). It can be as simple as `#!cpp ([](){return "Hello World"})`.<br><br>
|
Basically a piece of code that gets executed whenever the client calls the associated route, usually in the form of a [lambda expression](https://en.cppreference.com/w/cpp/language/lambda). It can be as simple as `#!cpp ([](){return "Hello World"})`.<br><br>
|
||||||
|
|
||||||
###Request
|
### Request
|
||||||
Handlers can also use information from the request by adding it as a parameter `#!cpp ([](const crow::request& req){...})`.<br><br>
|
Handlers can also use information from the request by adding it as a parameter `#!cpp ([](const crow::request& req){...})`.<br><br>
|
||||||
|
|
||||||
You can also access the url parameters in the handler using `#!cpp req.url_params.get("param_name");`. If the parameter doesn't exist, `nullptr` is returned.<br><br>
|
You can also access the url parameters in the handler using `#!cpp req.url_params.get("param_name");`. If the parameter doesn't exist, `nullptr` is returned.<br><br>
|
||||||
|
|
||||||
For more information on `crow::request` go [here](../../reference/structcrow_1_1request.html).<br><br>
|
For more information on `crow::request` go [here](../../reference/structcrow_1_1request.html).<br><br>
|
||||||
|
|
||||||
###Response
|
### Response
|
||||||
Crow also provides the ability to define a response in the parameters by using `#!cpp ([](crow::response& res){...})`.<br><br>
|
Crow also provides the ability to define a response in the parameters by using `#!cpp ([](crow::response& res){...})`.<br><br>
|
||||||
|
|
||||||
Please note that in order to return a response defined as a parameter you'll need to use `res.end();`.<br><br>
|
Please note that in order to return a response defined as a parameter you'll need to use `res.end();`.<br><br>
|
||||||
@ -46,12 +46,12 @@ Alternatively, you can define the response in the body and return it (`#!cpp ([]
|
|||||||
|
|
||||||
For more information on `crow::response` go [here](../../reference/structcrow_1_1response.html).<br><br>
|
For more information on `crow::response` go [here](../../reference/structcrow_1_1response.html).<br><br>
|
||||||
|
|
||||||
###Return statement
|
### Return statement
|
||||||
A `crow::response` is very strictly tied to a route. If you can have something in a response constructor, you can return it in a handler.<br><br>
|
A `crow::response` is very strictly tied to a route. If you can have something in a response constructor, you can return it in a handler.<br><br>
|
||||||
The main return type is `std::string`. although you could also return a `crow::json::wvalue` or `crow::multipart::message` directly.<br><br>
|
The main return type is `std::string`. although you could also return a `crow::json::wvalue` or `crow::multipart::message` directly.<br><br>
|
||||||
For more information on the specific constructors for a `crow::response` go [here](../../reference/structcrow_1_1response.html).
|
For more information on the specific constructors for a `crow::response` go [here](../../reference/structcrow_1_1response.html).
|
||||||
|
|
||||||
##Returning custom classes
|
## Returning custom classes
|
||||||
**Introduced in: `v0.3`**<br><br>
|
**Introduced in: `v0.3`**<br><br>
|
||||||
If you have your own class you want to return (without converting it to string and returning that), you can use the `crow::returnable` class.<br>
|
If you have your own class you want to return (without converting it to string and returning that), you can use the `crow::returnable` class.<br>
|
||||||
to use the returnable class, you only need your class to publicly extend `crow::returnable`, add a `dump()` method that returns your class as an `std::string`, and add a constructor that has a `Content-Type` header as a string argument.<br><br>
|
to use the returnable class, you only need your class to publicly extend `crow::returnable`, add a `dump()` method that returns your class as an `std::string`, and add a constructor that has a `Content-Type` header as a string argument.<br><br>
|
||||||
@ -79,7 +79,7 @@ class a : public crow::returnable
|
|||||||
|
|
||||||
instead of assigning a response code, you can use the `crow::status` enum, for example you can replace `crow::response(200)` with `crow::response(crow::status::OK)`
|
instead of assigning a response code, you can use the `crow::status` enum, for example you can replace `crow::response(200)` with `crow::response(crow::status::OK)`
|
||||||
|
|
||||||
##Catchall routes
|
## Catchall routes
|
||||||
**Introduced in: `v0.3`**<br><br>
|
**Introduced in: `v0.3`**<br><br>
|
||||||
By default, any request that Crow can't find a route for will return a simple 404 response. You can change that to return a default route using the `CROW_CATCHALL_ROUTE(app)` macro. Defining it is identical to a normal route, even when it comes to the `const crow::request&` and `crow::response&` parameters being optional.
|
By default, any request that Crow can't find a route for will return a simple 404 response. You can change that to return a default route using the `CROW_CATCHALL_ROUTE(app)` macro. Defining it is identical to a normal route, even when it comes to the `const crow::request&` and `crow::response&` parameters being optional.
|
||||||
!!!note
|
!!!note
|
||||||
|
@ -3,12 +3,12 @@ A static file is any file that resides in the server's storage.
|
|||||||
|
|
||||||
Crow supports returning Static files as responses in 2 ways.
|
Crow supports returning Static files as responses in 2 ways.
|
||||||
|
|
||||||
##Implicit
|
## Implicit
|
||||||
Crow implicitly returns any static files placed in a `static` directory and any subdirectories, as long as the user calls the endpoint `/static/path/to/file`.<br><br>
|
Crow implicitly returns any static files placed in a `static` directory and any subdirectories, as long as the user calls the endpoint `/static/path/to/file`.<br><br>
|
||||||
The static folder or endpoint can be changed by defining the macros `CROW_STATIC_DIRECTORY "alternative_directory/"` and `CROW_STATIC_ENDPOINT "/alternative_endpoint/<path>"`.<br>
|
The static folder or endpoint can be changed by defining the macros `CROW_STATIC_DIRECTORY "alternative_directory/"` and `CROW_STATIC_ENDPOINT "/alternative_endpoint/<path>"`.<br>
|
||||||
static directory changes the directory in the server's filesystem, while the endpoint changes the URL that the client needs to access.
|
static directory changes the directory in the server's filesystem, while the endpoint changes the URL that the client needs to access.
|
||||||
|
|
||||||
##Explicit
|
## Explicit
|
||||||
You can directly return a static file by using the `crow::response` method `#!cpp response.set_static_file_info("path/to/file");`. The path is relative to the executable unless preceded by `/`, then it is an absolute path.<br>
|
You can directly return a static file by using the `crow::response` method `#!cpp response.set_static_file_info("path/to/file");`. The path is relative to the executable unless preceded by `/`, then it is an absolute path.<br>
|
||||||
Please keep in mind that using the `set_static_file_info` method does invalidate any data already in your response body.<br><br>
|
Please keep in mind that using the `set_static_file_info` method does invalidate any data already in your response body.<br><br>
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
Using Systemd allows you to run any executable or script when the system starts. This can be useful when you don't want to re-run your Crow application every single time you restart your server.<br><br>
|
Using Systemd allows you to run any executable or script when the system starts. This can be useful when you don't want to re-run your Crow application every single time you restart your server.<br><br>
|
||||||
|
|
||||||
##Writing the Service Unit File
|
## Writing the Service Unit File
|
||||||
In order to have Systemd recognize your application, you need to create a `.service` file that explains how Systemd should handle your program.<br><br>
|
In order to have Systemd recognize your application, you need to create a `.service` file that explains how Systemd should handle your program.<br><br>
|
||||||
|
|
||||||
To create a service file, you need to go to `/etc/systemd/system` and create an empty text file with the extension `.service`, the file name can be anything.<br><br>
|
To create a service file, you need to go to `/etc/systemd/system` and create an empty text file with the extension `.service`, the file name can be anything.<br><br>
|
||||||
|
@ -2,22 +2,22 @@ Templating is when you return an html page with custom data. You can probably te
|
|||||||
|
|
||||||
Crow supports [mustache](http://mustache.github.io) for templates through its own implementation `crow::mustache`.<br><br>
|
Crow supports [mustache](http://mustache.github.io) for templates through its own implementation `crow::mustache`.<br><br>
|
||||||
|
|
||||||
##Components of mustache
|
## Components of mustache
|
||||||
|
|
||||||
There are 2 components of a mustache template implementation:
|
There are 2 components of a mustache template implementation:
|
||||||
|
|
||||||
- Page
|
- Page
|
||||||
- Context
|
- Context
|
||||||
|
|
||||||
###Page
|
### Page
|
||||||
The HTML page (including the mustache tags). It is usually loaded into `crow::mustache::template_t`. It needs to be placed in the *templates directory* which should be directly inside the current working directory of the crow executable.<br><br>
|
The HTML page (including the mustache tags). It is usually loaded into `crow::mustache::template_t`. It needs to be placed in the *templates directory* which should be directly inside the current working directory of the crow executable.<br><br>
|
||||||
|
|
||||||
For more information on how to formulate a template, see [this mustache manual](http://mustache.github.io/mustache.5.html).
|
For more information on how to formulate a template, see [this mustache manual](http://mustache.github.io/mustache.5.html).
|
||||||
|
|
||||||
###Context
|
### Context
|
||||||
A JSON object containing the tags as keys and their values. `crow::mustache::context` is actually a [crow::json::wvalue](../json#wvalue).
|
A JSON object containing the tags as keys and their values. `crow::mustache::context` is actually a [crow::json::wvalue](../json#wvalue).
|
||||||
|
|
||||||
##Returning a template
|
## Returning a template
|
||||||
To return a mustache template, you need to load a page using `#!cpp auto page = crow::mustache::load("path/to/template.html");`, keep in mind that the path is relative to the templates directory.<br>
|
To return a mustache template, you need to load a page using `#!cpp auto page = crow::mustache::load("path/to/template.html");`, keep in mind that the path is relative to the templates directory.<br>
|
||||||
You also need to set up the context by using `#!cpp crow::mustache::context ctx;`. Then you need to assign the keys and values, this can be done the same way you assign values to a json write value (`ctx["key"] = value;`).<br>
|
You also need to set up the context by using `#!cpp crow::mustache::context ctx;`. Then you need to assign the keys and values, this can be done the same way you assign values to a json write value (`ctx["key"] = value;`).<br>
|
||||||
With your context and page ready, just `#!cpp return page.render(ctx);`. This will use the context data to return a filled template.<br>
|
With your context and page ready, just `#!cpp return page.render(ctx);`. This will use the context data to return a filled template.<br>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
Unit tests can be written in 2 ways for a Crow application.<br><br>
|
Unit tests can be written in 2 ways for a Crow application.<br><br>
|
||||||
|
|
||||||
##The handler method
|
## The handler method
|
||||||
Crow Allows users to handle requests that may not come from the network. This is done by calling the `handle(req, res)` method and providing a request and response objects. Which causes crow to identify and run the appropriate handler, returning the resulting response.
|
Crow Allows users to handle requests that may not come from the network. This is done by calling the `handle(req, res)` method and providing a request and response objects. Which causes crow to identify and run the appropriate handler, returning the resulting response.
|
||||||
|
|
||||||
```cpp linenums="1"
|
```cpp linenums="1"
|
||||||
@ -29,7 +29,7 @@ Crow Allows users to handle requests that may not come from the network. This is
|
|||||||
This method does not send any data, nor does it run any post handle code, so things like static file serving (as far as sending the actual data) or compression cannot be tested using this method.
|
This method does not send any data, nor does it run any post handle code, so things like static file serving (as far as sending the actual data) or compression cannot be tested using this method.
|
||||||
|
|
||||||
|
|
||||||
##The client method
|
## The client method
|
||||||
This method involves creating a simple [ASIO](https://think-async.com/Asio/) client that sends the request and receives the response. It is considerably more complex than the earlier method, but it is both more realistic and includes post handle operations.
|
This method involves creating a simple [ASIO](https://think-async.com/Asio/) client that sends the request and receives the response. It is considerably more complex than the earlier method, but it is both more realistic and includes post handle operations.
|
||||||
|
|
||||||
```cpp linenums="1"
|
```cpp linenums="1"
|
||||||
|
@ -2,13 +2,13 @@ Websockets are a way of connecting a client and a server without the request res
|
|||||||
|
|
||||||
To create a websocket in Crow, you need a websocket route.<br>
|
To create a websocket in Crow, you need a websocket route.<br>
|
||||||
A websocket route differs from a normal route quite a bit. While it uses the same `CROW_ROUTE(app, "/url")` macro, that's about where the similarities end.<br>
|
A websocket route differs from a normal route quite a bit. While it uses the same `CROW_ROUTE(app, "/url")` macro, that's about where the similarities end.<br>
|
||||||
A websocket route follows the macro with `.websocket()` which is then followed by a series of methods (with handlers inside) for each event. These are:
|
A websocket route follows the macro with `.websocket()` which is then followed by a series of methods (with handlers inside) for each event. These are (sorted by order of execution):
|
||||||
|
|
||||||
- `#!cpp onopen([&](crow::websocket::connection& conn){handler code goes here})`
|
|
||||||
- `#!cpp onaccept([&](const crow::request&){handler code goes here})` (This handler has to return bool)
|
- `#!cpp onaccept([&](const crow::request&){handler code goes here})` (This handler has to return bool)
|
||||||
|
- `#!cpp onopen([&](crow::websocket::connection& conn){handler code goes here})`
|
||||||
- `#!cpp onmessage([&](crow::websocket::connection& conn, const std::string message, bool is_binary){handler code goes here})`
|
- `#!cpp onmessage([&](crow::websocket::connection& conn, const std::string message, bool is_binary){handler code goes here})`
|
||||||
- `#!cpp onclose([&](crow::websocket::connection& conn, const std::string reason){handler code goes here})`
|
- `#!cpp onerror([&](crow::websocket::connection& conn){handler code goes here})`
|
||||||
- `#!cpp onerror([&](crow::websocket::connection& conn){handler code goes here})`<br><br>
|
- `#!cpp onclose([&](crow::websocket::connection& conn, const std::string reason){handler code goes here})`<br><br>
|
||||||
|
|
||||||
These event methods and their handlers can be chained. The full Route should look similar to this:
|
These event methods and their handlers can be chained. The full Route should look similar to this:
|
||||||
```cpp
|
```cpp
|
||||||
|
@ -2,6 +2,17 @@
|
|||||||
|
|
||||||
<!-- Render hero under tabs -->
|
<!-- Render hero under tabs -->
|
||||||
|
|
||||||
|
{% block extrahead %}
|
||||||
|
<meta property="og:title" content="CrowCpp"/>
|
||||||
|
<meta property="og:type" content="website" />
|
||||||
|
<meta property="og:description" content="A Fast and Easy to use microframework for the web."/>
|
||||||
|
<meta name="description" content="Crow is a C++ microframework for running web services. It uses routing similar to Python's Flask which makes it easy to use. It is also extremely fast, beating multiple existing C++ frameworks as well as non C++ frameworks.">
|
||||||
|
<meta property="og:image" content="/assets/og_img.png" />
|
||||||
|
<meta property="og:url" content="https://crowcpp.org">
|
||||||
|
<meta property="twitter:card" content="summary_large_image">
|
||||||
|
<meta property="twitter:image" content="/assets/og_img.png">
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
<!-- Content -->
|
<!-- Content -->
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<style>
|
<style>
|
||||||
|
@ -74,6 +74,7 @@ plugins:
|
|||||||
- redirects:
|
- redirects:
|
||||||
redirect_maps:
|
redirect_maps:
|
||||||
'getting_started/setup/': 'getting_started/setup/linux.md'
|
'getting_started/setup/': 'getting_started/setup/linux.md'
|
||||||
|
- meta-descriptions
|
||||||
|
|
||||||
extra_css:
|
extra_css:
|
||||||
- 'stylesheets/colors.css'
|
- 'stylesheets/colors.css'
|
||||||
|
Loading…
Reference in New Issue
Block a user