-
-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add in the maybe
and with
control statements
#9
Comments
@cdepillabout I agree with the opinion that these additional control statements makes some code easier.
About
About I propose that it is much important to provide Of course, if you tell me actual use cases that can be enough good to require above disadvantages by providing these control statements, I'll rethink about it. |
I agree that not having Here's some examples of templates I'm writing for blueimpact/kucipong#86, and how they could be more simple with Example 1Here is an excerpt from the bottom of | %{ if null couponEntities }
| No Coupons
| %{ else }
| %{ forall couponEntity <- couponEntities }
include _couponSimple
| %{ endforall }
| %{ endif } And then here is the .couponSimple
a.card(href="/store/coupon/\#{ fromSqlKey (entityKey couponEntity) }")
.annotatedImageGroup
img.annotatedImageGroup-image(src=require("../img/dummy.jpg") alt="\#{ couponTitle (entityVal couponEntity) }")
span.annotatedImageGroup-annotation 画像は一例です
.card_body
.couponSimple_abstraction
h2.couponSimple_abstraction-store \#{ couponTitle (entityVal couponEntity) }
.couponSimple_abstraction-summary
| %{ if couponTypeIs couponEntity CouponTypeDiscount }
| %{ if isJust (couponDiscountPercent (entityVal couponEntity)) }
span.couponSimple_abstraction-summary-sub \#{ fromMaybe 0 (couponDiscountPercent (entityVal couponEntity)) }% OFF
| %{ endif }
| %{ if isJust (couponDiscountMinimumPrice (entityVal couponEntity)) }
span.couponSimple_abstraction-summary-main \#{ fromMaybe 0 (couponDiscountMinimumPrice (entityVal couponEntity)) }円
| %{ endif }
| %{ endif }
| %{ if couponTypeIs couponEntity CouponTypeGift }
| ...
| %{ endif }
| %{ if couponTypeIs couponEntity CouponTypeSet }
| ...
| %{ endif }
| %{ if couponTypeIs couponEntity CouponTypeOther }
| ...
| %{ endif } There are three annoying things about this:
Here's how I would rewrite it with
| %{ if null couponEntities }
| No Coupons
| %{ else }
| %{ forall couponEntity <- couponEntities }
| %{ with coupon <- entityVal couponEntity }
| %{ with couponKey <- entityKey couponEntity }
include _couponSimple
| %{ endwith }
| %{ endwith }
| %{ endforall }
| %{ endif }
.couponSimple
a.card(href="/store/coupon/\#{ fromSqlKey couponKey }")
.annotatedImageGroup
img.annotatedImageGroup-image(src=require("../img/dummy.jpg") alt="\#{ couponTitle coupon }")
span.annotatedImageGroup-annotation 画像は一例です
.card_body
.couponSimple_abstraction
h2.couponSimple_abstraction-store \#{ couponTitle coupon }
.couponSimple_abstraction-summary
| %{ case couponType coupon }
| %{ of CouponTypeDiscount }
| %{ maybe percent <- couponDescountPercent coupon }
span.couponSimple_abstraction-summary-sub \#{ percent }% OFF
| %{ endmaybe }
| %{ maybe minPrice <- couponDiscountMinimumPrice coupon }
span.couponSimple_abstraction-summary-main \#{ minPrice }円
| %{ endmaybe }
| %{ of CouponTypeGift }
| ...
| %{ of CouponTypeSet }
| ...
| %{ of CouponTypeOther }
| ...
| %{ endcase} Example 2Here's an example from | %{if isJust maybeCouponEntity}
.store
.store_editBtn
a.btn.outerBtn(href="/store/coupon/\#{fromSqlKey (entityKey (fromJustEx maybeCouponEntity))}/edit") クーポン情報編集
include _coupon_id
| %{else}
| No coupon info.
| %{endif} And here is part of .coupon
.card
.card_header
h2.card_header_text %{if isJust maybeStoreEntity}\#{ storeName entityVal) maybeStoreEntity}%{else}(no title)%{endif}
.card_header_icon
.icon.icon-fav.checkableIcon
input#js-fav-3.checkableIcon-check.js-fav(type="checkbox" data-coupon-id="\#{fromSqlKey (entityKey (fromJustEx maybeCouponEntity))}")
label.checkableIcon-icon(for="js-fav-3")
.annotatedImageGroup
img.annotatedImageGroup-image(src=require("../img/dummy.jpg") alt="七輪焼き肉・安安")
span.annotatedImageGroup-annotation 画像は一例です
.card_body
.card_body_title
| \#{couponTitle (entityVal (fromJustEx maybeCouponEntity))}
.card_body_summary.highlightedBlock
| %{ if couponTypeIs (fromJustEx maybeCouponEntity) CouponTypeDiscount }
| %{ if isJust (couponDiscountPercent (entityVal (fromJust maybeCouponEntity))) }
span.highlightedBlock-sub \#{ fromMaybe 0 (couponDiscountPercent (entityVal (fromJust maybeCouponEntity))) }% OFF
| %{ endif }
| %{ if isJust (couponDiscountMinimumPrice (entityVal (fromJust maybeCouponEntity))) }
span.highlightedBlock-main \#{ fromMaybe 0 (couponDiscountMinimumPrice (entityVal (fromJust maybeCouponEntity))) }円
| %{ endif }
| %{ endif } This code would also be slightly easier to write with Here is how I would rewrite it:
| %{ maybe couponEntity <- maybeCouponEntity }
| %{ with couponKey <- entityKey couponEntity }
| %{ with coupon <- entityVal couponEntity }
.store
.store_editBtn
a.btn.outerBtn(href="/store/coupon/\#{fromSqlKey couponKey}/edit") クーポン情報編集
include _coupon_id
| %{ endwith }
| %{ endwith }
| %{ nothing }
| No coupon info.
| %{ endmaybe }
.coupon
.card
.card_header
h2.card_header_text \#{maybe "(no store title)" (storeName . entityVal) maybeStoreEntity}
.card_header_icon
.icon.icon-fav.checkableIcon
input#js-fav-3.checkableIcon-check.js-fav(type="checkbox" data-coupon-id="\#{fromSqlKey couponKey}")
label.checkableIcon-icon(for="js-fav-3")
.annotatedImageGroup
img.annotatedImageGroup-image(src=require("../img/dummy.jpg") alt="七輪焼き肉・安安")
span.annotatedImageGroup-annotation 画像は一例です
.card_body
.card_body_title
| \#{couponTitle coupon}
.card_body_summary.highlightedBlock
| %{ case couponType coupon }
| %{ of CouponTypeDiscount }
| %{ maybe percent <- couponDiscountPercent coupon }
span.highlightedBlock-sub \#{percent}% OFF
| %{ endmaybe }
| %{ maybe minPrice <- couponDiscountMinimumPrice coupon }
span.highlightedBlock-main \#{minPrice}円
| %{ endmaybe }
| %{ of CouponTypeGift }
| ...
| %{ of CouponTypeSet }
| ...
| %{ of CouponTypeOther }
| ...
| %{ endcase } I think having But maybe there is some way of writing the above templates by making use of pugs features so it is easier to read/write? |
Thanks for real examples, @cdepillabout.
1.
|
Okay, that makes sense. Using the Here's an example from above using the | %{ maybe couponEntity <- maybeCouponEntity }
| %{ with couponKey <- entityKey couponEntity }
| %{ with coupon <- entityVal couponEntity }
.store
.store_editBtn
a.btn.outerBtn(href="/store/coupon/\#{fromSqlKey couponKey}/edit") クーポン情報編集
include _coupon_id
| %{ endwith }
| %{ endwith }
| %{ nothing }
| No coupon info.
| %{ endmaybe } It could be rewritten like this using just the | %{ case maybeCouponStuff }
| %{ of Just (couponKey, coupon) }
.store
.store_editBtn
a.btn.outerBtn(href="/store/coupon/\#{fromSqlKey couponKey}/edit") クーポン情報編集
include _coupon_id
| %{ of Nothing }
| No coupon info.
| %{ endcase } However, here's one example from one of the original documents (using just the | %{ if isJust (couponDiscountPercent coupon) }
span.couponSimple_abstraction-summary-sub \#{ fromJust (couponDiscountPercent coupon) }% OFF
| %{ endif } Using the | %{ maybe percent <- couponDiscountPercent coupon }
span.couponSimple_abstraction-summary-sub \#{percent}% OFF
| %{ endmaybe } However, using the | %{ case couponDiscountPercent coupon }
| %{ of Just percent }
span.couponSimple_abstraction-summary-sub \#{percent}% OFF
| %{ of Nothing }
| %{ endcase } This is more verbose than just having a Of course, you could write it without the | %{ case couponDiscountPercent coupon }
| %{ of Just percent }
span.couponSimple_abstraction-summary-sub \#{percent}% OFF
| %{ endcase } Can you think of a better way to write it than this? ↑ The downside of the @arowM Do you want to implement the |
I agree using I believe the important thing we have to consider when we decide to accept a new syntax or not is:
I think that if In general, adding new feature to a library is easy, but removing is hard because removing loses backward compatibility. @cdepillabout, if you have any thought that
Feel free to implement them. I'm so happy if you do so. |
Okay, that sounds good.
I agree that the So I agree that for now we shouldn't add the
I'll start working on it today. |
I just submitted PR #13 adding support for the Tomorrow I'll work on adding support the @arowM I had a question for you. How do you go about actually checking the code that has been generated when you are doing development? For example, when adding support for the I know about the |
Great, @cdepillabout . I'll check the PR later. |
To tell the truth, I'm not sure, too. @cdepillabout , If you have any good plan to check generated codes such as |
In #13, I've added an example executable that can easily be used to check the generated Haskell code. I'll use it when making sure that I've implemented the |
By the way, for testing this sort of thing, I suggest looking at
tasty-golden. It lets you test output against "golden", known-correct
output. Then you can build some examples, check them manually, and save
the results to do the tests automatically in the future.
…On Fri, Jan 13, 2017 at 10:26:40PM -0800, Kadzuya OKAMOTO wrote:
> How do you go about actually checking the code that has been generated when you are doing development?
To tell the truth, I'm not sure, too.
I only check the parsed types (`Control` and `Doc`) are correct or not in my hands, and trust `doctest` tests.
But it might not so important to check template-haskell-generated codes, because the core functions about template-haskell are copied from mature `Hamlet` module.
--
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
#9 (comment)
|
Thanks for the suggestion @chreekat! |
I've created a short blog post and github repo explaining how to use https://functor.tokyo/blog/2017-01-16-looking-at-generated-template-haskell This is spurred by the discussion for #13. |
I've released v1.0.3.0, which contains commits about |
Thanks, I'll close this issue! |
Would it be possible to add in the
maybe
andwith
control statements?http://www.yesodweb.com/book/shakespearean-templates#shakespearean-templates_maybe
http://www.yesodweb.com/book/shakespearean-templates#shakespearean-templates_with
It would also be nice to have a
case
statement, but that can be easily worked around withif
.http://www.yesodweb.com/book/shakespearean-templates#shakespearean-templates_case
These additional statements would make my current work (blueimpact/kucipong#77) on
kucipong
much easier.I can try implementing these if you'd like!
The text was updated successfully, but these errors were encountered: