├── .gitignore ├── README.md ├── build ├── documentation.json ├── elm-package.json ├── index.html ├── src ├── UrlParameterParser.elm └── UrlParseUtil.elm └── test.sh /.gitignore: -------------------------------------------------------------------------------- 1 | elm.js 2 | elm-stuff 3 | Gemfile 4 | Gemfile.lock 5 | _site 6 | node_modules 7 | *.js 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Elm Parameter Parsing 2 | 3 | This is an elm library for parsing parameters on the URL. 4 | 5 | ## To use it 6 | 7 | ```elm package install jessitron/elm-param-parsing``` 8 | 9 | To use this, you'll need 10 | to create an input port, pass the search string to Elm, and then parse 11 | them with this function, then that can populate your model. 12 | 13 | For instance, in the web page: 14 | 15 | var app = Elm.fullscreen(Elm.YourModule, 16 | { locationSearch: window.location.search }); 17 | 18 | in YourModule.elm, declare the port and then parse what comes into it. This example discards errors: 19 | 20 | ``` 21 | import Dict exposing (Dict) 22 | 23 | port locationSearch : String 24 | 25 | parameters : Dict String String 26 | parameters = 27 | case (parseSearchString locationSearch) of 28 | Error _ -> Dict.empty 29 | UrlParams dict -> dict 30 | ``` 31 | 32 | Then use that dict when you call your init function that needs the value 33 | of the parameter. 34 | 35 | ``` 36 | init (Dict.get parameters "customerID") 37 | 38 | init : Maybe String -> Model 39 | init maybeID = ... 40 | ``` 41 | 42 | ## see it in action 43 | 44 | The example app is built into this repo. 45 | [source](https://github.com/jessitron/elm-param-parsing/tree/ui); 46 | [result](http://jessitron.github.io/elm-param-parsing) 47 | 48 | -------------------------------------------------------------------------------- /build: -------------------------------------------------------------------------------- 1 | elm-make src/UrlParameterParser.elm 2 | -------------------------------------------------------------------------------- /documentation.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "UrlParameterParser", 4 | "comment": "Parse URL parameters. To use this, you'll need to create an input port, pass the search string to Elm,\nand then parse them with this function, then that can populate your model.\n\nFor instance, in the web page:\n```\n var app = Elm.fullscreen(Elm.YourModule,\n { locationSearch: window.location.search });\n```\nin YourModule.elm:\n```\nport locationSearch : String\n```\n\nThen parse the value of the port - this example discards errors:\n```\n\nimport Dict exposing (Dict)\nimport UrlParameterParser exposing (ParseResult(..))\n\nparameters : Dict String String\nparameters = \n case (parseSearchString locationSearch) of\n Error _ -> Dict.empty\n UrlParams dict -> dict\n```\n\nThen use that dict when you call your init function that needs the value of the parameter. It'll get a Maybe String.\n```\ninit (Dict.get \"customerID\" parameters)\n\ninit : Maybe String -> Model\ninit maybeID = ...\n```\n\n# Method\n@docs parseSearchString\n\n# Return type\n@docs ParseResult", 5 | "aliases": [], 6 | "types": [ 7 | { 8 | "name": "ParseResult", 9 | "comment": "\n If parsing is successful, you get a UrlParams containing a dictionary of keys to values.\n Otherwise, an error string.\n If there are no parameters, you'll get an error description.", 10 | "args": [], 11 | "cases": [ 12 | [ 13 | "Error", 14 | [ 15 | "String" 16 | ] 17 | ], 18 | [ 19 | "UrlParams", 20 | [ 21 | "Dict.Dict String String" 22 | ] 23 | ] 24 | ] 25 | } 26 | ], 27 | "values": [ 28 | { 29 | "name": "parseSearchString", 30 | "comment": "\n Given a search string of the form \"?key=value&key2=val2\"\n parse these into a dictionary of key to value.", 31 | "type": "String -> UrlParameterParser.ParseResult" 32 | } 33 | ], 34 | "generated-with-elm-version": "0.15.1" 35 | } 36 | ] -------------------------------------------------------------------------------- /elm-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "summary": "utility method to parse URL parameters", 4 | "repository": "https://github.com/jessitron/elm-param-parsing.git", 5 | "license": "BSD3", 6 | "source-directories": [ 7 | "src" 8 | ], 9 | "exposed-modules": [ 10 | "UrlParameterParser" 11 | ], 12 | "dependencies": { 13 | "elm-lang/core": "4.0.0 <= v < 5.0.0" 14 | }, 15 | "elm-version": "0.17.0 <= v < 0.18.0" 16 | } 17 | -------------------------------------------------------------------------------- /src/UrlParameterParser.elm: -------------------------------------------------------------------------------- 1 | module UrlParameterParser exposing 2 | ( ParseResult(..) 3 | , parseSearchString 4 | ) 5 | 6 | {-| Parse URL parameters. To use this, you'll need to create an 7 | input port, pass the search string to Elm, 8 | and then parse them with this function, then that can populate your model. 9 | 10 | For instance, in the web page: 11 | ``` 12 | var app = Elm.fullscreen(Elm.YourModule, 13 | { locationSearch: window.location.search }); 14 | ``` 15 | in YourModule.elm: 16 | ``` 17 | port locationSearch : String 18 | ``` 19 | 20 | Then parse the value of the port - this example discards errors: 21 | ``` 22 | parameters : Dict String String 23 | parameters = 24 | case (parseSearchString locationSearch) of 25 | Error _ -> Dict.empty 26 | UrlParams dict -> dict 27 | ``` 28 | 29 | Then use that dict when you call your init function that needs the 30 | value of the parameter. It'll get a Maybe String. 31 | ``` 32 | init (Dict.get parameters "customerID") 33 | 34 | init : Maybe String -> Model 35 | init maybeID = ... 36 | ``` 37 | 38 | # Method 39 | @docs parseSearchString 40 | 41 | # Return type 42 | @docs ParseResult 43 | 44 | -} 45 | 46 | import Dict exposing (Dict) 47 | import String 48 | import UrlParseUtil exposing (..) 49 | 50 | {-| 51 | If parsing is successful, you get a UrlParams containing a dictionary of keys to values. 52 | Otherwise, an error string. 53 | If there are no parameters, you'll get an error description. 54 | -} 55 | type ParseResult = 56 | Error String 57 | | UrlParams (Dict String (Maybe String)) 58 | 59 | {-| 60 | Given a search string of the form "?key=value&key2=val2" 61 | parse these into a dictionary of key to value. 62 | -} 63 | parseSearchString : String -> ParseResult 64 | parseSearchString startsWithQuestionMarkThenParams = 65 | case String.uncons startsWithQuestionMarkThenParams of 66 | Nothing -> Error "No URL params" 67 | Just ('?', rest) -> parseParams rest 68 | _ -> Error "Doesn't start with `?`" 69 | 70 | parseParams : String -> ParseResult 71 | parseParams stringWithAmpersands = 72 | let 73 | eachParam = (String.split "&" stringWithAmpersands) 74 | eachPair = List.map (splitAtFirst '=') eachParam 75 | in 76 | UrlParams (Dict.fromList eachPair) 77 | 78 | -------------------------------------------------------------------------------- /src/UrlParseUtil.elm: -------------------------------------------------------------------------------- 1 | module UrlParseUtil exposing (..) 2 | 3 | import String 4 | 5 | {-| These are broken out only to be testable 6 | without being exposed 7 | -} 8 | 9 | splitAtFirst : Char -> String -> (String, Maybe String) 10 | splitAtFirst c s = 11 | case firstOccurrence c s of 12 | Nothing -> (s, Nothing) 13 | Just i -> ( String.left i s 14 | , let right = String.dropLeft (i + 1) s 15 | in if right == "" 16 | then Nothing 17 | else Just right 18 | ) 19 | 20 | 21 | firstOccurrence : Char -> String -> Maybe Int 22 | firstOccurrence c s = 23 | case String.indexes (String.fromChar c) s of 24 | [] -> Nothing 25 | head :: _ -> Just head 26 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | elm-make src/*.elm 2 | elm-make test/*.elm --output test/raw-test.js 3 | bash test/elm-io.sh test/raw-test.js test/test.js 4 | node test/test.js 5 | --------------------------------------------------------------------------------