plzwrk: A front-end framework

This is a package candidate release! Here you can preview how this package release will appear once published to the main package index (which can be accomplished via the 'maintain' link below). Please note that once a package has been published to the main package index it cannot be undone! Please consult the package uploading documentation for more information.

[maintain] [Publish]

Please see the README on GitHub at https://github.com/meeshkan/plzwrk#readme


[Skip to Readme]

Properties

Versions 0.0.0.0, 0.0.0.0, 0.0.0.1, 0.0.0.2, 0.0.0.3, 0.0.0.4, 0.0.0.5, 0.0.0.6, 0.0.0.7, 0.0.0.8, 0.0.0.9, 0.0.0.10
Change log ChangeLog.md
Dependencies aeson (>=1.4.7 && <1.5), base (>=4.7 && <5), bytestring (>=0.10.10 && <0.11), containers (>=0.6.2 && <0.7), mtl (>=2.2.2 && <2.3), neat-interpolation (>=0.5.1 && <0.6), plzwrk, random (>=1.1 && <1.2), text (>=1.2.3 && <1.3), transformers (>=0.5.6 && <0.6), unordered-containers (>=0.2.10 && <0.3) [details]
License BSD-3-Clause
Copyright 2020 Mike Solomon
Author Mike Solomon
Maintainer mike@meeshkan.com
Category Web
Home page https://github.com/meeshkan/plzwrk#readme
Bug tracker https://github.com/meeshkan/plzwrk/issues
Source repo head: git clone https://github.com/meeshkan/plzwrk
Uploaded by mikesol at 2020-05-01T19:51:03Z

Modules

[Index] [Quick Jump]

Flags

Manual Flags

NameDescriptionDefault
plzwrk-enable-asterius

Enable asterius

Disabled

Use -f <flag> to enable a flag, or -f -<flag> to disable that flag. More info

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees


Readme for plzwrk-0.0.0.0

[back to package description]

plzwrk

A Haskell front-end framework.

Hello world

import           Web.Framework.Plzwrk
import           Web.Framework.Plzwrk.Asterius
import           Web.Framework.Plzwrk.Tag (p__)

main :: IO ()
main = do
  browser <- asteriusBrowser
  plzwrk'_ (p__ "Hello world!") browser

See it live.

Kitchen sink

Check out the code here.

See it live.

Installation

Add plzwrk to the build-depends stanza of your .cabal file.

Also, add plzwrk-X.Y.Z.? to the extra-deps list of your stack.yaml file if you're using stack.

Making a webpage

plzwrk uses Asterius as its backend for web development. Compiling an application using plzwrk is no different than compiling an application using ahc-cabal and ahc-dist as described in the Asterius documentation with one caveat. You must use -f plzwrk-enable-asterius when running ahc-cabal.

A minimal flow is shown below, mostly copied from the asterius documentation. It assumes that you have a cabal-buildable project in the root directory. Note the use of the -f plzwrk-enable-asterius flag in the ahc-cabal step.

username@hostname:~/my-dir$ docker run --rm -it -v $(pwd):/project -w /project terrorjack/asterius
asterius@hostname:/project$ ahc-cabal new-install -f plzwrk-enable-asterius --installdir <inst-dir> <exec-name>
asterius@hostname:/project$ cd <inst-dir> && ahc-dist --input-exe <exec-name> --browser --bundle

Documentation

The main documentation for plzwrk is on hackage. The four importable modules are:

Design

plzwrk is inspired by redux for its state management. The main idea is that you have a HTML-creation function that accepts one or more variables from a state that is composed, via applicative functors, with getters from a state.


-- State
data MyState = MkMyState { _name :: Text, age :: Int, _tags :: [Text] }

-- Function hydrating a DOM with elementse from the state
makeP = (\name age -> p'__ concat [name, " is the name and ", show age, " is my age."]) <$> _name <*> _age

HTML-creation functions can be nested, allowing for powerful abstractions.

nested = div_ (take 10 $ repeat makeP)

HTML-creation functions use an apostrophe after the tag name (ie div') if they accept arguments and no apostrophe (ie div) if they don't. Additionally, tags that do not have any attributes (class, style etc) are marked with a trailing underscore (div_ [p__ "hello"]), and tags that only accept text are marked with two trailing underscores (p__ "hello").

The HTML-creation function itself should be pure with type (s -> Node s opq), where s is the type of the state and opq is the type of the opaque pointer used to represent a JavaScript value. opq will rarely need to be provided manually as it is induced from the compiler based on the Browserful being used (ie asteriusBrowser).

Event handlers take two arguments - an opaque pointer to the event and the current state - and return a new state (which could just be the original state) in the IO monad. For example, if the state is an integer, a valid event handler could be:

eh :: opq -> Int -> IO Int
eh _ i = pure $ i + 1

To handle events (ie extract values from input events, etc) you can use one of the functions exported by Web.Framework.Plzwrk. Please see the hackage documentation for more information.

If you are using the Asterius backend, callback functions are still quite fragile and subject to breakage. The less third-party libraries you use in them, the better. For example, avoid using Data.Text and aeson if possible.

Testing your code

Plzwrk comes with a mock browser that can act as a drop-in replacement for your browser. Use this in your tests.

import Web.Framework.Plzwrk.MockJSVal

main :: IO ()
    browser <- makeMockBrowser
    print "Now I'm using the mock browser."

Using

Plzwrk should be considered experimental. It is unfit for production and the syntax will change frequently, often in non-backward-compatible ways. There is a changelog.

Contributing

Thanks for your interest in contributing! Here is a small list of things I'd really appreciate help with: