Skip to content

Commit

Permalink
v0.16.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Adrian Salceanu committed Aug 29, 2019
1 parent 4b653b8 commit d7fc35b
Show file tree
Hide file tree
Showing 46 changed files with 9,039 additions and 918 deletions.
27 changes: 25 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,37 @@
# Changelog

## v0.16.0 - 2019-08-29

* switched to native Julia logging (automatic logging to file for now is disabled, will come back in a future version)
* the `log` function has been removed (**breaking**)
* added support for embedded Julia within HTML arguments
* cleaned up HTML rendering
* refactored cache adapters loading to be less hacky and more performant
* refactored session adapters loading to be less hacky and more performant
* consolidated the `Helpers` API into the `Requests` and `Sessions` modules and removed `Helpers` module (**breaking**)
* added new `Exceptions` module defining the `ExceptionalResponse` type
* added extra `@params` pointing to the currently matched route and webchannel
* fixed broken `Cookies` and `Session` functionality
* `Renderer.redirect` now supports extra arguments which are passed to `Router.linkto` for reverse routing
* new `Renderer.response` method specialized for `ExceptionalResponse`
* consolidated `flash` functionality in dedicated module `Flash` (**breaking**)
* added support for URI segments matching in routes
* refactored the `Route` and `Channel` types
* `ExceptionalResponses` now break the execution flow if thrown from controller hooks
* added `up()` as shortcut for `Genie.startup()` to start the web servers
* internal API consolidation
* added new generic `error-xxx.html` page template
* updated bundled JS and CSS files to newer versions

## v0.15.0 - 2019-08-22

* fixed error in `Genie.newapp()` with `dbsupport = true`
* internal API cleanup and optimisations
* fixed issue with `newresource` SearchLight integration
* SearchLight initializer code is now uncommented
* dependencies update
* `Router.tolink` and its alias `Router.linkto` throw exceptions if the route is not defined **breaking**
* `Router.tolink!!` and its alias `Router.linkto!!` have been removed **breaking**
* `Router.tolink` and its alias `Router.linkto` throw exceptions if the route is not defined (**breaking**)
* `Router.tolink!!` and its alias `Router.linkto!!` have been removed (**breaking**)
* new method `Requests.read(HttpFile, Type{String})` which returns the content of an uploaded file as a string.

