π₯ The fastest way to build type safe web apps. IHP is a new batteries-included web framework optimized for longterm productivity and programmer happiness
The first release of IHP in 2021 π
HTTP Caching: We now set common HTTP headers for your CSS, JS and other static files. This will speed up your apps by a lot.
static/
are never cached. This also fixed an issue where sometimes the browser was incorrectly caching your "old" CSS in dev mode. This is not happening anymore.Cache-Control
, Last-Mofified
and ETag
headersstatic/
are cached for 24 hoursstatic/vendor/
are cached for 30days. So it's best to place all your library code here.ihp-auto-refresh.js
are also cached up to 30 daysMail: Support for Generic SMTP and SendGrid: Previously IHP was only working with your local sendmail
or AWS SES. You can now connect SendGrid or any custom SMTP server.
macOS Big Sur Support + Package Updates: We're updating the GHC version used by IHP to improve support for macOS Big Sur. This also includes updating our nixpkgs version.
CHECK
Constraints: You can now use CHECK
constraints inside your Schema.sql
.
redirectBack: Use redirectBack
to redirect the user back where he came from:
action LikeAction { postId } = do
post <- fetch postId
post
|> incrementField #likesCount
|> updateRecord
redirectBack
This relies on the Referer
header being set. If the header is missing the user will be redirect back to the startpage. You can also provide a custom fallback path using redirectBackWithFallback "/custom-fallback"
.
Improved router error handling in prod: In production we don't give out debugging info anymore as this is not useful for users. It's just a generic An error happend
page now.
fetch
with a UUID that does not exist), the 404 page will be shown instead of a generic error page like beforeJS & CSS Bundling Disabled: All new IHP apps that are created with ihp-new
will now not have the IHP CSS and JS Bundling enabled. The bundling usually causes a bad experience when deploying your app for the first time, because usually you miss some configuration in your Makefile
. With the new http caching it also doesn't have that much of a performance impact.
Simplify Auto Refresh Setup: The auto refresh is now part of the default application setup of new IHP apps. This way you can now just call autoRefresh
on your actions and don't need to spend any time on boilerplate.
copyFields
Function: Useful to rewrite getter-setter code like this:
-- OLD:
let newProject = newRecord @Project
|> set #name (get #name otherProject)
|> set #isPublic (get #isPublic otherProject)
|> set #userId (get #userId otherProject)
-- NEW:
let newProject = newRecord @Project
|> copyFields @["name", "isPublic", "userId"] otherProject
currentUser
are now part of the IHP.ControllerPrelude
and IHP.ViewPrelude
modules and so don't need to be added to the Application.Helper.View
and Application.Helper.Controller
files anymore.CurrentUserRecord
is now specified in Web.Types
.IHP.Server
that caused GHC to take huge amounts of memory when compiling with O2
optimization settings
{}
curly braces
beforeLogin
in the IHP Session Controller Hook System is now able to access the database. This way you can e.g. implement a login counter that goes up every time a user logs into your app.
IDE
. So /schema-designer.css
is now /IDE/schema-designer.css
.
createMany
was called with an empty list (createMany []
)
If you have any problems with updating, let us know on the IHP forum.
π§ To stay in the loop, subscribe to the IHP release emails. Or follow digitally induced on twitter..
π The next release is expected to be released at the end of January. There's still a couple things to do before we can tag v0.9.0 which is the last release before v1.0.0 which is planned to be released early this year.
Time for the next release of IHP: v20201213 π
deleteRecordById
: Like deleteRecord
but you can pass an id instead of a full record.
startPage
now works with apps other than Web
nonEmpty
validator now works with Id record
values
InputValue Aeson.Value
instance, so form fields can be used with json fields
If you have any problems with updating, let us know on the IHP forum.
π§ To stay in the loop, subscribe to the IHP release emails. Or follow digitally induced on twitter..
π The next release is expected to be released on 08.01.2021.
It's time for the next release of IHP: v20201030 π This release mainly focus on improving existing functionality and making things more stable :) Since the last release we also reached an important milestone: IHP is now the second biggest haskell framework measured by GitHub stars - just 5 months after it's initial public release. The future of haskell web dev is happening right here π
Update DB
will now be displayed in a more useful way. Previously the error message just displayed the full postgresql output in a single line. Now the error message is displayed like this:
tailwindcss
into your IHP projects. You can find the guide here: https://ihp.digitallyinduced.com/Guide/tailwindcss.html
How many people are running at which IHP version? What is the primary OS people are using IHP on? How many active users are working with IHP?
we added Telemetry to the local dev server that runs when you call ./start
. The dev server reports ihpVersion
, os
, architecture
and a anonymous project id to ihp-telemetry.digitallyinduced.com
. You can opt-out by setting a env var IHP_DISABLE_TELEMETRY=1
ON DELETE SET DEFAULT
: Next to ON DELETE SET NULL
you can now use SET DEFAULT
.
POINT
column in IHP. The Point type is also supported inside the param
functions.
New Migration
Generator now automatically creates the Application/Migration
directory on first use
setLayout
is not called inside the application lifecycle IHP will now continue to render a view. Previously it would crash when calling render
without a layout.
migrate
command
Next
button at the bottom of the first sections.
DEBUG=1 ./start
).
Cannot start app as postgres is not ready yet
. This error cannot happen anymore since we added database pools. Usually when this happens it's usually a false alarm.
If you have any problems with updating, let us know on the IHP forum. Or join our new slack.
π§ To stay in the loop, subscribe to the IHP release emails. Or follow digitally induced on twitter..
π The next release is expected to be released on 11.12.2020.
It's friday the 13th, a good day for the next release of IHP: v13112020 π This release changes a couple of important things in IHP, so plan a bit more time again to upgrade your apps.
Config/Config.hs has a new format: We rebuild the whole configuration management to remove some very bad hacks and to allow for more flexibility in the future.
Custom 404 Page: You can now customize the 404 Page used by IHP. Just create a new file at static/404.html
. IHP will automatically render this instead of the default IHP error page. See the docs for details.
Custom CSS Frameworks: You can now override the CSS classes used by e.g. IHP forms. By default it uses bootstrap, but you can switch to tailwind
(which is supported out of the box, but you need to add the <link>
tags manually to your header in Layout.hs) or even use a custom CSS framework.
ViewContext has been removed: You might have seen that ViewContext thing in your views. It's been replaced with ControllerContext
to simplify the whole action lifecycle.
New Migration System: There's a new migration system for migrating your production or staging database. There's also a new code generator for migrations. Check the Guide for Migrations
to learn more.
Improved Support for JSON Requests: Useful when building APIs with IHP. Instead of sending a form body you can now also send a json body when you set the Content-Type: application/json
header from your API client. You can use the familiar param
functions to access the json values:
Documentation for Modals: It was always missing, when the docs are missing it feels like the feature isn't there at all :D Now you can finally use modals everywhere. Check the new Modal documentation in the Guide.
action UsersAction = do
users <- query @User
|> limit (param @Int "limit")
|> fetch
render UsersView { .. }
This action could be called from curl like this:
curl --header 'Content-Type: application/json' --data '{"limit": 50}' --request POST http://localhost:8000/Users
Makefile
again instead of being hardcoded
ModelControllerMap
type family has been removed
ViewApp
type family has been removed
checkboxField
function now actually uses the user-specified labelClass
mime-mail-ses
packages has been updated in the IHP package set. The previously provided package definition was broken
sqlQuery
and sqlExec
now also log the executed sql queries like createRecord or updateRecord do
data-turbolinks-preload='false'
on a link it's not preloaded anymore
selectField
input
build/ihp-lib
exists. If the symlink is missing, it will be created. This makes the dev environment more reliable
If you have any problems with updating, let us know on the IHP forum. Or join our new slack.
π§ To stay in the loop, subscribe to the IHP release emails. Or follow digitally induced on twitter..
π The next release is expected to be released on 27.11.2020.
Just a small out-of-line release. In the last version we broke the code generators, causing an issue when generating a new controller. When you get an error like Not in scope: type constructor or class βStaticControllerinstanceβ
, update to this release.
Here's a full error message you get with v20201030
when generating a new controller:
Not in scope: type constructor or class 'StaticControllerinstance'
|
7 | instance AutoRoute StaticControllerinstance AutoRoute CustomersController
| ^^^^^^^^^^^^^^^^^^^^^^^^
Workaround: If you don't want to update, you can easily manually fix the issue by opening Web/Routes.hs
and adding a missing newline character:
You will find code like this:
instance AutoRoute StaticControllerinstance AutoRoute CustomersController
Just add a new line before the second instance
:
instance AutoRoute StaticController
instance AutoRoute CustomersController
First open default.nix
and change the git commit in line 4 to the following:
rev = "e21f5d743104ba8b1bed185ee85fb20e064e0bef";
After that run the following command to update your project:
nix-shell -j auto --cores 0 --run 'make -B .envrc'
make -B build/ihp-lib
Now you can start your project as usual with ./start
.
It's time for the next release of IHP: v20201030 π This release mainly focus on improving existing functionality and making things more stable :)
Database Connection Pool: IHP now comes with a new database connection pool. This allows for better scalability and performance when dealing with many queries. It also makes IHP more reliable: In previous versions of IHP, a long running database connection might be closed by the database server when nothing happens for too long. This issue will not happen anymore with the new db connection pool.
Live Reloading Improvements: A bug has been fixed that caused the live reloading not to work when a file was changed. Additionally the web-based compiling status view has been rewritten to be more efficient (you can really feel that it's faster now).
LocalTime Support: Support for TIMESTAMP WITHOUT TIME ZONE
has been added. It works similiar to the normal timestamp you already know from IHP, but doesn't store any Timezone information.
Welcome Page In Project: When generating a new IHP project, the project now contains the initial welcome action as part of the project code. This allows to for more play when just starting out, because now you can just change the welcome view as you like :)
Basic Auth: Finally you can have basic auth prompts in IHP. You can use it like this:
instance Controller WidgetsController where
beforeAction = basicAuth "sanja" "hunter2" "myapp"
This requires the user to enter sanja
with password hunter2
when trying to access the WidgetsController
. Check the documentation for details.
Schema.sql
INSERT, UPDATE, DELETE
queries now work in the custom sql query box inside the IHP Data Editor
Schema.sql
. This avoids issues where a CREATE TABLE
statements uses an enum that hasn't been defined yet.
data-confirm
: <a href={DeleteProjectAction} data-confirm={"Do you really want to delete" <> get #name project <> "?"}>Delete project</a>
js-delete
for your link.ihp-new
now sets the correct permissions to the .ghci
when starting a new project. This has caused troubles in the past for some new users
.stylish-haskell
config file that's part of all IHP projects by default has been updated to work again with the latest IHP version
First open default.nix
and change the git commit in line 4 to the following:
rev = "a8030dd1e4041a0353f63d03b4ffb836cb2bd95c";
After that run the following command to update your project:
nix-shell -j auto --cores 0 --run 'make -B .envrc'
make -B build/ihp-lib
Now you can start your project as usual with ./start
.
Aside from all the code changes above we've also updated the IHP website: https://ihp.digitallyinduced.com/ :) First big refresh after IHP has been published around 4 months ago.
If you have any problems with updating, let us know on the IHP forum.
π§ To stay in the loop, subscribe to the IHP release emails. Or follow digitally induced on twitter..
π The next release is expected to be released on 13.11.2020.
It's time for the next release of IHP: v20201016 π
Haskell Language Server Support: You can now get cool IDE features by using Haskell Language Server. It works mostly out of the box after updating to this IHP version. Check out the documentation on how to get it running with your fav editor.
Updated NixPkgs Version: We're updating the IHP package set to a newer version. We're moving from da7ddd822e32aeebea00e97ab5aeca9758250a40
to 07e5844fdf6fe99f41229d7392ce81cfe191bcfc
. This means some of your dependencies might get updated.
OFFSET Support: You can now easily use Postgres OFFSET
with the query builder:
query @User
|> limit 25
|> offset 50
|> fetch
New Form Helper: numberField
: Similiar to textField
, renders a <input type="number"/>
.
formFor project [hsx|
{numberField #maxUsersLimit}
|]
Automatic Troubleshooting: We've created a script that checks all common issues that often go wrong when setting up IHP (like direnv
issues, .ghci
permission issues, etc.). When you cannot run your IHP app anymore, run the troubleshooting to find out possible error conditions. You can find more in the Troubleshooting section.
Sending Emails: Support for sending mails has been added in this release. Use the new code generator to get started π₯
param @Bool
now accepts true
as a truthy value.
HttpOnly
and secure
(only if app is served via https) now
beforeLogin
callback. This can be useful to abort the login process when a user is not yet confirmed.
urlTo
can now be used everywhere where pathTo
is used
stripTags
function has been added to HaskellSupport
. This function removes all html tags from an input string.
Uploading a user profile picture
now mentions that the picture_url
should be nullable
Id
values such as Id Project
now have Ord
and Hashable
instances by default
Data
Tool have been fixed. E.g. adding a row works again now.
Using IHP with Emacs
has been added
Using IHP with Vim
has been added
textToId
function now also works with text primary keys. Previously it only worked with UUIDs.
postgresql-simple
Only
wrapper is now exported to all controllers
BYTEA
) column in a table
This release requires a few more steps than usual. As we've changed the nixpkgs version, this will also require a lot of redownloading of all packages. Make sure you have good internet and can wait up to 30 minutes to complete the download. We highly suggest to make sure your coffee machine is working before starting the update.
First open default.nix
and change the git commit in line 4 to the following:
rev = "49816c21d34fd7894a956bf7fd997e6ed5243acf";
Open Config/nix/nixpkgs-config.nix
and replace the file with this new version: https://raw.githubusercontent.com/digitallyinduced/ihp-boilerplate/81518e9b66e1e9d3bdf40affa674a7d2cd63f414/Config/nix/nixpkgs-config.nix
After that run the following command to update your project:
# Be aware that this will redownload a lot of files and take lots of time
nix-shell -j auto --cores 0 --run 'make -B .envrc'
make -B build/ihp-lib
# This step is required to get the config files for haskell-language-server
make hie.yaml
Now you can start your project as usual with ./start
.
Check out the docs to get started with haskell language server to get cool IDE features.
If you have any problems with updating, let us know on the IHP forum.
π§ To stay in the loop, subscribe to the IHP release emails. Or follow digitally induced on twitter..
π The next release is expected to be released on 30.10.2020.
It's time for the next release of IHP: v20201002 π
INSERT
, UPDATE
or DELETE
happens to the records used by your action IHP will rerun your action on the serverside. When the generated html looks different to the html generated on the initial page load it will send the new html to the browser using the WebSocket connection. Watch a demo on twitter or Learn more in the Auto Refresh documentation.
param
but returns a list when the input is something like ingredients=milk&ingredients=egg
. Useful when working with checkboxes.LIMIT
to your sql queries easily when using the query builder:
topTen <- query @Post
|> orderBy #rating
|> limit 10
|> fetch
int[]
or text[]
. These types are not visible in the web-based dev tools yet, but can be used manually when using a code editor to edit the Schema.sql
.collectionFetchRelated
was not working with certain relationships. This has been fixed and the below code will now work as expected:
posts <- query @Post
|> fetch
>>= collectionFetchRelated #comments
- The image upload recipe has been extended to document how the form needs to look when doing image uploads.
- Login error messages are now Invalid credentials
- Generated.Types
is imported by default in the empty Layout.hs
- The Contributing documentation now explains how to run the IHP tests
- A bug where the FrontController.hs was generated twice was fixed
- The version of morphdom used by IHP has been updated
- A new textToId
function has been added to simplify conversion of text or bytestrings to db ids
- Missing documentation on fetchCount
has been added
- New recipe: How to generate a random string
- New function: sqlQueryScalar
similiar to sqlQuery
but returns a scalar value
- Fixed scripts not working in dev mode
- Fixed awk warning when running make static/prod.js
To update the IHP version of your project, open default.nix
and change the git commit in line 4 to the following:
rev = "c4d2815f064c055cd957389a4df5eab25294dba3";
After that run the following command to update your project:
nix-shell -j auto --cores 0 --run 'make -B .envrc'
make -B build/ihp-lib
Now you can start your project as usual with ./start
.
If you have any problems with updating, let us know on the IHP forum.
π§ To stay in the loop, subscribe to the IHP release emails. Or follow digitally induced on twitter..
π The next release is expected to be released on 16.10.2020.
If you haven't looked already, check out the IHP Auto Refresh Demo π
It's time for the next release of IHP: 20200918 π
query @User |> orderBy #firstname |> orderBy #lastname
. Previously the last call to orderBy #lastname
would overwrite the existing orderBy #firstname
. This has been added by @fegu πerror: file '/build/db/.s.PGSQL.5432' has an unsupported type
when starting IHP has been fixed by @ruhatch ! π This error happend when opening a new nix shell while the dev server is running.getSessionAndClear
: Returns a session value and removes it from the sessiongetRequestUrl
has been renamed to getRequestPath
to better reflect it's behavior. Also a new getRequestPathAndQuery
has been added.
jsonb
: You can now easily store json inside your postgres with your IHP app. Right now this is just very basic support. Additional support for mapping the json will be added in the future. Currently you need to manually map it using aeson.toSlug
: toSlug "IHP Release: 18.09.2020"
will turn the string into a url friendly version "ihp-release-18-09-2020"
.fetchOne
fails because no result was returned
dateTime
is now working correctly in all locals :) Thanks @dansvo!fetchExists
To update the IHP version of your project, open default.nix
and change the git commit in line 4 to the following:
rev = "0575a933331d45782ed732a5437ead377e165b29";
After that run the following command to update your project:
nix-shell -j auto --cores 0 --run 'make -B .envrc'
Now you can start your project as usual with ./start
.
If you have any problems with updating, let us know on the IHP forum.
π§ To stay in the loop, subscribe to the IHP release emails. Or follow digitally induced on twitter..
π The next release is expected to be released on 02.10.2020.
It's time for the next release of IHP: 20200904 π
CREATE TABLE order_trucks (
order_id BIGSERIAL NOT NULL,
truck_id BIGSERIAL NOT NULL,
PRIMARY KEY(order_id, truck_id)
);
This feature has been contributed by @ruhatch π
param
now have a beautiful error screen telling you about what do next. It also displays all submitted params, so you can quickly spot whether there was a typo.SQL Logging only in dev mode: IHP will now not log sql queries when it's running in production mode.
Improved Data Tool in the Dev Tooling: The database access tool (below the Schema Editor in the IHP navigation) now makes more efficient use of screen space. We made a few small changes to improve the overall usability of the tool.
More documentation:
- The primary haskell json library aeson
is now exported by the ViewPrelude by default. No need to manually import it in your views anymore.
- A code generation issue caused by having a table with two foreign keys referencing the same foreign table has been fixed.
- An issue encoding with enums using multibyte characters has been resolved
- The CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
is not required in your app's Schema.sql
anymore. It's automatically loaded by IHP.
- Support for empty attributes in HSX like <input disabled/>
has been added.
- Grammar fixes
- The make target build/bin/RunOptimizedProdServer
now correctly depends on build/Generated/Types.hs
. The target build/bin/RunUnoptimizedProdServer
already has this dependency.
- Dotless Emails are now validated correctly
- All IHP binaries are now compiled with -threaded
. Somehow we missed this. This improves the performance of the dev server.
- The default ghci prompt of a IHP is now a lambda symbol
- make targets for compiling IHP scripts have been added
- a naming issue causing request
not being easily useable in actions has been resolved
vDDMMYYYY
to vYYYYMMDD
starting with this version.To update the IHP version of your project, open default.nix
and change the git commit in line 4 to the following:
rev = "a12a1ce8f16814b802aae39eb26a9d3247192c12";
After that run the following command to update your project:
nix-shell -j auto --cores 0 --run 'make -B .envrc'
Now you can start your project as usual with ./start
.
In case you get a compiler error about a missing field in ModelContext
in the auto-generated build/Generated/Types.hs
please stop your application and do a clean rebuild:
make clean
nix-shell -j auto --cores 0 --run 'make -B .envrc'
./start
If you have any problems with updating, let us know on the brand new IHP forum.
π§ To stay in the loop, subscribe to the IHP release emails. Or follow digitally induced on twitter..
π The next release is expected to be released on 18.09.2020.
Also a short update on IHP Cloud: We're sending out the first IHP Cloud invites in the coming days π₯