I have a Plone (4.0.1) site which requires changes in layout depending on the folder. Imagine a structure like:
University > Faculty A > Institute A1 > Person A11
> Person A12
> Institute A2 > Person A21
...
Now if I put all needed resources (custom css file, images, etc.) into the ZODB, pages for person A11 would automatically pick up a fac-image.gif located in the Faculty A folder.
However, to avoid confusion, I do not want to expose fac-image.gif to the users. (This is all part of the framework which they're not supposed to touch anyway.)
If I register a resource, I can access stuff with ++resource++theme.images/path, but no acquisition from parents is taking place, so ++resource++theme.images/facultyA/instituteA1/fac-image.gif won't find the image. Even worse, I have a separate directory structure to maintain now.
What I'm currently doing is hand-rolling a "best effort" traversal process through a file system directory view that will try to go down the path, just stay where it is if the subdirectory doesn't exist (i.e. the resource tree doesn't have a subdirectory for person A11; instead of yelling 404 I stay at institute A1), and then try to acquire back up. Some trickery is involved for portal_factory and views, and I'm pretty sure I've missed more.
So: that surely isn't the way one is supposed to do it, but what is?
Use CSS.
Simply tag your tag with classes based on the current section / faculty / aspect of your choice and alter your images based on those classes. Keep visual design separate from your content!
You can inspirate you from collective.phantasy that implements this use case for plone3 (change l&f for a folder container).
It seems to be so. I ended up registering a helper view that examines and mangles the context path and points it somewhere else into a file system directory view.
Related
I've been reading through the documentation, which is great, however I'm still not entirely sure the best way of creating a nested route in NextJS.
In my example I have modules that have nested lessons. Or in other words, my module could be a book and each lesson a chapter.
So, my current thought is to have my pages directory like so:
pages/modules/[mid]/lessons/[lid]
Pretty generic route path, but it feels off to create a dir path like this:
/Pages
--/modules
----[id].js
----/lessons
------[id].js
It seems very very coupled to modules. What happens if I want a different route to lead to lessons or if I make another page that just GETs all lessons regardless of modules. What then?
Would the ex below be a normal/suitable design? Seems a bit messy having all these tucked away places to have lessons appear. I'm sure I'll get a better grip of it soon enough. Just want to make sure I'm not going well off the beaten path.
/Pages
--/modules
----[id].js
----/lessons
------[id].js
--/lessons
----index.js
Thanks!
If you want to nest the entire content of a directory under a route parameter you can name the directory itself between brackets. Then all the content under moduleId directory will receive a module Id.
You can have
/Pages
--[moduleId]
----/lessons
------[id].js
I have a sets of users that I need to create themes for. Depending on the user's account association I want to load different themes. For example if John Doe logs in I need to load up greenteam.scss. However, if Doug Smith logs in he should see blueteam.scss.
Those files are basically color and font settings used by other elements. greenteam may have $header-bg: green; and blueteam would have $header-bg: blue;.
My initial thought is to have a structure like this: /src/scss/client/_client-xxx.scss that says the background colors, font colors, etc variables set in the application. So, after login the system is told the person logged in is part of "greenteam" and /src/scss/client/_client-greenteam.scss is loaded to compile the colors and other settings together. This way I can just drop the new client theme in the directory and boom, new theme!
The number of "teams" is going to grow exponentially. I have no idea how many I'll ever have at any given point. This is why the "just change the body class" is worrisome as that will get very big and hard to manage.
It's also possible I don't have a good grasp on how angular builds itself out on the web as a user calls the pages/styles. It appears, at a glance, when deployed on the server angular compiles the scss down to css in the header and not loaded "on the fly". If that's the case it seems I'd have to load all the possible client css options and just show what matches (the body class route).
The user won't have control over their theme directly or be able to change it, the theme will be customized manually by a developer.
I would have suggested to change the body class, but, if you really want to apply css at runtime, you could try to:
compile the scss to css
insert it in the dom at runtime depending on the user
Check this topic which tells how to add a style at runtime, you could get the text content of the stylesheet from a database:
https://stackoverflow.com/a/524717/10899694
I see a message This type of folder does not support ordering when viewing the News or Events folder. My understanding is that items contained in such folder, their position order can not be set arbitrarily. Only alphabetical order for their IDs is applied.
From ZMI, I see News and Events folders are of ATFolder type, everything seems the same with the regular folder I just create. What makes such difference? And what is the rationale behind this?
Edit: My bad that Info message in the above image is enabled by wildcard.foldercontents, which I thought due to Plone 4.3.2. However, the issue remains that position order can not be set arbitrarily. The following image attached to illustrate this.
PS: I ever delete the News folder, create a regular folder named news, this way I can set item position order arbitrarily. However, I find the Calendar Portlet within that folder is not working right. The issue happens when I click to switch months. The URL link will be out of its context, I mean, not staying in the news folder. Maybe this is not related to the folder ordering behavior, anyway, just for your reference.
For some reason Plone is shipping with the news and events folders being unorderable.
>>> news = site.news
>>> news.getOrdering()
<plone.folder.unordered.UnorderedOrdering object at 0x112e434d0>
I consider this a bug in plone's initial site installation.
Plone core actually explicitly sets the folder to unordered: https://github.com/plone/Products.CMFPlone/blob/4.3.x/Products/CMFPlone/setuphandlers.py#L250
I don't understand why. I'll change it if there aren't any objections...
So I'm writing a Django based website that allows users select a color scheme through an administration interface.
I already have middleware/context processors that links the current request (based on domain) to the account.
My question is how to dynamically serve the CSS with the account's custom color scheme.
I see two options:
Add a CSS block to the base template that overrides the styles w/variables passed in through a context processors.
Use a custom URL (e.g. "/static/dynamic/css/< website_id >/styles.css") that gets routed to a view that grabs all the necessary values and creates the css file.
I'm content with either option, but was wondering if anyone else out there has dealt with similar problems and could give some insight as to "Best Practices".
Update : I'm leaning towards option number 2, as I think this will allow for better caching down the road. So it's dynamic the first time, gets stored in memcache (or whatever), and invalidated when a user updates their settings in the admin site.
Update: Firstly, I'd like to thank everyone for their suggestions thus far. All the answers thus far have focused around generating static files. Though this would work great in production, it feels like a tremendous burden during development. If I wanted to add a new element to be styled, or tweak existing styles I'd have to go through and recreate each and every css file. Sure, this could be done with a management command, but I just don't feel it's worth it. Doing it dynamically would add 1 maybe 2 queries to each page load, which is something I'm not worried about at this stage. All I need to know is that at some point I will be able to cache it without rewriting the whole thing.
I've used option #2 with success. There are 2 decent ways of updating the generated static files that I know of:
Use a version querystring like /special_path.css?v=11452354234 where the v parameter is generated from a database field, key in memcached, or some other persistent file. Version gets updated by admin, or for development you would just make the generation not save if the parameter was something special like v=-1. You'll need a process to clean up the old generations after some time.
Don't use a version querystring, but have it look first for the generated file, if it can't find it, it generates it. You can create a cron job or WSGI app that looks for filesystem changes for development, and have a hook from your admin panel that deletes generations after an update. Here's an example of the monitoring, which you would have to convert to be specific to your generations and not to Django. http://code.google.com/p/modwsgi/wiki/ReloadingSourceCode#Monitoring%5FFor%5FCode%5FChanges
Could generate the css and store it in a textfield in the same model as the user profile/settings. Could then have a view to recreate them if you change a style. Then do your option 1 above.
Nice question.
I would suggest to pre-generate css file after colors scheme is saved. This would have positive impact on caching and overall page loading time. You can store your css files in directory /media/css/custom/<id or stometing>/styles.css or /media/css/custom/<id or sth>.css and in template add <link rel="stylesheet" href="/media/css/custom/{{some_var_pointing _to_file_name}}" />
You can also do the trick with some random number or date in css file name that could be changed each time file is saved. Thanks to this browser will load the file immediately in case of changes.
UPDATE: example of using model to improve this example
To make managing of those file easy you can create simple model (one per user):
class UserCSS(models.Model):
bg_color = models.CharField(..)
...
...
Fields (like bg_color) can represent parts of your css file. You can ovveride save method to add logic that creates css file for user (by rendering some template).
In case your file format change you can make changes in your's model definition (with some default values for new fields), make little changes in template and run save method for each exisintg instance of class. This would renew your css files.
That should work nicely.
I would create an md5 key with the theme elements, store this key in the user profile and create a ccs file named after this md5 key : you gain static file access and automatic theme change detection.
In my asp.net app a user can upload several localized images (of buttons) .
For example, he will upload 'send.gif', 'send.fr.gif', 'send.en-UK,gif; etc..
When a visitor is coming to his page, I need to pick up the right file based on the visitor's locale.
Is there an api (or simple way) to find the best appropriate image based on the locale - for example, if a visitor is from France the API will return 'send.fr.gif', if the visitor is from Australia the API will return 'send.en.gif' etc...
The logic should be the same as ASP.NET pick the right localized resource file basically.
Thanks.
It seems from your post that you already have a way to detect the users locale. So I will assume that you are holding this information.
The way that we do this is we store the users locale in session, and store all localised resources in corresponding directory names. eg:
/
/images
sendButton.gif
background.gif
/de-de/
sendButton.gif
/fr-fr/
sendButton.gif
An HttpHandler is then used to map the localised directories over the top of the default directory, based on the current users locale. This allows for seamless integration of images into all code, and css, and will use the image in the base directory if no localised image is found.
If more sophisticated sorting is required then i would suggest nesting your countries inside your languages. like this:
/
/images
sendButton.gif
background.gif
/de
/de
sendButton.gif
/fr
sendButton.gif
/fr
/be
You can then specify lenguage level resources. And even have your http handler map files in suce a way that they propogate up rather than down the tree. So that the fr-fr resource will be used for all french speacking countries that dont have their own resource of that name.
Of course at this point it does become rather complex, especially when deciding which french speaking country is used as the default for the french language if none is specified. you may wish to start storing priorities somewhere in order to decide what you serve to which locale. And whether resources propogate up or down the tree. But as a transparent structure for localising images while keeping yoru markup and CSS clean this should work very well.