is this a good use for django internationalisation - django

I am working on a django website/project, it has already been internationalised/localised to us-english, gb-english and mandarin.
It is deployed with same codebase except for the settings config which states what lang to use. Some deployments are mandarin only, others are us-english.
The client now has a requirement to change some of the language used within a gb-english version for a specific deployment. My main goal is not to duplicate things and I think I can get what I need out of django 18n.
Basically, I am looking to find if i can or should use django i18n to handle:
'Welcome' on deployA
'Oh hai' on deployB,
even though they're still both gb-english based sites, I feel I should be able to say that deployA will use 'en_GB' and deployB would use 'en_GB_special'.
I suppose it's the fact that I want to use a non-standard i18n name/code that is making me wonder if I should do this, or if I am approaching this in the wrong manner.

I would only create a new language if you're intending to maintain two translations. If the new site will need to stay in sync with en_GB and/or you intend to use the customization in another language then I think you'd be better off creating new messages, adding a string for them to en_GB and add a flag to your application to switch the feature for your feline client.

Related

Vue: keep linebreaks and indentation intact

I'm working on a Vue app that (obviously ;)) loads Vue templates, lets the user fill in content and then export the markup of those templates/components. However, all linebreaks and indentation are lost in the process.
Is there any way to make Vue keep that information? So far at least I achieved to keep (conditional) comments via the
comments: true
option. There are several other options like expectHTML or shouldDecodeNewlines, but they don't seem to be documented and none of them seem to help me accomplish what I want.
The problem is that we're in part handling email templates (meh...) and it's a client requirement that "input === output" (well, markup-wise), because indeed a space or linebreak here or there can indeed make a difference in fussy mail clients. So simply running the markup through a beautifier is not an option.
I know, I know... That's not really what Vue is made for, and markup !== DOM... But the tool itself is written in Vue and I love to currently be able to use all the magic of Vue syntax inside the templates being processed as well.
If all else fails, I might have to resort to using mustache (or any other template system - recommendations welcome) - but I would really like to keep the templating as it is right now, for the aforementioned reasons.

Ember-CLI - How to access application classes

Previously when I developed ember application I used App as my global object and every class was stored in this big object.
Like this
window.App.MyModel = Em.Object.extend({});
And in the browser console, I was able to do
App.MyModel.create();
So it was really easy for me to access MyModel class.
Now I started experiments with Ember-CLI, I don't have much experience with this kind of tools. I followed the documentations and I created my model Service like this.
var Service = Ember.Object.extend({});
export default Service
But now, how to access Service class from browser console?
Only way I found was:
App.__container__.resolve('model:service')
But I don't like it much. Is there better way? Btw, can you please explain how export works? Or is there some source (documentation, article) where I can study it?
Thanks a lot for response.
If you're aiming to have something available in most places throughout your application you'll typically want to register it on the container.
There are multiple ways to access the container, and you're correct in that the one you found was less than ideal. The running joke is "any time you directly access __container__ we need to add more underscores."
To directly control how things are registered on the container and injected into the container you typically want to use an initializer. Using initializers in ember-cli is super-easy, they're executed for you automatically.
Checking out the documentation you can see that you get access to the application's container as an argument which allows you to manipulate it in a safe manner.
Once you have access to the container you can use register and inject to make content easily available in particular locations. This was introduced here. One note, accessing things inside of the container from outside the context of your app (browser console) will require the usage of App.__container__ and that is the expected use pattern.
And the export you're running into is an ES6 module system construct, it's not Ember-specific. Playing with the ES6 module transpiler can give you a good sense of what goes in and what comes out in "we can do this today" type of JavaScript.
For ember 3.22, application classes can be accessed like so:
Ember.Namespace.NAMESPACES[1]._applicationInstances.values().next().value.lookup('service:state-events')
Note, you may need to modify the index in NAMESPACES[1] to be something other than 1. You can determine which namespace is your application when this returns true:
Ember.Namespace.NAMESPACES[1] instanceof Application
This approach is how ember-inspector accesses ember applications: https://github.com/emberjs/ember-inspector/blob/50db91b7bd26b12098cae774a307208fe0a47d75/ember_debug/main.js#L163-L168

Joomla 2.5 ― using administrator components controllers in frontent part of component