## v0.14.0 - 2019-08-21
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2016-2019 [Genie.jl Contributors](https://github.com/GenieFramework/Genie.jl/graphs/contributors)
Copyright (c) 2016-2019 [Adrian Salceanu](https://www.linkedin.com/in/adriansalceanu/) and [Genie.jl Contributors](https://github.com/GenieFramework/Genie.jl/graphs/contributors)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
25 changes: 9 additions & 16 deletions Manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ uuid = "b99e7846-7c00-51b0-8f62-c81ae34c0232"
version = "0.5.6"

[[CodeTracking]]
deps = ["InteractiveUtils", "Test", "UUIDs"]
git-tree-sha1 = "9b21a2dfe51ba71fdc5688039075819196595367"
deps = ["InteractiveUtils", "UUIDs"]
git-tree-sha1 = "0becdab7e6fbbcb7b88d8de5b72e5bb2f28239f3"
uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2"
version = "0.5.7"
version = "0.5.8"

[[Codecs]]
deps = ["Test"]
Expand Down Expand Up @@ -115,9 +115,9 @@ uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"

[[LoweredCodeUtils]]
deps = ["JuliaInterpreter"]
git-tree-sha1 = "45af0ce564939cbc9b88374f91e3339c0430fdff"
git-tree-sha1 = "ea065f38cccb556b4eabe43b3b3b91e1c67cbffd"
uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b"
version = "0.3.7"
version = "0.3.8"

[[Markdown]]
deps = ["Base64"]
Expand All @@ -130,16 +130,9 @@ uuid = "739be429-bea8-5141-9913-cc70e7f3736d"
version = "0.7.0"

[[Millboard]]
deps = ["Compat"]
git-tree-sha1 = "21622ffb05343e51bc5b95c3576a71b26183809d"
git-tree-sha1 = "c6d4a61d1b74ba35b1efe5cb025bf852145521e1"
uuid = "39ec1447-df44-5f4c-beaa-866f30b4d3b2"
version = "0.2.0"

[[MiniLogging]]
deps = ["Test"]
git-tree-sha1 = "4f2f5ca0663afa0172db23bbdd99e683dd17fb0e"
uuid = "f59402ec-0262-5707-a561-770af94bc5a6"
version = "0.2.0"
version = "0.2.1"

[[Mmap]]
uuid = "a63ad114-7e13-5084-954f-fe012c677804"
Expand Down Expand Up @@ -192,9 +185,9 @@ version = "0.2.0"

[[Revise]]
deps = ["CodeTracking", "Distributed", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "Pkg", "REPL", "UUIDs", "Unicode"]
git-tree-sha1 = "f0d18f8b5199150dd9ced1cc6f9200b167fbb4d9"
git-tree-sha1 = "34e80fba701ce58064b3b5f4b32027ad3dc136ba"
uuid = "295af30f-e4ad-537b-8983-00126c2a3abe"
version = "2.1.7"
version = "2.1.8"

[[SHA]]
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
Expand Down
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "Genie"
uuid = "c43c736e-a2d1-11e8-161f-af95117fbd1e"
authors = ["Adrian Salceanu <[email protected]>"]
version = "0.15.0"
version = "0.16.0"

[deps]
ArgParse = "c7e460c6-2fb9-53a9-8c5b-16f535851c63"
Expand All @@ -11,10 +11,10 @@ Gumbo = "708ec375-b3d6-5a57-a7ce-8257bf98657a"
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
HttpCommon = "77172c1b-203f-54ac-aa54-3f1198fe9f90"
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a"
MbedTLS = "739be429-bea8-5141-9913-cc70e7f3736d"
Millboard = "39ec1447-df44-5f4c-beaa-866f30b4d3b2"
MiniLogging = "f59402ec-0262-5707-a561-770af94bc5a6"
Nettle = "49dea1ee-f6fa-5aa6-9a11-8816cee7d4b9"
Nullables = "4d1e1d77-625e-5b40-9113-a560ec7a8ecd"
OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
Expand Down
62 changes: 32 additions & 30 deletions docs/documentation/10--Loading_Genie_Apps.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,17 @@

At any time, you can load and serve an existing Genie app. Loading a Genie app will bring into scope all your app's files, including the main app module, controllers, models, etcetera.

## Manual loading in Julia's REPL

First, make sure that you're in the root dir of a Genie app. This is the project's folder and you can tell by the fact that there should be a `bootstrap.jl` file, plus Julia's `Project.toml` and `Manifest.toml` files, amongst others.

Next, once you start a new Julia REPL session, we have to activate the local package environment:

```julia
julia> ] # enter pkg> mode

pkg> activate .
```

Then, back to the julian prompt, run

```julia
julia> using Genie

julia> Genie.loadapp()
```

The app's environment will now be loaded.

In order to start the web server execute

```julia
julia> startup()
```

## Starting a Genie REPL session MacOS / Linux

The recommended approach is to skip the manual loading and start an interactive REPL in Genie's environment by executing `bin/repl` in the os shell, again while in the project's root folder.
The recommended approach is to start an interactive REPL in Genie's environment by executing `bin/repl` in the os shell, while in the project's root folder.

```shell
$ bin/repl
```

The app's environment will be loaded.

In order to start the web server execute:
In order to start the web server, you can next execute:

```julia
julia> startup()
Expand All @@ -52,6 +24,8 @@ If you want to directly start the server, use `bin/server` instead of `bin/repl`
$ bin/server
```

This will automatically start the web server and drop you off at the Julia REPL.

---
**HEADS UP**

Expand Down Expand Up @@ -98,3 +72,31 @@ using Genie

Genie.loadapp()
```

## Manual loading in Julia's REPL

In order to load a Genie app within an open Julia REPL session, first make sure that you're in the root dir of a Genie app. This is the project's folder and you can tell by the fact that there should be a `bootstrap.jl` file, plus Julia's `Project.toml` and `Manifest.toml` files, amongst others. You can `julia> cd(...)` or `shell> cd ...` your way into the folder of the Genie app.

Next, from within the active Julia REPL session, we have to activate the local package environment:

```julia
julia> ] # enter pkg> mode

pkg> activate .
```

Then, back to the julian prompt, run the following to load the Genie app:

```julia
julia> using Genie

julia> Genie.loadapp()
```

The app's environment will now be loaded.

In order to start the web server execute

```julia
julia> startup()
```
38 changes: 36 additions & 2 deletions docs/documentation/12--Advanced_Routing_Techniques.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Unlike Julia's multiple dispatch, Genie's router won't match by the most specifi

---

## Dynamic routing (using request/router parameters)
## Dynamic routing (using route parameters)

Static routing works great for fixed URLs. But what if we have dynamic URLs, where the components map to information in the backend (like database IDs) and vary with each request? For example, how would we handle a URL like "/customers/57943/orders/458230", where 57943 is the customer id and 458230 is the order id.

Expand Down Expand Up @@ -119,7 +119,7 @@ OrderedCollections.OrderedDict{Symbol,Genie.Router.Route} with 1 entry:
---
**HEADS UP**

For consistency, Genie names all the routes. However, the autogenerated name is state dependent. So, if you change the route, it's possible that the name will change as well. Thus, it's best to explicitly name the routes if you plan on referencing them throughout the app.
For consistency, Genie names all the routes. However, the auto-generated name is state dependent. So, if you change the route, it's possible that the name will change as well. Thus, it's best to explicitly name the routes if you plan on referencing them throughout the app.

---

Expand Down Expand Up @@ -194,6 +194,7 @@ The routes are represented internally by the `Route` type which has 3 fields:
* `method::String` - for storing the method of the route (`GET`, `POST`, etc)
* `path::String` - represents the URI pattern to be matched against
* `action::Function` - the route handler to be executed when the route is matched
* `name::Union{Symbol,Nothing}` - the name of the route

## Removing routes

Expand Down Expand Up @@ -260,6 +261,39 @@ Base.convert(::Type{Int}, v::SubString{String}) = parse(Int, v)

Once we register the converter in `Base`, our request will be correctly handled, resulting in `Order ID has type Int64 // Customer ID has type Int64`

## Matching individual URI segments

Besides matching the full route, Genie also allows matching individual URI segments. That is, enforcing that the various route parameters obey a certain pattern. In order to introduce constraints for route parameters we append `#pattern` at the end of the route parameter.

### Example

For instance, let's assume that we want to implement a localized website where we have a URL structure like: `mywebsite.com/en`, `mywebsite.com/es` and `mywebsite.com/de`. We can define a dynamic route and extract the locale variable to serve localized content:

```julia
route(":locale", TranslationsController.index)
```

This will work very well, matching requests and passing the locale into our code within the `payload(:locale)` variable. However, it will also be too greedy, virtually matching all the requests, including things like static files (ie `mywebsite.com/favicon.ico`). We can constrain what the `:locale` variable can match, by appending the pattern:

```julia
route(":locale#(en|es|de)", TranslationsController.index)
```

The refactored route only allows `:locale` to match one of `en`, `es`, and `de` strings.

---
**HEADS UP**

Keep in mind not to duplicate application logic. For instance, if you have an array of supported locales, you can use that to dynamically generate the pattern -- routes can be fully dynamically generated!

```julia
const LOCALE = ":locale#($(join(TranslationsController.AVAILABLE_LOCALES, '|')))"

route("/$LOCALE", TranslationsController.index, named = :get_index)
```

---

## The `@params` collection

It's good to know that the router bundles all the parameters of the current request into the `@params` collection (a `Dict{Symbol,Any}`). This contains valuable information, such as route parameters, query params, POST payload, the original HTTP.Request and HTTP.Response objects, etcetera. In general it's recommended not to access the `@params` collection directly but through the utility methods defined by `Genie.Requests` and `Genie.Responses` -- but knowing about `@params` might come in handy.
2 changes: 1 addition & 1 deletion docs/guides/Working_With_Genie_Apps.md
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ Next, we add `SearchLight`:
Genie is designed to seamlessly integrate with SearchLight and provides access to various database oriented generators. First we need to tell Genie/SearchLight how to connect to the database. Let's use them to set up our database support. Run this in the Genie/Julia REPL:

```julia
julia> Genie.Generator.dbsupport()
julia> Genie.Generator.db_support()
```

The command will add a `db/` folder within the root of the app. What we're looking for is the `db/connection.yml` file. Let's edit it. Make the file to look like this:
Expand Down
17 changes: 8 additions & 9 deletions docs/guides/Working_With_Genie_Apps_Intermediary_Topics.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,6 @@ mutable struct Book <: AbstractModel
### INTERNALS
_table_name::String
_id::String
_serializable::Vector{Symbol}

### FIELDS
id::DbId
Expand All @@ -180,9 +179,7 @@ mutable struct Book <: AbstractModel
title = "",
author = "",
cover = "",
) = new("books", "id", Symbol[],
id, title, author, cover
)
) = new("books", "id", id, title, author, cover)
end

