Dynamically adding routes in compojure - dynamic

Hi guys : I have a "hierarchichal" styled site in compojure with a defroutes declaration like so :
(defroutes main-routes
(GET "/" [] (resp/redirect "/public/index.html")
(GET "/blog" [] (resp/redirect "/public/blogs/index.html")
(GET "/tools" [] (resp/redirect "/public/tools/index.html"))
I would like, however, for these pages to be more dynamic - that is, I would like the index.html page to be generated by scanning the contents of the /blog directory, and likewise, for the /tools route.
That is, in the end, I would like the routes to look like so :
(defroutes main-routes
(GET "/" [] (resp/redirect "/public/index.html")
(GET "/blog" [] (generate-index "/public/blog"))
(GET "/tools" [] (generate-index "/public/tools")))
Is there a simple roadmap for building dynamic paths through my site via compojure ?
More concretely ---- are there any suggestions on how to build a (generate-index) function which scans the inputted path and returns links to all files ? I assume that compojure might already have such a feature, given the recent rise of so many blogging platforms which are based on this type of idiom.

Doing most of what you said is fairly simple.
There are two things that you are going to want to look at in particular, as well as some general reading which will help you understand what's going on.
First, you are going to want to take a look at some form of HTML Templating tool. While it is possible to just build the necessary strings, things will be simpler if you use one. I've seen two different main styles for them, and which to chose depends on your tastes.
Hiccup is focused on taking Clojure data structures and transforming them into HTML
Enlive is focused on taking HTML template files and transforming them into the correct end form
For actually getting the list of files, consider using file-seq. Transform the file name into the appropriate post name and file, and then use that as data to generate the links to the pages.
The other thing you're going to want to learn more about is Compojure route templates and a little more on Ring Responses.
Compojure's route templates make it easy to pass in route parameters which you can then generate responses from. Following this is a simple example which serves a simple static html file using the html page name as the parameter.
(GET "/blog/:post" [post] (ring/file-response (str "/public/blogs/" post ".html")))
Finally, consider reading through the rest of the Compojure and Ring wikis. The Ring wiki gives some very good information on the core "how things work". The Compojure wiki provides some good examples on how to best make use of Compojure, which just focuses on providing an easy way - but far from the only way - to handle the routes and make the page generation for Ring easy.
Depending on where you want the site to go, I'd also consider taking a look at Noir, which is a framework that does a nice job at pulling together all the pieces and solving some common problems in the process.

Related

What is the recommended workflow for vue.js + i18n?

I have recently made the jump from developing using the Django framework to vue.js. One thing I am having a hard time wrapping my head around is the workflow for adding translations.
In Django, my workflow felt very intuitive:
Annotate my code with translation hooks.
Pull out the translation hooks into a .po (gettext) file
Translate the messages into the desired locale, i.e. do work in the .po file
Compile the .po file
In the context where all of my work needs to be translated, this workflow was very convenient and fool-proof.
I am excited about the move over to vue.js but I am afraid the difference in translation workflow might be a deal-breaker. Or perhaps, there is something I am missing? Here is my understanding of the vue.js/i18n workflow
Annotate my code with translation hooks. Unlike the Django process, I am using a Translation ID to link messages and translations.
Manually add those translation ids to a JSON file, e.g. en.json
Mirror that json file to that of a different locale, e.g., fr.json
I understand that I can use a tool like BabelEdit to manage the last step. While this seems like a great tool, it is the second step that I am really having a hard time getting my head around. Without a function like the django-admin/gettext makemessages this seems like it would be a tedious and inefficient task.
What am I getting wrong here? I imagine I am not the only one with these needs, so what are the translation workflows that are working for others developing with vue.js?
Thanks in advance.
I believe that you can use https://github.com/pixari/vue-i18n-extract on step 2. I think that BabelEdit can only help if you keep your translations as <i18n> section in your Vue components (in which case you will need https://github.com/intlify/vue-i18n-loader)

Using a static website generator with forms and data-driven content?

I am looking at using a static generator to generate up to hundreds of thousands of pages (on S3) of data-driven content from json or csv files, each of which has an html form that posts to an external API. Is this a feasible undertaking?
It depends on your requirements, but at minimum, you might even get away with a simple node program that uses fs to read/write. Going up the complexity spectrum, you might do with a Gulp setup. Going even further up the spectrum, you can use static website generator to read/write your data files (but that's probably worth the trouble only if you already know static generator and/or you will want to have a blog on S3 as well, driven by .MD files, besides hundreds of thousands of data-driven pages).
If going simple node script route, you would create your local application in a js file, run it through command line in node. It would generate thousands of pages locally, then you would upload them to S3. You can either use standard fallbacks or fancier way using promises (like using Bluebird). This way is the most manual but you have the most control over the result.
For the record, you could whip up a script in any programming language that you are proficient, like for example, PHP. JavaScript is popular these days, that's why I'm assuming you would use JS.
If going Gulp route, I imagine a custom function that reads data files from the location, parses their contents into an array, and writes the contents into files.
If going Hugo route, simply use data driven content reference, getCSV function. You'll still need to work in the context of a website, this means the more you stray off the website's setup, the more you'll have to fight Hugo.
As I mentioned, arguments against static website generator would be if you don't need the website part, only to perform operations on data and write files, it might stand in a way.
Hugo is a good option for thousands of files because it's fast.
Solution also depends on if your CSV files are going to change, or is it one-off thing; also how much automation you need. Gulp approach might be handy even if you go Hugo route.
So, yes, it is a very feasible undertaking.

Basics of i18next

Im new to i18n and when I typed it in the search bar i18next is in the top results.
I already did my research regarding i18n and how to use it. But it still not clear to me. All I know is that to be able to make your web app available to other language, you need to do a json file that contains the keys and value of your app, and you need to add a script for the i18n.
The rest is still confusing for me. This might sound a stupid question for you, but I just cant understand how it works.
1) Im not sure but based on my observation, you only create a json translation for those that have a value or text that will be shown in the page. Correct? Assuming in the html file, I have a text that is not inside a label or innerhtml, example:
<html>
<body>
**How are we going to translate this text? What key am I going to use?**
</body>
</html>
What do I need to do to translate this text?
2) What should we use as the key? id? class? tag? Because I've seen different examples and it uses different any of these. When is the right time to use these?
3) regarding the key-value pair, what if the pair is coming from the server? what's the syntax for this?
4) When do we need a multi line json?
i18n is a big topic, with a lot of solutions depending on what kind of web app you are trying to internationalize / localize. Unfortunately, i18next's documentation is not very good, and it has next to nothing in way of tutorials.
That said, you might be best off taking a look at the sample app on i18next.js's github repository here: https://github.com/jamuhl/i18next/tree/master/sample/static. It does give some examples of how i18next can be used to replace html text with localized versions of the same. To answer some of your questions:
There are a few ways of doing this. The sample script replaces much of the data by using the jQuery .text call -- something like this: $('#MyHTMLID').text($.t('ns.common:MyLocalizedTextForMyHTMLID'));. Any html inside the id "MyHTMLID" is replaced by the localized data for the key "MyLocalizedTextForMyHTMLID' by the i18next .t call.
A lot of these decisions are just convention. Keep it simple, be consistent.
Normally in a web app the json file is on the server, in a locales subdirectory of the directory where your html resides. Take a look at that i18next example for how it's laid out.
When you're first building your web app, use a multi-line json file to be able to troubleshoot. You can compress it later using something like http://jsonformatter.curiousconcept.com/.
Hope this helps get you started!

Knockout in Rails 3

if I'm using rails 3 which uses asset pipeline to compile all
Javascripts, does that mean I can have only one Knockout view model for my entire application? If not, how do I specify which view model is binded with which view? In the tutorial code, it looks like 1 view model is bound per page, but that doesnt work in rails since all JS are loaded upon first page load.
No, you do not need to include all javascript on every page! This is a very bad idea.
There are many methods for limiting javascript to a single page, you should pick one:
Method 1
Method 2
Method 3
Please, please, please do not try to load all your javascript on every single page.
Update (after your comment below):
I think you are confusing a few different things here.
First, even if you compile all your javascript into a single gzipped/uglified file, that still doesn't force you to use one knockout viewmodel for your entire application. That file can contain multiple viewmodels. They don't even need to know about each other.
Second, the way the rails pipeline works is by concatenating related or dependant javascript files together. It does this to reduce the number of requests the browser has to make to get the javascript it needs for each page. It doesn't necessarily mean all your javascript becomes one file. Just that the javascript for each page become one file. For more information, check out the Rails Asset Pipeline Documenation, it has a great explanation of how it works and how to use it properly.
Third, neither of these things mean you need to write all your javascript as if it were one file. In fact, this is a bad idea. You should seperate your javascript into relevant files by functionality. This allows them to be reusable, as well as eases development work.

Naming convention for assets (images, css, js)?

I am still struggling to find a good naming convention for assets like images, js and css files used in my web projects.
So, my current would be:
CSS: style-{name}.css
examples: style-main.css, style-no_flash.css, style-print.css etc.
JS:
script-{name}.js
examples: script-main.js, script-nav.js etc.
Images: {imageType}-{name}.{imageExtension}
{imageType} is any of these
icon (e. g. question mark icon for help content)
img (e. g. a header image inserted via <img /> element)
button (e. g. a graphical submit button)
bg (image is used as a background image in css)
sprite (image is used as a background image in css and contains multiple "versions")
Example-names would be: icon-help.gif, img-logo.gif, sprite-main_headlines.jpg, bg-gradient.gif etc.
So, what do you think and what is your naming convention?
I've noticed a lot of frontend developers are moving away from css and js in favor of styles and scripts because there is generally other stuff in there, such as .less, .styl, and .sass as well as, for some, .coffee. Fact is, using specific technology selections in your choice of folder organization is a bad idea even if everyone does it. I'll continue to use the standard I see from these highly respected developers:
src/html
src/images
src/styles
src/styles/fonts
src/scripts
And their destination build equivalents, which are sometimes prefixed with dest depending on what they are building:
./
images
styles
styles/fonts
scripts
This allows those that want to put all files together (rather than breaking out a src directory) to keep that and keeps things clearly associated for those that do break out.
I actually go a bit futher and add
scripts/before
scripts/after
Which get smooshed into two main-before.min.js and main-after.min.js scripts, one for the header (with essential elements of normalize and modernizr that have to run early, for example) and after for last thing in the body since that javascript can wait. These are not intended for reading, much like Google's main page.
If there are scripts and style sheets that make sense to minify and leave linked alone because of a particular cache management approach that is taken care of in the build rules.
These days, if you are not using a build process of some kind, like gulp or grunt, you likely are not reaching most of the mobile-centric performance goals you should probably be considering.
I place CSS files in a folder css, Javascript in js, images in images, ... Add subfolders as you see fit. No need for any naming convention on the level of individual files.
/Assets/
/Css
/Images
/Javascript (or Script)
/Minified
/Source
Is the best structure I've seen and the one I prefer. With folders you don't really need to prefix your CSS etc. with descriptive names.
For large sites where css might define a lot of background images, a file naming convention for those assets comes in really handy for making changes later on.
For example:
[component].[function-description].[filetype]
footer.bkg-image.png
footer.copyright-gradient.png
We have also discussed adding in the element type, but im not sure how helpful that is and could possibly be misleading for future required changes:
[component].[element]-[function-description].[filetype]
footer.div-bkg-image.png
footer.p-copyright-gradient.png
You can name it like this:
/assets/css/ - For CSS files
/assets/font/ - For Font files. (Mostly you can just go to google fonts to search for usable fonts.)
/assets/images/ - For Images files.
/assets/scripts/ or /assets/js/ - For JavaScript files.
/assets/media/ - For video and misc. files.
You can also replace "assets" with "resource" or "files" folder name and keep the name of it's subfolders. Well having an order folder structure like this isn't very important the only important is you just have to arrange your files by it's format. like creating a folder "/css/" for CSS files or "/images/" for Image files.
First, I divide into folders: css, js, img.
Within css and js, I prefix files with the project name because your site may include js and css files which are components, this makes it clear where files are specific for your site, or relating to plugins.
css/mysite.main.css css/mysite.main.js
Other files might be like
js/jquery-1.6.1.js
js/jquery.validate.js
Finally images are divided by their use.
img/btn/submit.png a button
img/lgo/mysite-logo.png a logo
img/bkg/header.gif a background
img/dcl/top-left-widget.jpg a decal element
img/con/portait-of-something.jpg a content image
It's important to keep images organized since there can be over 100 and can easily get totally mixed together and confusingly-named.
I tend to avoid anything generic, such as what smdrager suggested. "mysite.main.css" doesn't mean anything at all.
What is "mysite"?? This one I'm working on? If so then obvious really, but it already has me thinking what it might be and if it is this obvious!
What is "Main"? The word "Main" has no definition outside the coders knowledge of what is within that css file.
While ok in certain scenarios, avoid names like "top" or "left" too: "top-nav.css" or "top-main-logo.png".
You might end up wanting to use the same thing elsewhere, and putting an image in a footer or within the main page content called "top-banner.png" is very confusing!
I don't see any issue with having a good number of stylesheets to allow for a decent naming convention to portray what css is within the given file.
How many depends entirely on the size of the site and what it's function(s) are, and how many different blocks are on the site.
I don't think you need to state "CSS" or "STYLE" in the css filenames at all, as the fact it's in "css" or "styles" folder and has an extension of .css and mainly as these files are only ever called in the <head> area, I know pretty clearly what they are.
That said, I do this with library, JS and config (etc) files. eg libSomeLibrary.php, or JSSomeScript.php. As PHP and JS files are included or used in various areas within other files, and having info of what the file's main purpose is within the name is useful.
eg: Seeing the filename require('libContactFormValidation.php'); is useful. I know it's a library file (lib) and from the name what it does.
For image folders, I usually have images/content-images/ and images/style-images/. I don't think there needs to be any further separation, but again it depends on the project.
Then each image will be named accordingly to what it is, and again I don't think there's any need for defining the file is an image within the file name. Sizes can be useful, especially for when images have different sizes.
site-logo-150x150.png
site-logo-35x35.png
shop-checkout-button-40x40.png
shop-remove-item-20x20.png
etc
A good rule to follow is: if a new developer came to the files, would they sit scratching their head for hours, or would they likely understand what things do and only need a little time researching (which is unavoidable)?
As anything like this, however, one of the most important rules to follow is simply constancy!
Make sure you follow the same logic and patterns thoughout all your naming conventions!
From simple css file names, to PHP library files to database table and column names.
This is an old question, but still valid.
My current recommendation is to go with something in this lines:
assets (or assets-web or assets-www); this one is intended for static content used by the client (browser)
data; some xml files and other stuff
fonts
images
media
styles
scripts
lib (or 3rd-party); this one is intended for code you don't make or modify, the libraries as you get them
lib-modded (or 3rd-party-modified); this one is intended for code you weren't expected to modify, but had to, like applying a workaround/fix in the meantime the library provider releases it
inc (or assets-server or assets-local); this one is intended for content used server side, not to be used by the client, like libraries in languages like PHP or server scripts, like bash files
fonts
lib
lib-modded
I marked in bold the usual ones, the others are not usual content.
The reason for the main division, is in the future you can decide to server the web assets from a CDN or restrict client access to server assets, for security reasons.
Inside the lib directories i use to be descriptive about the libraries, for example
lib
jquery.com
jQuery
vX.Y.Z
github
[path]
[library/project name]
vX.Y.Z (version)
so you can replace the library with a new one, without breaking the code, also allowing future code maintainers, including yourself, to find the library and update it or get support.
Also, feel free to organize the content inside according to its usage, so images/logos and images/icons are expected directories in some projects.
As a side note, the assets name is meaningful, not only meaning we have resources in there, but meaning the resources in there must be of value for the project and not dead weight.
The BBC have tons of standards relating web development.
Their standard is fairly simple for CSS files:
http://www.bbc.co.uk/guidelines/futuremedia/technical/css.shtml
You might be able to find something useful on their main site:
http://www.bbc.co.uk/guidelines/futuremedia/