Widget 이란?
Yesod의 경우 위젯의 역할은 HTML, CSS, Javascript 등의 컴포넌트를 적절히 하나의 HTML로 정리하기 위한 통일된 표현을 부여하기 위한 것입니다. 예를 들면, Web 페이지를 기술하는 실제에서는 아래의 형식적인 관습을 따르는 편이 좋습니다.
- CSS는 페이지의 head 부분에 기술한다
- Javascript은 body의 마지막에 기술한다
- jQuery 등의 외부 파일을 여러번 회독하지 않음
- 타이틀태그는 한 번 출현
위젯 컴포넌트
컴포넌트의 종류 | 실제 태그 | Yesod에서 취급하기 위한 함수 또는 템플릿 언어 |
---|---|---|
타이틀 | <title> ... </title> | setTitle |
외부의 스타일시트 | <link rel="stylesheet" href="..."> | addStylesheet계열 |
외부의 Javascript | <script src="..."></script> | addScript계열 |
CSS 코드 | <style>...</style> | Cassius or Lucius |
Javascript 코드 | <script>...</script> | Julius |
임의의 head 컨텐츠 | <head>...</head> | Hamlet |
임의의 body 컨텐츠 | <body>...</body> | Hamlet |
위젯 사용방법
1 2 3 4 5 6 7 8 9 10 | # stack new widget yesod-simple && cd widget Downloading template "yesod-simple" to create project "widget" in widget/ ... Looking for .cabal or package.yaml files to use to init the project. Using cabal packages: - widget/widget.cabal Selecting the best among 12 snapshots... Downloaded lts-10.3 build plan. AesonException "Error in $.packages.cassava.constraints.flags['bytestring--lt-0_10_4']: Invalid flag name: \"bytestring--lt-0_10_4\"" | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | # stack build yesod-bin cabal-install --install-ghc # stack build blackbriar-0.0.0: unregistering (components added: exe:blackbriar) blackbriar-0.0.0: configure (lib + exe) Configuring blackbriar-0.0.0... blackbriar-0.0.0: build (lib + exe) Preprocessing library blackbriar-0.0.0... [ 1 of 13] Compiling Settings ( src/Settings.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Settings.o ) [ 2 of 13] Compiling Settings.StaticFiles ( src/Settings/StaticFiles.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Settings/StaticFiles.o ) [ 3 of 13] Compiling Model ( src/Model.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Model.o ) [ 4 of 13] Compiling Import.NoFoundation ( src/Import/NoFoundation.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Import/NoFoundation.o ) [ 5 of 13] Compiling Foundation ( src/Foundation.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Foundation.o ) src/Foundation.hs:150:5: warning: [-Wincomplete-patterns] Pattern match(es) are non-exhaustive In an equation for ‘isAuthorized’: Patterns not matched: HaskellR _ [ 6 of 13] Compiling Import ( src/Import.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Import.o ) [ 7 of 13] Compiling Handler.Comment ( src/Handler/Comment.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Handler/Comment.o ) [ 8 of 13] Compiling Handler.Common ( src/Handler/Common.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Handler/Common.o ) [ 9 of 13] Compiling Handler.Echo ( src/Handler/Echo.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Handler/Echo.o ) [10 of 13] Compiling Handler.Haskell ( src/Handler/Haskell.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Handler/Haskell.o ) [11 of 13] Compiling Handler.Home ( src/Handler/Home.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Handler/Home.o ) [12 of 13] Compiling Handler.Profile ( src/Handler/Profile.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Handler/Profile.o ) [13 of 13] Compiling Application ( src/Application.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/Application.o ) Preprocessing executable 'blackbriar' for blackbriar-0.0.0... [1 of 1] Compiling Main ( app/main.hs, .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/blackbriar/blackbriar-tmp/Main.o ) [flags changed] Linking .stack-work/dist/x86_64-linux/Cabal-1.24.2.0/build/blackbriar/blackbriar ... blackbriar-0.0.0: copy/register Installing library in .stack-work/install/x86_64-linux/lts-9.14/8.0.2/lib/x86_64-linux-ghc-8.0.2/blackbriar-0.0.0-2VBmQYLKFgeLhypfZqR3QO Installing executable(s) in .stack-work/install/x86_64-linux/lts-9.14/8.0.2/bin Registering blackbriar-0.0.0... | cs |
다음으로 /widget WidgetR GET
라는 루트에 핸들러를 추가한다.
1 2 3 4 | # stack exec -- yesod add-handler Name of route (without trailing R): Widget Enter route pattern (ex: /entry/#EntryId): /widget Enter space-separated list of methods (ex: GET POST): GET | cs |
바로 http://localhost:3000/widget 에 접속해보자. 아직까지는 아래 그림에서 보듯이Internal Server Error:
라고 표시가 되지만, 문제는 되지 않는다.
메시지에 나오는대로 아래와 같이 추가한다.
src/Foundation.hs
1 2 | -- Routes not requiring authentication. isAuthorized widgetR _ = return Authorized | cs |
그럼 이제 샘플사이트의 레이아웃에 적용하기 위해 아래에서 필요한 파일을 수정해보자.
사용방법
setTitle
을 통해 html 파일의 타이틀을 지정할 수 있다.Handler/Widget.hs
1 2 3 4 5 6 7 8 9 | {-# LANGUAGE OverloadedStrings #-} module Handler.Widget where import Import getWidgetR :: Handler Html getWidgetR = defaultLayout $ do setTitle "ウィジェットテスト1" | cs |
상기 코드가 생성하는 HTML
1 2 3 4 5 6 7 | <html> <head>> <title>ウィジェットテスト1</title> </head> <body> </body> </html> | cs |
복수의 setTitle
을 기술하면, 아래와 같이 가장 마지막의 ウィジェットテスト3 이 표시된다.
Handler/Widget.hs
1 2 3 4 5 6 7 8 9 10 11 | {-# LANGUAGE OverloadedStrings #-} module Handler.Widget where import Import getWidgetR :: Handler Html getWidgetR = defaultLayout $ do setTitle "ウィジェットテスト1" setTitle "ウィジェットテスト2" setTitle "ウィジェットテスト3" | cs |
상기 코드가 생성하는 HTML
1 2 3 4 5 6 7 | <html> <head>> <title>ウィジェットテスト3</title> </head> <body> </body> </html> | cs |
addStylesheet 계열
스타일시트를 읽어내는 위젯입니다. 아래와 같이 동종의 위젯이 몇 개 제공됩니다. 속성은 [(속성명, 속성값)]
과 같은 형식으로 추가합니다.
함수명 | 참조처 (로컬) | 참조처 (리모트) | 속성정보의 추가 |
---|---|---|---|
addStylesheet | O | ||
addStylesheetAttrs | O | O | |
addStylesheetRemote | O | ||
addStylesheetRemoteAttrs | O | O | |
addStylesheetEither | O | O |
사용방법 (로컬 참조)
1 2 3 4 5 6 7 8 9 10 11 | {-# LANGUAGE OverloadedStrings #-} module Handler.Widget where import Import getWidgetR :: Handler Html getWidgetR = defaultLayout $ do addStylesheet $ StaticR css_bootstrap_css addStylesheetAttrs (StaticR css_bootstrap_css) [("title", "Sample")] addStylesheet $ StaticR css_bootstrap_css | cs |
1 2 3 4 5 6 7 8 9 10 11 12 | <html> <head> <title></title> <link rel="stylesheet" href="http://***.**.***.***:3000/static/css/bootstrap.css?etag=PDMJ7RwX"> <link rel="stylesheet" href="http://***.**.***.***:3000/static/css/bootstrap.css?etag=PDMJ7RwX" title="Sample"> <link rel="stylesheet" href="http://***.**.***.***:3000/static/tmp/autogen-dyDfk8nC.css"> </head> <body> </body> </html> | cs |
로컬의 정적(static
) 파일을 취급하기 위해 아래의 사항을 주의할 필요가 있습니다.
static/
아래에 파일을 배치할 필요가 있음- 정적 파일을 패스에 대응하는 안전형URL의 데이터 컨스트럭터는
StaticR
을 사용 - 참조시의 파일의 패스에 관하여、
/ . -
의 기호는_
으로 바꾼다.
상기 예에서 StaticR css_bootstrap_css
는 /static/css/bootstrap.css
라고 해석하게 된다.
사용방법(리모트 참조)
CDN을 참조하는 링크의 경우에는 다수의 예를 생각해볼 수 있습니다. 아래는 Bulma
의 css
를 가져오는 예제입니다.
1 2 3 4 5 6 7 8 9 10 11 | {-# LANGUAGE OverloadedStrings #-} module Handler.Widget where import Import getWidgetR :: Handler Html getWidgetR = defaultLayout $ do addStylesheetRemote "https://cdnjs.cloudflare.com/ajax/libs/bulma/0.2.3/css/bulma.min.css" addStylesheetRemoteAttrs "https://cdnjs.cloudflare.com/ajax/libs/bulma/0.2.3/css/bulma.min.css" [("title", "Sample")] addStylesheetRemote "https://cdnjs.cloudflare.com/ajax/libs/bulma/0.2.3/css/bulma.min.css" | cs |
1 2 3 4 5 6 7 8 9 10 11 | <html> <head> <title></title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.2.3/css/bulma.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.2.3/css/bulma.min.css" title="Sample"> </head> <body> </body> </html> | cs |
addScript 계열
스크립트파일을 읽어오기 위한 위젯입니다. addStyleSheet
계열의 함수와 동일합니다.
함수명 | 참조처 (로컬) | 참조처 (리모트) | 속성정보의 추가 |
---|---|---|---|
addScript | O | ||
addScriptAttrs | O | O | |
addScriptRemote | O | ||
addScriptRemoteAttrs | O | O | |
addScriptEither | O | O |
사용방법은 addStyleSheet
과 동일한 방법으로 할애합니다.
위젯은 모나드다
위젯은 모나드인 관계로, 작은 위젯을 조합하여 큰 위젯을 만들 수 있다.
Handler/Widget.hs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | {-# LANGUAGE OverloadedStrings #-} module Handler.Widget where import Import getWidgetR :: Handler Html getWidgetR = defaultLayout $ do cssWidget jsWidget cssWidget jsWidget cssWidget :: Widget cssWidget = do addStylesheet $ StaticR css_bootstrap_css addStylesheetAttrs (StaticR css_bootstrap_css) [("title", "Sample")] addStylesheet $ StaticR css_bootstrap_css jsWidget :: Widget jsWidget = do addStylesheetRemote "https://cdnjs.cloudflare.com/ajax/libs/bulma/0.2.3/css/bulma.min.css" addStylesheetRemoteAttrs "https://cdnjs.cloudflare.com/ajax/libs/bulma/0.2.3/css/bulma.min.css" [("title", "Sample")] addStylesheetRemote "https://cdnjs.cloudflare.com/ajax/libs/bulma/0.2.3/css/bulma.min.css" | cs |
상기 코드가 생성하는 HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 | <html> <head> <title></title> <link rel="stylesheet" href="http://***.***.***.***:3000/static/css/bootstrap.css?etag=PDMJ7RwX"> <link rel="stylesheet" href="http://***.***.***.***:3000/static/css/bootstrap.css?etag=PDMJ7RwX" title="Sample"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.2.3/css/bulma.min.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.2.3/css/bulma.min.css" title="Sample"> <link rel="stylesheet" href="http://***.***.***.***:3000/static/tmp/autogen-dyDfk8nC.css"> </body> </html> | cs |
'프로그래밍 Programming' 카테고리의 다른 글
Haskell Yesod의 템플릿 언어 세익스피어를 활용하여 웹페이지 만들기 (2) (0) | 2018.02.03 |
---|---|
Haskell Yesod의 템플릿 언어 세익스피어를 활용하여 웹페이지 만들기 (1) (0) | 2018.02.01 |
하스켈 익스텐션 사용법 How to Enable Extensions (0) | 2018.01.26 |
하스켈 Yesod 튜토리얼 - 페이지 추가하기 Minimal echo application (0) | 2018.01.19 |
하스켈 Yesod Illegal view pattern: fromPathPiece -> Just dyn_anHx (0) | 2018.01.19 |