end
Expand Down Expand Up @@ -264,11 +261,13 @@ Great, now let's display the images. Let's start with the HTML view - please edi
<!-- app/resources/books/views/billgatesbooks.jl.html -->
<h1>Bill's Gates top $( length(@vars(:books)) ) recommended books</h1>
<ul>
<%
@foreach(@vars(:books)) do book
"""<li><img src="$( isempty(book.cover) ? "img/docs.png" : book.cover )" width="100px" /> $(book.title) by $(book.author)"""
end
%>
<%
@foreach(@vars(:books)) do book
%>
<li><img src="$( isempty(book.cover) ? "img/docs.png" : book.cover )" width="100px" /> $(book.title) by $(book.author)
<%
end
%>
</ul>
```

Expand Down
2 changes: 1 addition & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ using Documenter
using Genie, Genie.App, Genie.AppServer, Genie.Assets
using Genie.Cache, Genie.Commands, Genie.Configuration, Genie.Cookies
using Genie.Encryption, Genie.FileTemplates, Genie.Flax, Genie.Generator
using Genie.Helpers, Genie.Inflector, Genie.Input, Genie.Loggers, Genie.Plugins
using Genie.Inflector, Genie.Input, Genie.Plugins
using Genie.Renderer, Genie.Requests, Genie.Responses, Genie.Router
using Genie.Sessions, Genie.Tester, Genie.Toolbox, Genie.Util, Genie.WebChannels

Expand Down
2 changes: 1 addition & 1 deletion files/new_app/app/helpers/ValidationHelper.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module ValidationHelper

using Genie, Genie.Helpers
using Genie
using SearchLight.Validation

export output_errors
Expand Down
8 changes: 4 additions & 4 deletions files/new_app/app/helpers/ViewHelper.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
module ViewHelper

using Genie, Genie.Helpers
using Genie, Genie.Flash, Genie.Router

export output_flash

function output_flash(params::Dict{Symbol,Any}) :: String
! isempty( flash(params) ) ? """<div class="form-group alert alert-info">$(flash(params))</div>""" : ""
function output_flash() :: String
flash_has_message() ? """<div class="form-group alert alert-info">$(flash())</div>""" : ""
end

end
end
2 changes: 1 addition & 1 deletion files/new_app/genie.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function bootstrap() :: Nothing

isfile("env.jl") && include("env.jl")
haskey(ENV, "GENIE_ENV") || (ENV["GENIE_ENV"] = "dev")
@info "\nStarting Genie in >> $(ENV["GENIE_ENV"] |> uppercase) << mode \n\n"
@info "\nStarting Genie v$(Genie.Configuration.GENIE_VERSION) in >> $(ENV["GENIE_ENV"] |> uppercase) << mode \n\n"

push!(LOAD_PATH, pwd(), "src")

Expand Down
Loading

2 comments on commit d7fc35b

@essenciary
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/3044

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if Julia TagBot is installed, or can be done manually through the github interface, or via:

git tag -a v0.16.0 -m "<description of version>" d7fc35bd1f5fd77fe981065a0e010152944a70d5
git push origin v0.16.0

Please sign in to comment.