I have below scenario:
css/abc.css - myCss{prop1: val}
css_new/abc.css - myCss{prop1: newVal}
I cannot update css/abc.css. Hence, css_new/abc.css is introduced. Both these files will be used parallely in prod at least till the time complete migration is done.
All of the old code use style from css folder. The new code refers to css_new folder. My concerns are:
1. Will there be any caching at browser level.
2. Are there possibilities of my old code referring to the new css class defined in css_new.
I want to make sure there are no regressions in old code because of this change.
Some more background: upgrading UI code to angular. Mainly, image URLs referred from CSS are broken. Many thanks.
Related
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 am new to Plone and I'm just learning how to change stylesheets.
I successfully changed the ploneCustom.css in /Plone/portal_skins/custom/ and saved it.
But when I tried to take a look at the site, I realised that the ploneCustom.css stylesheet isn't even loaded.
According to my research a template is broken...
But what do I do with that information?
Where do I fix it and how?
Thanks for your help in advance!
50 ways of styling Plone, four of them explained:
1.) Customize ploneCustom.css
A relict of the skin-folder-times, by now it is recommended to use browser-based resources, instead.
The reason is, when you have a lot of resources registered, it's hard to keep a correct order of the skin-layers and that can lead to unwanted overrides. Nevertheless, if you don't have a complex setup, or for quick testing, it is feasible to use skin-layers and ploneCustom.css, the exact steps are:
Go to "http://yourhost.net:8080/yourPloneSiteId/portal_skins/sunburst_styles/ploneCustom.css/manage_main".
Click on "customize".
Enter some style for testing, e.g. "body { background: red }", save.
Make sure, CSS-debug-mode is on at "http://yourhost.net:8080/yourPloneSiteId/portal_css/manage_cssForm" also make sure that ploneCustom.css is actually on the list and enabled, meaning the checkbox on the left is checked. It should be the last entry in order to override all other stylesheets.
2.) Use a site's page as style-source
Alternatively you can have a look at "adi.ttw_styles" (disclaimer: I'm the author), which provides you with a stylesheet living in the site as an ordinary item of type "Page" and is registered as a browser-based resource, so naming-conflicts are impossible. Still, the stylesheet lives in the site then, which wouldn't be suitable for cases, where you want to have a reproducable theme.
3.) Include browser-based resources in your addon (f.k.a. "Product")
Well documented.
An addon-generator, which allows you to create an addon holding a browser-based stylesheet and javascript, is "adi.devgen" (disclaiming again: I'm the author), after installation simply execute devgen addBrowserSkel your.addonname of the commandline.
4.) Diazo
The widely promoted state-of-the-art-way-of-theming. Well documented, have fun learning XLST :-)
I have several large CSS files and making a change can sometimes take a few minutes just to find the right selector to change. I would like it if there was a nice ModX editor for CSS, but I haven't been able to find one. I am willing to settle for splitting up my files into parts, as long as my site still renders. Can I do that and how? If there is a nice editor (plugin?) instead, where can I find one?
I guess the real question is what kind of parts are acceptable for you. If you follow this question, you can begin the process of allowing ModX to manage your CSS. Once this happens, your options open considerably. Your CSS editing will then become easier and less time consuming depending on your level of expertise with ModX. This answer will be pretty simple, as it will show simply how to add a given selector as a resource. Other further development can be intuited from here, though.
CSS as a Resource
Once your CSS is being managed as a Resource (which takes about 15 minutes), you may utilize Templates, Template Variables, Chunks, Snippets and Plugins. Thisis actually pretty amazing, but setup can be a bit of a pain. You will basically be investing some time to save a lot of time in the future. The next logical step is split your Selectors accordingly, but you don't want to break what currently works. Having a fluid understanding of the getResources addon will be crucial to further development.
How to do it:
1. Create a new chunk
Click the Elements tab, and click "New Chunk". Name it "css-selector". Set the content to:
[[+pagetitle]] {[[+content]]}
It's as simple as that. Don't forget to click "Save"! This will let you set a Selector as a resource. It will use the title for the selector and content for the rules. You can forget about using those braces any more. Your new chunk will handle those from now on.
2. Adjusting your Template
Now, we just have to convince the template that it nows how to read parts, as well as not forget the whole. Open your CSS Stylesheet template (the one that says [[*content]] for its content). Adjust the code so that it has the following:
[[!getResources?
&parent=`[[*id]]`
&depth=`1`
&tpl=`css-selector`
&includeContent=`1`
&sortby=`menuindex`
&sortdir=`ASC`
&limit=`99`
]]
[[*content]]
Again, click "Save". Let me explain the Template real quick. If you have child, they'll get rendered first depending on their menu index. Further, it will render the contents of the document that are not children afterward. This will allow you to only make new resources for your most important selectors, while keeping the stuff that will never change in the main resource.
3. Create a new Template
This is so that your selectors don't do anything funny and just render the content. Create a new Template named "CSS Selector". Set its content to:
[[*content]]
4. Create a new Resource
Create a new Resource. Set the title to the selector for the css statement you want to manage. Then set the content to the rules without the braces. For instance, if your css statement is: div#header .logo {border:0;}, you'll set the title to div#header .logo and the content to border:0;. Set the resource alias to whatever you want. I use numbers for each one. Set the template to your new "CSS Selector". Important Now, set the Parent Document to your Stylesheet. Click Save.
5. Testing the Stylesheet
First, Right-click your new resource and choose "View Resource". This will just make sure that the statement was rendered correctly. It should simply say your rule in CSS format.
Next, Right-Click the Stylesheet resource and choose "View Resource". You should see the Selector at the top and all of the other rules below it.
Final Considerations
Observations
You'll notice that your child resources do not have to be changed to "CSS" for Document Type. Only the parent stylesheet has to be. This allows for some neat stuff as your expertise with ModX grows.
You can change the order of rules by simply changing the menu index of them.
The number of rules that can be done this way is based on the &limit variable in the getResources statement in your template. &limit applies to each stylesheet, so in this example you have 99 statements per stylesheet that may be separate resources.
A Note on Server Load
This will place load on the server as the number of resources goes up. For development, keep the "do not cache flag" (!) on your getResources statement. Once you are done, remove the exclamation mark and let it all be cached. This will save a ton of load.
Further Development
I added an isEnabled template variable to mine so I can turn on and off each rule as I pleased.
You may possibly begin to manage your CSS on the front-end utilizing FormIt.
Custom Manager Pages may even be a better option for you.
Further abstraction might allow you to create Groupings of statements for even further organization.
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.
I found out that some websites use css tag like style.css?ver=1. What is this?
What is purpose of ?ver=1?
How do I do it in code?
To avoid caching of CSS.
If the website updates their CSS they update the ver to a higher number, therefore browser is forced to get a new file and not use cached previous version.
Otherwise a browser may get a new HTML code and old CSS and some elements of the website may look broken.
Adding '?ver=1' makes the HTTP request look like a GET query with parameters, and well-behaved browsers (and proxies) will refuse to cache parameterized queries. Of course well-behaved browsers (and proxies) should also pay attention to the 'Cache-control: no-cache', 'Expires', 'Last-Modified', and 'ETag' response headers (all of which were added to HTTP to specify correct caching behavior).
The '?ver=1' method is an expensive way to force behavior when the site developer doesn't know how (or is too lazy) to implement the correct response headers. In particular, it means that every page request is going to force requesting that CSS file, even though, in practice, CSS files change rarely, if at all.
My recommendation? Don't do it.
The purpose of the ?ver=1 is to parameterize the css file, so when they publish a new style.css file they up the version and it forces the client to download the new file, instead of pulling from the cached version.
If you are developing a web application in HTML and CSS or any other technology, and you are using some external CSS or JS files, you might notice one thing that in some cases if you made any changes to your existing .css or .js files then the browsers are not reflecting the changes immediately.
What happens in that case is that the browser do not download a fresh copy of the latest version of the .css and .js files, instead it uses those files stored in your local cache. As a result the changes you made recently are not visible to you.
<link rel="stylesheet" href="style.css?v=1.1">
The above case when you load the web page the browser will treat "style.css" as a different file along with "?v=1.1". Hence the browser is forced to download a fresh copy if the stylesheet or the script file.
I think that ?ver=1 is for the version no. of the web app. Every time a new build is created, the app can update the ver to the new version. This is so that the browser will load the new CSS file and not use the cached one (both use different file names).
You can refer to this site: http://www.knowlegezone.com/36/article/Technology/Software/JavaScript/CSS-Caching-Hack----javascript-as-well
IMO a better way to do this would be to include a hash generated off of the file size or a checksum based on the file contents or last-modified date. That way you don't have to update some version number and just let the number be driven off of the file's changing properties.