fmt: remove space in front of ? and ! (#14366)
							parent
							
								
									0866c73f4b
								
							
						
					
					
						commit
						54bbc00493
					
				| 
						 | 
					@ -5,6 +5,7 @@ Hello,
 | 
				
			||||||
In this guide, we'll build a simple web blog in V.
 | 
					In this guide, we'll build a simple web blog in V.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The benefits of using V for web:
 | 
					The benefits of using V for web:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- A safe, fast, language with the development agility of Python or Ruby and
 | 
					- A safe, fast, language with the development agility of Python or Ruby and
 | 
				
			||||||
  the performance of C.
 | 
					  the performance of C.
 | 
				
			||||||
- Zero dependencies: everything you need for web development comes with the language
 | 
					- Zero dependencies: everything you need for web development comes with the language
 | 
				
			||||||
| 
						 | 
					@ -15,11 +16,10 @@ in a 1 MB package.
 | 
				
			||||||
  is enough.
 | 
					  is enough.
 | 
				
			||||||
- Fast development without any boilerplate.
 | 
					- Fast development without any boilerplate.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
*Please note that V and Vweb are at a very early stage and are changing rapidly.*
 | 
					_Please note that V and Vweb are at a very early stage and are changing rapidly._
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The code is available <a href='https://github.com/vlang/v/tree/master/tutorials/code/blog'>here</a>.
 | 
					The code is available <a href='https://github.com/vlang/v/tree/master/tutorials/code/blog'>here</a>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
### Installing V
 | 
					### Installing V
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
| 
						 | 
					@ -32,17 +32,15 @@ sudo ./v symlink
 | 
				
			||||||
Now V should be globally available on your system.
 | 
					Now V should be globally available on your system.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
> On macOS use `v_macos.zip`, on Windows - `v_windows.zip`.
 | 
					> On macOS use `v_macos.zip`, on Windows - `v_windows.zip`.
 | 
				
			||||||
If you use a BSD system, Solaris, Android, or simply want to install V
 | 
					> If you use a BSD system, Solaris, Android, or simply want to install V
 | 
				
			||||||
from source, follow the simple instructions here:
 | 
					> from source, follow the simple instructions here:
 | 
				
			||||||
https://github.com/vlang/v#installing-v-from-source
 | 
					> https://github.com/vlang/v#installing-v-from-source
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Install SQLite development dependency
 | 
					### Install SQLite development dependency
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If you don't have it already installed, look at the
 | 
					If you don't have it already installed, look at the
 | 
				
			||||||
[`sqlite` README](../../vlib/sqlite/README.md) for instructions.
 | 
					[`sqlite` README](../../vlib/sqlite/README.md) for instructions.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
### Creating a new Vweb project
 | 
					### Creating a new Vweb project
 | 
				
			||||||
 | 
					
 | 
				
			||||||
V projects can be created anywhere and don't need to have a certain structure:
 | 
					V projects can be created anywhere and don't need to have a certain structure:
 | 
				
			||||||
| 
						 | 
					@ -94,7 +92,6 @@ with an MVC web framework, you can think of it as a controller. (Vweb is
 | 
				
			||||||
not an MVC framework however.) It embeds the vweb Context object, that's why we get access
 | 
					not an MVC framework however.) It embeds the vweb Context object, that's why we get access
 | 
				
			||||||
to methods like `.text()`.
 | 
					to methods like `.text()`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
As you can see, there are no routing rules. The `index()` action handles the `/` request by default.
 | 
					As you can see, there are no routing rules. The `index()` action handles the `/` request by default.
 | 
				
			||||||
Vweb often uses convention over configuration and adding a new action requires
 | 
					Vweb often uses convention over configuration and adding a new action requires
 | 
				
			||||||
no routing rules either:
 | 
					no routing rules either:
 | 
				
			||||||
