I'm working on a JavaScript app and have so far entered all my strings as plain text.
This is starting to feel really hacky (I'm used to gettext) so I'd prefer to wrap them all in something like {{translatable_string}} and have a gulp task just search/replace them all during the build step.
So, my question is; is there a generic (no framework-specific like angular-gettext or something like that) gettext replacer out there?
Obviously it doesn't even have to be connected to JavaScript in any way, you should be able to run it on any file type and have {{translatable_string}}:s be translated.
You may want to look into using gulp-replace. As they explained in this answer, you should be able to use it to find and replace any string that you want in the stream.
I suggest a database of strings for your translations if dynamic generation of page content is possible for your app. Starting with English or whichever is normal but the need to localize content is a tough issue without a robust system. A simple MongoDB table can be used to store the content, and when the app needs an interface it can be loaded with the right localized strings. As a for instance:
if(err) alert("Please turn off caps lock");
could become:
if(err) alert(Please_turn_off_caps_lock.English);
If you are needing to build static pages with gulp, a database in conjunction with gulp-replace sounds interesting. Using gulp-data to call up and package the strings, you can then feed it to gulp-replace and alter the files. The extensible nature of databases or document stores enable you to expand your localization without hacking on individual files or trees all the time.
Try gulp-gettext-parser.
var gettext = require("gulp-gettext-parser");
var rename = require("gulp-rename");
gulp.task("gettext", function() {
return gulp.src("src/**/*.js")
.pipe(gettext())
.pipe(rename("bundle.po"))
.pipe(gulp.dest("dist/"));
});
Perhaps what you need is mustache.js, take a look: https://github.com/janl/mustache.js/
I'm not used to work with mustache, but I had to do some updates in a project done with it, and I was surprised the capabilities it have.
If you're familiar with jade (now renamed to pug), you'll find is something similar but at the end, you're not forced to generate only html files, you cand generate any kind of text file.
This blog could be helpful to understand the differences between some other templating languages over Nodejs: https://strongloop.com/strongblog/compare-javascript-templates-jade-mustache-dust/
Related
I have been recently been working with Laravel, and Artisan has several useful make commands that generates php from template stubs on the fly based off a class name, as well as allowing for custom make commands to speed things up.
Short of copy-pasting, there an easy tool that lets me generate plain JS in a similar way based on a templates that allows me to specify some variables to be replaced, then generated in my project?
The ultimate goal of mine for this project is to run a single terminal command with some arguments that generate all the files I need (at least 8-10 PHP files, as well as around 4 JS files), all put into the right directories that lets me do minimal "plugging in" so I can start using them right away. I can chain custom artisan commands, but the next step is getting some kind of terminal JS generator. The nature of the project is that there is approx. 12-14 files that need to be generated and generically filled in before being able to interface with a database table and the front end, so you can understand why I want to do this.
You can do it with bash like this
#!/bin/bash
file_location=path/to/dir/$1.js
if [ -e $1 ]; then
echo "File $1.js already exists!"
else
cat > $file_location <<EOF
let hi = '$2'
console.log(hi)
EOF
fi
$1 is the filename and $2 is another parameter you can pass to the script to be written in the js file.
I would look at hygen. I don't know what your output files are supposed to look like, but hygen allows you to create your own templates and generators. This has a relevant code snippet that displays some JS code. I can't give any advice beyond that as I've not used it thus far.
If this is looking like a bit too much, you can always use VS Code's templates to build up a base, but you won't have any params. A VS Code extension could overcome that I'd guess, but then you're not within a cli.
I have an HTML file with some Javascript and css applied on.
I would like to duplicate that file, make like file1.html, file2.html, file3.html,...
All of that using Javascript, Jquery or something like that !
The idea is to create a different page (from that kind of template) that will be printed afterwards with different data in it (from a XML file).
I hope it is possible !
Feel free to ask more precision if you want !
Thank you all by advance
Note: I do not want to copy the content only but the entire file.
Edit: I Know I should use server-side language, I just don't have the option ):
There are a couple ways you could go about implementing something similar to what you are describing. Which implementation you should use would depend on exactly what your goals are.
First of all, I would recommend some sort of template system such as VueJS, AngularJS or React. However, given that you say you don't have the option of using a server side language, I suspect you won't have the option to implement one of these systems.
My next suggestion, would be to build your own 'templating system'. A simple implementation that may suit your needs could be something mirroring the following:
In your primary file (root file) which you want to route or copy the other files through to, you could use JS to include the correct HTML files. For example, you could have JS conditionally load a file depending on certain circumstances by putting something like the following after a conditional statement:
Note that while doing this could optimize your server's data usage (as it would only serve required files and not everything all the time), it would also probably increase loading times. Your site would need to wait for the additional HTTP request to come through and for whatever requested content to load & render on the client. While this sounds very slow it has the potential of not being that bad if you don't have too many discrete requests, and none of your code is unusually large or computationally expensive.
If using vanilla JS, the following snippet will illustrate the above:
In a script that comes loaded with your routing file:
function read(text) {
var xhr=new XMLHttpRequest;
xhr.open('GET',text);
xhr.onload=show;
xhr.send();
}
function show() {
var text = this.response;
document.body.innerHTML = text;//you can replace document.body with whatever element you want to wrap your imported HTML
}
read(path/to/file/on/server);
Note a couple of things about the above code. If you are testing on your computer (ie opening your html file on a browser, with a path like file://__) without a local server, you will get some sort of cross origin request error when trying to make an XML request. To bypass this error, either test your code on an actual server (not ideal constantly pushing code, I know) or, preferably, set up a local testing server. If this is something you would want to explore, its not that difficult to do, let me know and I'd be happy to walk you through the process.
Alternately, you could implement the above loading system with jQuery and the .load() function. http://api.jquery.com/load/
If none of the above solutions work for you, let me know more specifically what it is that you need, and I'll be happy to give a more useful/ relevant answer!
We use DNN and often need to pass a few context specific values (like page id or module-on-page-id) into an AngularJS app. We've developed our own conventions how to do this, but would like to hear from others how they approach this to find a best practice.
So basically the situation is that the server-page has information needed by the JS. Using WebAPI is not an option, as these values are known in the page, but not in a separate request. Things I've seen so far have been:
Use in-view-razor like href="#Tab.TabId/{{...}}" (I don't like this)
Place the values in the ng-init like ng-init="config = { prop1: '#Tab.TabId' }"
Create a separate <script> tag where we generate a module on the fly containing these values so angular.module("config", []).constant('prop1', '#Tab.TabId')
Create a json with razor in the page somewhere and inject all of it as a module into the app using a generic code which does the same as #3, just with cleaner code re-use.
I've seen all these and have also used all. Currently we avoid #1 as we believe it's not good to mix templating languages and because it doesn't allow externalizing parts of the view. So basically we use #2 as for quick-and-simple (and a bit dirty) + #3/#4 for larger projects.
Do you have a better way, or which way would you prefer?
We are using variant #4.
This has the advantage that the JSON defines the exact interface for the config needed by the JS module. And Razor is great to generate URLs using #Url.Action.
we use NewtonSoft and do JSONConvert.SerializeObject(ObjectName) and then pass it over as a Session from the controller and then use #Html.Raw(ObjectName) and its a JSON Object that can be utilized easily in javascript...
Been trying to figure out a solution to internationalize a shopify store. Would really like to use JS or jQuery and switch languages instantly/client side without a reload using JSON-files for storing all language snippets..
There are a couple of really smart options (like localizejs.com), but they are rather expensive over time. Ideally we do not even need a super fancy backend and wouldn't mind "just" editing the language-files manually.
JSON could look like this:
{
"english": {
"Cart":"Warenkorb",
"Products":"Produkte",
"Contact":"Contact"
}
We appreciate any solution you can recommend! We need to be able to replace strings that contain elements like "href" as well though:
<div class="lang“>Replace <a href="#“>a Link</a></div>
How is this tackled usually?
Nowadays people are trying jQueryi18n plugin. May be you can check whether it can suffice your requirements. Its minified version size is upto 5KB. Its very easy to use in your project.
http://www.SiteTran.com/ will enable you to switch languages on the client side, and it's free. It also can provide usable SEO urls (for your HREF's) and it only requires a snippet of javascript for integration.
If you want to do it on your own, you can just simply a JSON file with all of the translations and then with javascript load the text based upon the language.
I want to render some static files (*.js in particularly) using Django template variables. I believe this is a common use-case, especially when doing anything AJAX-y; I don't want to hardcode AJAX urls in my .js files any more than I want to hardcode them in my .html files. Buuuut of course I don't want those static files to have to run through the template engine at every client request because this will be slow. I am referring to things like URLs (which do not change after compile/deploy) or static (non-db) model attributes. (I suppose there are use cases where these things might be changed at run-time - this is Python, after all- but I think they are uncommon). For some possible template variables (e.g. model fields), of course the file must be rendered at the time of the client request, but this is not what I'm talking about.
So wouldn't it make sense to render some of my static files through the template engine, for a subset of possible template variables, perhaps at the same time as collectstatic?
As far as I can tell this is not currently the case. To be clear, what I am looking for is a solution to render static files through the template engine at compile/deploy-time so that at "client-request-time" they are in fact plain old static files.
Such an approach would avoid these hacks:
DRY URLs in Django Javascript
Using the Django URL Tag in an AJAX Call
Disclaimers:
Yes I know there are template engines out there for javascript (mustache, handlebars, prototype, etc). Why should I add another template engine to the stack when Django already has one? Plus the syntax collides! That seems silly.
This looks like it takes a crack at it, but it's complicated and not fully implemented.
So:
Is there a solution out there that I am missing?
If not, is there a way to hook into collectstatic (like a pre-collectstatic hook) that would allow one to render certain static files through the template engine before "collecting" them?
EDIT:
No responses yet...is this a really dumb question, and I'm missing something obvious? If so...go ahead and let me know...
There are several frameworks for Django for same purpose: django-pipeline, django-assets, and etc. which integrates different static files processing strategies, with varying degrees of difficulty configuring.
I use an external tool - Grunt (it requires node.js) - for asset post-processing after collectstatic. It is easier and has a lots of plugins for any purpose (source validation, css/js/images minification, merging, testing and etc.).
It is possible to hook in collectstatic by a custom static files storage with overrided post_process method.
example/settings.py
STATIC_ROOT = 'assets'
STATICFILES_STORAGE = 'example.storage.MyStaticFilesStorage'
example/storage.py
import os
from django.contrib.staticfiles.storage import StaticFilesStorage
from django.core.files.base import ContentFile
from django.template import Template, Context
class MyStaticFilesStorage(StaticFilesStorage):
def post_process(self, paths, dry_run=False, **options):
# don't even dare to process the files if we're in dry run mode
if dry_run:
return
js_template_data = {'foo': 'bar'} # template variables
js_template_extension = '.jst'
js_extension = '.js'
for original_name, (storage, path) in paths.items():
processed = False
saved_name = original_name
original_path, original_extension = os.path.splitext(original_name)
if original_extension == js_template_extension:
with storage.open(path) as original_file:
saved_name = original_path + js_extension
if hasattr(original_file, 'seek'):
original_file.seek(0)
original_source = original_file.read()
c = Context(js_template_data)
saved_source = Template(original_source).render(c)
self.delete(saved_name)
self.delete(original_name)
self._save(saved_name, ContentFile(saved_source))
processed = True
yield original_name, saved_name, processed
A completely different way to approach the problem would be to ask if you really need to get those URLs in javascript--instead, can the Javascript get the URLs from things like data attributes in your HTML?
In other words, you might have wanted:
homepage.html:
<div id="pop-up-modal">pop me up</div>
homepage.js:
$("#pop-up-modal").click(function {
$.ajax("{% url 'some-class-name %}")
...
});
When it can often be more straightforward to do something like:
homagepage.html:
<div id="pop-up-modal" data-popurl="{% url 'some-class-name' %}">pop me up</div>
homepage.js:
$("#pop-up-modal").click(function {
$.ajax($(this).data('popurl'))
...
});
I think that django-medusa would suit your needs.
By setting up a renderer and using the disk based backend, generating the static files would be as easy as:
django-admin.py staticsitegen
You aren't crazy. I was frustrated by this as well and found myself hacking something together for each new Django project I tackled. I think the reason for the lack of direct solutions is that this is mega-drought bone DRY. Its super easy to just hard code these things and call it day. This and the two most common use cases for this involve generating code in one language from code in another which tends to be viewed as suspect.
I've recently published a new Django package django-render-static that solves this problem generically. It piggy-backs on Django's existing template engine infrastructure. A management command called render_static should be run before collectstatic. This command will look for templates registered in settings (or passed as arguments) and render them to your static file location on disk. They're then available for whatever normal static file packaging pipeline you have configured.
I'm sure there are more use cases, but the two most common I've found are providing a reverse utility in static JavaScript thats equivalent to Django's and auto-translating define-like python structures (i.e. choice fields) into JavaScript. The app provides template tags that do both.
The JavaScript url reversal code is guaranteed to be functionally equivalent to Django's reverse function. I won't bother plopping example code down here because it's been well documented.