how can I use the controllers created at
/administrator/components/com_mycom/controllers/*
in
/components/com_mycom/mycom.php
In detail:
I have a »log« controller with an »add« method, and I would like to use this from the frontend. I one is not logged in in the backend the task is not executed and a 500 error rises. So just would like to include the backend controllerpath in the frontend, so that JController::getInstance( 'Mycom' ) still works.
Greetings…
EDIT:
After a long time of searching I could find a more or less undocumented Parameter of the:
JController::getInstance() method, namely the second one: $config = array(). Going through the source code I found out that there is one key of the »config-array« that is of interest, which is: »base_path«.
The call of:
JController:getInstance( 'Mycom, array('base_path' =>JPATH_ADMINISTRATOR.DS.'components'.DS.'com_mycom')' );
always delivers the backend controller and one can use them safely in the frontend, BUT one must take care that then also the views are taken from the backend side of the component. In my case, I just use it to make ajax-calls so it does not matter, but one needs to be careful with using this method when planning to create »frontend views« with »backend controller«.
Greetings…
I had recently a similar problem where I wanted to use the whole CRUD system form back-end also in front-end.
This is the method that worked for me (and I am not saying that this is recommended or best practice):
I've just modeled the folders / file structure from backend. PHP files contained something like:
require_once JPATH_ADMINISTRATOR . '/components/com_mycom/controllers/log.php';

Running multiple sites on the same python process

In our company we make news portals for a pretty big number of local newspapers (currently 13, going to 30 next month and more in the future), each with 2k to 100k page views/day. Since we are evolving from a situation where each site was heavily customized to one where each difference is a matter of configuration or custom template, our software is already pretty much the same for all sites. Right now our deployment strategy is one gunicorn instance for each site (with 1-17 workers each, depending on the site traffic), on a 16-core server and 12GB RAM. The problem with this setup is that each worker (regular pre-forked gunicorn) takes 110MB, whether its being used or not. Now with the new sites we would need to add more RAM to serve not that much many requests, so basically it doesn't scale. Also, since we are moving from this model where each site is independent, each site has its own database and I quite like it that way, especially since we are using relational databases (mysql, but migrating to pgsql), so its much easier to shard this way.
I'm doing some research and experimenting with running all sites on one gunicorn instance, so I could use the servers fully and add more servers behind a load balancer when it came to it. The problem is that django assumes in a lot of places that only one site is running per process, so for what I've thought of so far I'd have to implement:
A middleware that takes the HTTP_HOST from the request and places an identifier on a threadlocal variable.
A template loader that uses that variable to load custom templates accordingly.
Monkey patch django.db.model.Model, probably adding a metaclass (not even sure that's possible, but I think I would need it because of the custom managers we sometimes need to use) that would overwrite the managers for one that would first call db_manager(identifier) on the original manager and then call the intended method. I would also need to overwrite the save and delete methods to always include the using=identifier parameter.
I guess I would need to stop using inclusion_tag decorators, not a big problem, but I need to think of other cases like this.
Heavy and ugly patching of urlresolvers if I need custom or extra urls for each site. I don't need them now, but probably will at some point.
And this is just is what I came up with without even implementing it and seeing where it breaks, I'm sure I'd need many more changes for it to work. So I really don't want to do it, especially with the extra maintenance effort I'll need, but I don't see any alternatives and would love to learn that someone already solved this in a better way. Of course I could also stop using django altogether (I already have many reasons to do so) but that would mean a major rewrite and having two maintain two incompatible branches of the software until the new one reached feature parity with the django version, so to me it seems even worse than all the ugly hacks.
I've recently developed an e-commerce system with similar requirements -- many instances running from the same project sharing almost everything. The previous version of the system was a bunch of independent installations (~30) so it was pretty unmaintainable. I'm sure the requirements still differ from yours (for example, all instances shared the same models in my case), but it still might be useful to share my experience.
You are right that Django doesn't help with scenarios like this out of the box, but it's actually surprisingly easy to work it around. Here is a brief description of what I did.
I could see a synergy between what I wanted to achieve and django.contrib.sites. Also because many third-party Django apps out there know how to work with it and use it, for example, to generate absolute URLs to the current site. The major problem with sites is that it wants you to specify the current site id in settings.SITE_ID, which a very naive approach to the multi host problem. What one naturally wants, and what you also mention, is to determine the current site from the Host request header. To fix this problem, I borrowed the hook idea from django-multisite: https://github.com/shestera/django-multisite/blob/master/multisite/threadlocals.py#L19
Next I created an app encapsulating all the functionality related to the multi host aspect of my project. In my case the app was called stores and among other things it featured two important classes: stores.middleware.StoreMiddleware and stores.models.Store.
The model class is a subclass of django.contrib.sites.models.Site. The good thing about subclassing Site is that you can pass a Store to any function where a Site is expected. So you are effectively still just using the old, well documented and tested sites framework. To the Store class I added all the fields needed to configure all the different stores. So it's got fields like urlconf, theme, robots_txt and whatnot.
The middleware class' function was to match the Host header with the corresponding Store instance in the database. Once the matching Store was retrieved, It would patch the SITE_ID in a way similar to https://github.com/shestera/django-multisite/blob/master/multisite/middleware.py. Also, it looked at the store's urlconf and if it was not None, it would set request.urlconf to apply its special URL requirements. After that, the current Store instance was stored in request.store. This has proven to be incredibly useful, because I was able to do things like this in my views:
def homepage(request):
featured = Product.objects.filter(featured=True, store=request.store)
...
request.store became a natural additional dimension of the request object throughout the project for me.
Another thing that was defined on the Store class was a function get_absolute_url whose implementation looked roughly like this:
def get_absolute_url(self, to='/'):
"""
Return an absolute url to this `Store` or to `to` on this store.
The URL includes http:// and the domain name of the store.
`to` can be an object with `get_absolute_url()` or an absolute path as string.
"""
if isinstance(to, basestring):
path = to
elif hasattr(to, 'get_absolute_url'):
path = to.get_absolute_url()
else:
raise ValueError(
'Invalid argument (need a string or an object with get_absolute_url): %s' % to
)
url = 'http://%s%s%s' % (
self.domain,
# This setting allowed for a sane development environment
# where I just set it to ".dev:8000" and configured `dnsmasq`.
# The same value was also removed from the `Host` value in the middleware
# before looking up the `Store` in database.
settings.DOMAIN_SUFFIX,
path
)
return url
So I could easily generate URLs to objects on other than the current store, e.g.:
# Redirect to `product` on `store`.
redirect(store.get_absolute_url(product))
This was basically all I needed to be able to implement a system allowing users to create a new e-shop living on its own domain via the Django admin.

Best way to move API from CodeIgniter to Django

In the beginning we made a project using CodeIgniter and we had some controllers that were used to connect an external NAS to the database via it's web interface, to cut a long story short we had a bunch of URL that required an API key to have access to avoid general hackery from outside sources calling the API.
The API existed for various tasks the NAS had to do (manage orders, upload data/images etc.), so we had a few different controllers (ie. one for Orders, Images, etc.) So the API folder looked something like this:
controllers/apiv1/
orders.php
images.php
...
Something along the lines of this:
class Orders extends ApiController {
function Orders()
{
parent::ApiController();
}
function get_paid()
{
$shop = self::get_shop();
$this->load->model('order');
echo json_encode($this->order->by_status($shop->shop_id, Order::STATUS_PAID));
}
}
Where the ApiController just checked the APIKey against the Shop that it was trying to access.
Now we are moving the project to Django, and I was just wondering the be way to setup this api again. I was thinking of making an API app for the project and importing the models in to the views.py and make some functions for everything, my problem here is there a way to break everything up nicely (into separate files for each of the various things)? Or should I just have the views.py full of everything and worry about it in the urls.
Or is there a better way? If possible I would like to separate the api into versions like (api/v1, api/v2, etc.) so that we can just route the urls to the new api without affecting the old. This may come in handy if we have various NAS's using different versions of the API (Hard to explain why...)
You could try using something like Django Piston or Django-tastypie to quickly get something working. The big advantage over using normal Django views is that you get most of the CRUD and serialization to JSON/Yaml/XML done for you.
Tastypie comes with a built-in shared-secret key authentication mechanism, and it's not difficult to find the equivalent code for Piston.
EDIT: BTW, I've been working with both Piston and Tastypie recently. I find Tastypie is easier to setup and the code base looks cleaner. That said, it lacks some features (coming on 1.0 though) that makes it impossible for me to use it at the moment. Piston is very easy to shoehorn into whatever you need, but the code seems to be growing stagnant, the author doesn't seem to be very responsive about open issues and you'll probably end up having your own fork with the bugfixes you need for your application to work properly. Not an ideal situation.