{"id":133,"date":"2019-09-06T14:29:21","date_gmt":"2019-09-06T12:29:21","guid":{"rendered":"http:\/\/www.mbarsinai.com\/blog\/?p=133"},"modified":"2019-09-06T14:29:21","modified_gmt":"2019-09-06T12:29:21","slug":"psps","status":"publish","type":"post","link":"https:\/\/www.mbarsinai.com\/blog\/2019\/09\/06\/psps\/","title":{"rendered":"PSPS"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">At <a href=\"http:\/\/codeworth.io\">CodeWorth.io\u00a0<\/a>we create many web applications. Unless there&#8217;s a very compelling reason not to, we&#8217;re using the Scala flavor of <a href=\"https:\/\/www.playframework.com\">Play Framework<\/a>, which we find performant, fun to work with, and generally easy to maintain (static typing FTW! There. I&#8217;ve said it.).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now, Play is a very non-opinionated framework that&#8217;s happy to work with multiple database servers,  front-end kits, etc. It&#8217;s great since it provides us with the flexibility a software studio like us needs. On the flip side, though, we found ourselves re-implementing various functionalities, such as nav-bars, page layouts, and logins (including &#8220;forgot password&#8221; flow and such). The textbooks say that re-implementing functionality is wrong. That&#8217;s only partially right &#8211; when you implement a functionality for the fourth time, you&#8217;re doing a much better job at it. But enough is enough &#8211; one would also like to write some new functionality from time to time.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Enter <a href=\"https:\/\/github.com\/codeworth-gh\/PSPS\">PSPS<\/a>. This is a very opinionated application seed. We built it by collecting our best implementations, and then cleaning and brushing them up one more last final time (hmm,  actually, we could improve this a bit by&#8230;) . PSPS is based on technologies we found to be reliable, and easy to work with and extend. Nothing fancy or surprising, really: <a href=\"https:\/\/www.postgresql.org\">PostgreSQL<\/a>, <a href=\"https:\/\/getbootstrap.com\/\">Bootstrap4<\/a>, and <a href=\"http:\/\/slick.lightbend.com\">Slick<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Out of its proverbial box, PSPS supports many features common to web applications:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>User management<\/li><li>Public and user-only sections<\/li><li>Navigation bars (including menus, and created using type-safe Scala code)<\/li><li>Database connectivity<\/li><li>UI Components and functionality (paging, page headers, buttons, JS alerts&#8230;)<\/li><li>Page templates that support localization, CSRF, informationals, etc.<\/li><li>Basic localization<\/li><li>Ajax functionality (wrapping Play&#8217;s <a href=\"https:\/\/www.playframework.com\/documentation\/2.7.x\/JavaJavascriptRouter#Javascript-Routing\">JS Routers<\/a>)<\/li><li>Scripts for deploying on UNIX boxes<\/li><li><a href=\"https:\/\/psps-play-app.netlify.com\/\">Documentation<\/a> (yay AsciiDoc and <a href=\"https:\/\/antora.org\">antora<\/a>)<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">We have been testing PSPS internally for a while now, and believe it&#8217;s ready human consumption. It might even be good for said human, e.g. if they&#8217;re a part of the Play Framework community.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So feel free to try it out &#8211; it&#8217;s open sourced under Apache v2.0. We&#8217;re happily accepting improvements, suggestions, and pull-requests. Hopefully, together we can get the Play community an excellent application seed, so we can all focus on writing new things.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"625\" height=\"432\" loading=\"lazy\" src=\"https:\/\/i0.wp.com\/www.mbarsinai.com\/blog\/wp-content\/uploads\/2019\/09\/Screen-Shot-2019-09-06-at-14.32.05.png?resize=625%2C432\" alt=\"\" class=\"wp-image-134\" srcset=\"https:\/\/i0.wp.com\/www.mbarsinai.com\/blog\/wp-content\/uploads\/2019\/09\/Screen-Shot-2019-09-06-at-14.32.05.png?resize=1024%2C708&amp;ssl=1 1024w, https:\/\/i0.wp.com\/www.mbarsinai.com\/blog\/wp-content\/uploads\/2019\/09\/Screen-Shot-2019-09-06-at-14.32.05.png?resize=300%2C207&amp;ssl=1 300w, https:\/\/i0.wp.com\/www.mbarsinai.com\/blog\/wp-content\/uploads\/2019\/09\/Screen-Shot-2019-09-06-at-14.32.05.png?resize=768%2C531&amp;ssl=1 768w, https:\/\/i0.wp.com\/www.mbarsinai.com\/blog\/wp-content\/uploads\/2019\/09\/Screen-Shot-2019-09-06-at-14.32.05.png?resize=624%2C431&amp;ssl=1 624w, https:\/\/i0.wp.com\/www.mbarsinai.com\/blog\/wp-content\/uploads\/2019\/09\/Screen-Shot-2019-09-06-at-14.32.05.png?w=1107&amp;ssl=1 1107w\" sizes=\"auto, (max-width: 625px) 100vw, 625px\" \/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>At CodeWorth.io\u00a0we create many web applications. Unless there&#8217;s a very compelling reason not to, we&#8217;re using the Scala flavor of Play Framework, which we find performant, fun to work with, and generally easy to maintain (static typing FTW! There. I&#8217;ve said it.). Now, Play is a very non-opinionated framework that&#8217;s happy to work with multiple [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"nf_dc_page":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"","footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[1],"tags":[6,13,16],"class_list":["post-133","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-play","tag-scala","tag-webdev"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/s3NnQg-psps","_links":{"self":[{"href":"https:\/\/www.mbarsinai.com\/blog\/wp-json\/wp\/v2\/posts\/133","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mbarsinai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mbarsinai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mbarsinai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mbarsinai.com\/blog\/wp-json\/wp\/v2\/comments?post=133"}],"version-history":[{"count":3,"href":"https:\/\/www.mbarsinai.com\/blog\/wp-json\/wp\/v2\/posts\/133\/revisions"}],"predecessor-version":[{"id":137,"href":"https:\/\/www.mbarsinai.com\/blog\/wp-json\/wp\/v2\/posts\/133\/revisions\/137"}],"wp:attachment":[{"href":"https:\/\/www.mbarsinai.com\/blog\/wp-json\/wp\/v2\/media?parent=133"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mbarsinai.com\/blog\/wp-json\/wp\/v2\/categories?post=133"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mbarsinai.com\/blog\/wp-json\/wp\/v2\/tags?post=133"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}