| 
						 | 
					@ -109,7 +106,6 @@ fn (mut app App) time() vweb.Result {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
<img width=662 src="https://github.com/vlang/v/blob/master/tutorials/building_a_simple_web_blog_with_vweb/img/time.png?raw=true">
 | 
					<img width=662 src="https://github.com/vlang/v/blob/master/tutorials/building_a_simple_web_blog_with_vweb/img/time.png?raw=true">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
> TIP: run the following command to live-reload the server: `v watch run blog.v`
 | 
					> TIP: run the following command to live-reload the server: `v watch run blog.v`
 | 
				
			||||||
| 
						 | 
					@ -117,7 +113,6 @@ fn (mut app App) time() vweb.Result {
 | 
				
			||||||
The `.text(string)` method returns a plain text document with the provided
 | 
					The `.text(string)` method returns a plain text document with the provided
 | 
				
			||||||
text, which isn't frequently used in websites.
 | 
					text, which isn't frequently used in websites.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
### HTML View
 | 
					### HTML View
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Let's return an HTML view instead. Create `index.html` in the same directory:
 | 
					Let's return an HTML view instead. Create `index.html` in the same directory:
 | 
				
			||||||
| 
						 | 
					@ -129,8 +124,8 @@ Let's return an HTML view instead. Create `index.html` in the same directory:
 | 
				
			||||||
  </head>
 | 
					  </head>
 | 
				
			||||||
  <body>
 | 
					  <body>
 | 
				
			||||||
    <b>@message</b>
 | 
					    <b>@message</b>
 | 
				
			||||||
	<br>
 | 
					    <br />
 | 
				
			||||||
	<img src='https://vlang.io/img/v-logo.png' width=100>
 | 
					    <img src="https://vlang.io/img/v-logo.png" width="100" />
 | 
				
			||||||
  </body>
 | 
					  </body>
 | 
				
			||||||
</html>
 | 
					</html>
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
| 
						 | 
					@ -176,7 +171,6 @@ into a single binary file together with the web application itself.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- All errors in the templates are guaranteed to be caught during compilation.
 | 
					- All errors in the templates are guaranteed to be caught during compilation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
### Fetching data with V ORM
 | 
					### Fetching data with V ORM
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Now let's display some articles!
 | 
					Now let's display some articles!
 | 
				
			||||||
| 
						 | 
					@ -184,7 +178,6 @@ Now let's display some articles!
 | 
				
			||||||
We'll be using V's builtin ORM and a SQLite database.
 | 
					We'll be using V's builtin ORM and a SQLite database.
 | 
				
			||||||
(V ORM will also support MySQL, Postgre, and SQL Server soon.)
 | 
					(V ORM will also support MySQL, Postgre, and SQL Server soon.)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
Add a SQLite handle to `App`:
 | 
					Add a SQLite handle to `App`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```v oksyntax
 | 
					```v oksyntax
 | 
				
			||||||
| 
						 | 
					@ -199,14 +192,11 @@ pub mut:
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
In `fn main()` we'll connect to a database.
 | 
					In `fn main()` we'll connect to a database.
 | 
				
			||||||
Code in the `main()` function is run only once during app's startup, so we are going
 | 
					Code in the `main()` function is run only once during app's startup, so we are going
 | 
				
			||||||
to have one DB connection for all requests. This improves the performance of the web application,
 | 
					to have one DB connection for all requests. This improves the performance of the web application,
 | 
				
			||||||
since a DB connection doesn't have to be set up for each request.
 | 
					since a DB connection doesn't have to be set up for each request.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
```v oksyntax
 | 
					```v oksyntax
 | 
				
			||||||
// blog.v
 | 
					// blog.v
 | 
				
			||||||
fn main() {
 | 
					fn main() {
 | 
				
			||||||
| 
						 | 
					@ -268,14 +258,13 @@ pub fn (app &App) index() vweb.Result {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
Finally, let's update our view:
 | 
					Finally, let's update our view:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```html
 | 
					```html
 | 
				
			||||||
<body>
 | 
					<body>
 | 
				
			||||||
  @for article in articles
 | 
					  @for article in articles
 | 
				
			||||||
  <div>
 | 
					  <div>
 | 
				
			||||||
			<b>@article.title</b> <br>
 | 
					    <b>@article.title</b> <br />
 | 
				
			||||||
    @article.text
 | 
					    @article.text
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
  @end
 | 
					  @end
 | 
				
			||||||
| 
						 | 
					@ -323,7 +312,6 @@ article := app.retrieve_article(10) or {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
### Adding new articles
 | 
					### Adding new articles
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Create `new.html`:
 | 
					Create `new.html`:
 | 
				
			||||||
| 
						 | 
					@ -334,10 +322,10 @@ Create `new.html`:
 | 
				
			||||||
    <title>V Blog</title>
 | 
					    <title>V Blog</title>
 | 
				
			||||||
  </head>
 | 
					  </head>
 | 
				
			||||||
  <body>
 | 
					  <body>
 | 
				
			||||||
	<form action='/new_article' method='post'>
 | 
					    <form action="/new_article" method="post">
 | 
				
			||||||
		<input type='text' placeholder='Title' name='title'> <br>
 | 
					      <input type="text" placeholder="Title" name="title" /> <br />
 | 
				
			||||||
		<textarea placeholder='Text' name='text'></textarea>
 | 
					      <textarea placeholder="Text" name="text"></textarea>
 | 
				
			||||||
		<input type='submit'>
 | 
					      <input type="submit" />
 | 
				
			||||||
    </form>
 | 
					    </form>
 | 
				
			||||||
  </body>
 | 
					  </body>
 | 
				
			||||||
</html>
 | 
					</html>
 | 
				
			||||||
| 
						 | 
					@ -373,7 +361,7 @@ not necessary).
 | 
				
			||||||
We need to update `index.html` to add a link to the "new article" page:
 | 
					We need to update `index.html` to add a link to the "new article" page:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```html
 | 
					```html
 | 
				
			||||||
<a href='/new'>New article</a>
 | 
					<a href="/new">New article</a>
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Next we need to add the HTML endpoint to our code like we did with `index.html`:
 | 
					Next we need to add the HTML endpoint to our code like we did with `index.html`:
 | 
				
			||||||
| 
						 | 
					@ -387,7 +375,6 @@ pub fn (mut app App) new() vweb.Result {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Re-running this code will now allow us to add new posts to our blog endpoint
 | 
					Re-running this code will now allow us to add new posts to our blog endpoint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
### JSON endpoints
 | 
					### JSON endpoints
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This tutorial used the traditional server-side rendering. If you prefer
 | 
					This tutorial used the traditional server-side rendering. If you prefer
 | 
				
			||||||
| 
						 | 
					@ -406,10 +393,10 @@ pub fn (mut app App) articles() vweb.Result {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
<img width=662 src="https://github.com/vlang/v/blob/master/tutorials/building_a_simple_web_blog_with_vweb/img/articles_json.png?raw=true">
 | 
					<img width=662 src="https://github.com/vlang/v/blob/master/tutorials/building_a_simple_web_blog_with_vweb/img/articles_json.png?raw=true">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Persistent data
 | 
					### Persistent data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
If one wants to persist data they need to use a file instead of memory SQLite Database.
 | 
					If one wants to persist data they need to use a file instead of memory SQLite Database.
 | 
				
			||||||
Replace the db setup code with this instead:
 | 
					Replace the db setup code with this instead:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -422,7 +409,6 @@ If the database file doesn't exist it will create it. The second command will
 | 
				
			||||||
create the table `Article` if none exists already. Now every time the
 | 
					create the table `Article` if none exists already. Now every time the
 | 
				
			||||||
app is run you will see the articles created from the previous executions
 | 
					app is run you will see the articles created from the previous executions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
To be continued...
 | 
					To be continued...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
For an example of a more sophisticated web app written in V, check out Vorum: https://github.com/vlang/vorum
 | 
					For an example of a more sophisticated web app written in V, check out Vorum: https://github.com/vlang/vorum
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,6 @@ from a terminal in an easy and structured manner.
 | 
				
			||||||
The module provides an easy way to prompt the user for
 | 
					The module provides an easy way to prompt the user for
 | 
				
			||||||
questions or even make a REPL or an embedded console.
 | 
					questions or even make a REPL or an embedded console.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
# Usage:
 | 
					# Usage:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```v
 | 
					```v
 | 
				
			||||||
| 
						 | 
					@ -18,6 +17,7 @@ println(answer)
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
or just:
 | 
					or just:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
```v
 | 
					```v
 | 
				
			||||||
import readline { read_line }
 | 
					import readline { read_line }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
vlib/v/checker/tests/go_wait_or.vv:11:17: error: unexpected `?`, the function `wait` does neither return an optional nor a result
 | 
					vlib/v/checker/tests/go_wait_or.vv:11:16: error: unexpected `?`, the function `wait` does neither return an optional nor a result
 | 
				
			||||||
    9 |         go d(1)
 | 
					    9 |         go d(1)
 | 
				
			||||||
   10 |     ]
 | 
					   10 |     ]
 | 
				
			||||||
   11 |     r := tg.wait()?
 | 
					   11 |     r := tg.wait()?
 | 
				
			||||||
| 
						 | 
					@ -19,7 +19,7 @@ vlib/v/checker/tests/go_wait_or.vv:19:13: error: unexpected `or` block, the func
 | 
				
			||||||
      |                ~~~~~~~~~~~~~~~~~~~~~~~
 | 
					      |                ~~~~~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
   20 |     tg2[0].wait()?
 | 
					   20 |     tg2[0].wait()?
 | 
				
			||||||
   21 |     tg3 := [
 | 
					   21 |     tg3 := [
 | 
				
			||||||
vlib/v/checker/tests/go_wait_or.vv:20:16: error: unexpected `?`, the function `wait` does neither return an optional nor a result
 | 
					vlib/v/checker/tests/go_wait_or.vv:20:15: error: unexpected `?`, the function `wait` does neither return an optional nor a result
 | 
				
			||||||
   18 |     ]
 | 
					   18 |     ]
 | 
				
			||||||
   19 |     tg2.wait() or { panic('problem') }
 | 
					   19 |     tg2.wait() or { panic('problem') }
 | 
				
			||||||
   20 |     tg2[0].wait()?
 | 
					   20 |     tg2[0].wait()?
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,11 +1,11 @@
 | 
				
			||||||
vlib/v/checker/tests/optional_propagate_nested.vv:10:19: error: to propagate the optional call, `xx_prop` must return an optional
 | 
					vlib/v/checker/tests/optional_propagate_nested.vv:10:18: error: to propagate the optional call, `xx_prop` must return an optional
 | 
				
			||||||
    8 | 
 | 
					    8 | 
 | 
				
			||||||
    9 | fn xx_prop() string {
 | 
					    9 | fn xx_prop() string {
 | 
				
			||||||
   10 |     s := ret(raise()?)
 | 
					   10 |     s := ret(raise()?)
 | 
				
			||||||
      |                     ^
 | 
					      |                     ^
 | 
				
			||||||
   11 |     return s
 | 
					   11 |     return s
 | 
				
			||||||
   12 | }
 | 
					   12 | }
 | 
				
			||||||
vlib/v/checker/tests/optional_propagate_nested.vv:28:22: error: to propagate the optional call, `aa_propagate` must return an optional
 | 
					vlib/v/checker/tests/optional_propagate_nested.vv:28:21: error: to propagate the optional call, `aa_propagate` must return an optional
 | 
				
			||||||
   26 | 
 | 
					   26 | 
 | 
				
			||||||
   27 | fn (mut s St) aa_propagate() {
 | 
					   27 | fn (mut s St) aa_propagate() {
 | 
				
			||||||
   28 |     f := retf(s.raise()?)
 | 
					   28 |     f := retf(s.raise()?)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
vlib/v/checker/tests/propagate_option_with_result_err.vv:6:8: error: to propagate an option, the call must also return an optional type
 | 
					vlib/v/checker/tests/propagate_option_with_result_err.vv:6:7: error: to propagate an option, the call must also return an optional type
 | 
				
			||||||
    4 | 
 | 
					    4 | 
 | 
				
			||||||
    5 | fn bar() ?string {
 | 
					    5 | fn bar() ?string {
 | 
				
			||||||
    6 |     foo()?
 | 
					    6 |     foo()?
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
vlib/v/parser/tests/defer_propagate.vv:9:15: error: error propagation not allowed inside `defer` blocks
 | 
					vlib/v/parser/tests/defer_propagate.vv:9:14: error: error propagation not allowed inside `defer` blocks
 | 
				
			||||||
    7 |     mut a := 0
 | 
					    7 |     mut a := 0
 | 
				
			||||||
    8 |     defer {
 | 
					    8 |     defer {
 | 
				
			||||||
    9 |         a = test1()?
 | 
					    9 |         a = test1()?
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
vlib/v/parser/tests/defer_propagate2.vv:16:13: error: error propagation not allowed inside `defer` blocks
 | 
					vlib/v/parser/tests/defer_propagate2.vv:16:12: error: error propagation not allowed inside `defer` blocks
 | 
				
			||||||
   14 |     dump(s.x)
 | 
					   14 |     dump(s.x)
 | 
				
			||||||
   15 |     defer {
 | 
					   15 |     defer {
 | 
				
			||||||
   16 |         s.close()?
 | 
					   16 |         s.close()?
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue