The scenario:
A homepage that is generated with PHP and a template engine.
The page is being redesigned.
The new design is based on jQuery UI.
The current CMS uses multiple templates: a page template, an article details template, a comments template etc.
The problem:
Some templates (like the article details template) generate html fragments that should use jQuery UI elements like tabs. Currently the data source of the page template does not contain any information which elements should be turned into jQuery UI elements in the main jQuery call in the documents head.
Possible solution
Add a CSS class like "jqTabs" to the html markup of the sub-templates and use the selector .jqTabs in the main jQuery script.
Question
Is this a bad idea?
BTW: "Use a different CMS" is not a valid answer, because this is not an option right now (deadline, budget,... you name it -.- ).
Not a bad idea at all.
That is one of the primary uses of classes.
A class (like and ID) can be used as both a way to style an element and / or a hook for scripting.
In this case, it might be the best possible solution, as it allows for what seems to be minimal markup changes for a wider redesign.
And it is easily reversible.
I believe that using CSS classes as hooks for JavaScript can indeed be a bad practice. The reason I say this is because this approach intermingles your CSS and JavaScript and can often lead to unnecessary confusion.
Let me explain: Right now I am working on adding new templates to an existing system which uses dynamic user controlled admin settings to control CSS properties (page width, font sizes, colors, etc). These settings can also affect JS properties (slideshow options, delay between slides, etc.).
The problem is that since so many CSS classes were used as JavaScript hooks, I am having a terribly hard time determining which classes are used for styles and which ones are used as JS hooks, and which ones are used for both! As a result, when doing a new template, it would be very difficult to start from scratch with new markup as I would be leaving out various important classes for both CSS and JS functionality.
The task would be much easier if CSS classes were ONLY used for styling, and other JS hooks were only used for JS. I envision this being accomplished with HTML5 data attributes, which would look something like this:
my link
By using the HTML5 data attributes for JavaScript hooks and the class attribute for CSS styling, we can be sure that all classes are ONLY related to CSS, and anything JavaScript related simply gets its custom attribute.
Another option I have used is prefixing any css class with js- that is ever referenced by the JavaScript. That way you would know which classes you could remove safely for styling and which ones had to remain for existing functionality.
<a href="/mylink" class="my-style-class my-other-style-class js-my-hook-1 js-myhook-2">
My link
</a>
Related
I created a browser extension that inserts DOM elements directly into a page, and I'd like to prevent them from being styled by any inherited CSS already in the page. At the moment, I append my a css call to the head to bring in my own styles. So far my plan has been to use obscure class/id names and create very specific rules. In some cases I've had to use !important. I feel like I'm throwing throwing my morals out the door!
Any thoughts on how I could efficiently prevent inherited styling, and yet allow the browser to render my code efficiently?
Any thoughts on how I could use an iframe to do this? I'm running PHP on the back end.
You can't prevent the cascading bit of cascading style sheets but you can define all styles so there is nothing left to inherit.
A quick way of doing this is style them how you want then use webkit's developer tools (or firebug) to view the computed styles for the elements.
Then you can just copy all of the computed styles into your stylesheet. Make sure to use unique IDs so they don't overlap with anything on the page and the styles will be very specific. Add !important ...cringing as I say this... to prevent someones weirdly specific stylesheet from overlapping and make sure your stylesheet call is added in at the end of HEAD or insert it in a style block at the end of the body to make sure it can't be overridden.
I need to add styles to my style tag in my head section. How can i add to that style tag from the view.
You'd be better off from an MVC point of view by putting these style elements in to their own stylesheet, and then inserting the sheet in the way mentioned above.
However if you must use internal CSS, this should work:
$this->addScript('extraCSS','<style type="text/css>".foo{color:red;}</style>');
extraCSS I believe is just an internal name given to the content that gets added to the $scripts_for_layout buffer.
This will appear below any JS inclusions, which can be a problem at times.
See all about adding css files using the HTML Helper here: http://book.cakephp.org/view/1437/css
Make sure you have $scripts_for_layout in the head of your layout to have cake put scripts there automatically (see the third example).
EDIT:
For style tags, see here: http://book.cakephp.org/view/1440/style
Otherwise, CakePHP uses simple PHP as the templating language in the view - so just write it using that.
Some example code and further explanation of what you'd like to do would also be helpful.
I want to include a specific css file that should be applied to the homepage, and 6-7 other pages throughout my site.
I know I can do this via PHP, getting the URL, finding out what page, linking the css...etc, but I was wondering if there was a slick way (or any better way) using CakePHP to include the correct css file(s).
I realize I can link the CSS file from the specific views, but - then they wouldn't be in the <head>. Is there a way to link from a view and have it show up in the head?
I hope my questions make sense, and greatly appreciate any help.
I realize I can link the CSS file from
the specific views, but - then they
wouldn't be in the <head>. Is there a
way to link from a view and have it
show up in the head?
Yes, they would be in the head. See the HTML Helper documentation:
If key 'inline' is set to false in
$options parameter, the link tags are
added to the $scripts_for_layout
variable which you can print inside
the head tag of the document.
So, this snippet in your view...
$this->Html->css('my-css', null, array('inline' => false));
...will add the proper <link> element to your <head>.
Check this little tutorial out:
http://nuts-and-bolts-of-cakephp.com/2008/05/05/css-files-and-scripts_for_layout/
Basically you can use this standard view attribute $scripts_for_layout to inject CSS files based on the view. Hope this is what you're looking for. There's a few other crazy options I thought of, involving extension parsing, but it would probably be more cumbersome than just manually linking the stylesheets. I think this link describes the best solution.
You can also have different layouts, and include css in them:
http://book.cakephp.org/view/1080/Layouts#!/view/1080/Layouts
This comes handy if all the views of a model have the same css, or script.
It is not the answer for your question, but...
you can program your own injection for the layout file. The problem with $scripts_for_layout is that js and css codes are injected in the header. If you write your own implementation you can put the $scripts_for_layout var (for the js) at the end of the layout file. The cue is: separation...
I'm starting to understand the importance of templating in PHP. I'm using PHP itself as a template engine to avoid learning any new language. I'm still not clear on one thing tho, although I have an idea about it. I would like to know what the experts do.
Should I create a full page template, with all tables, forms and everything else (including header and footer), or should I put all of my tables, forms, etc in their own file and then add them to the template as needed.
Here's a small example to clear things up...
Should I
a) create one page with all the tables, forms, and other elements in it and use that as a final product
// Set all the information
$template->title = $username;
$template->user_info = get_user($user_id);
$template->articles = get_articles($user_id);
$template->ads = random_ad($user_info);
// Load the template with everything already in it
$template->load('user_page.tpl')
$template->display();
OR
b) create every table, form, related block element in its own file and then use those to create a final product
// set the title and load the header template
$header['title'] = $username;
$template->load('header.tpl', $header);
// get the user info as an array and load into user profile template
$user_info = get_user($user_id);
$template->load('user_profile.tpl');
// load the new article form
$template->load('new_article_form.tpl');
// get the articles as an array of info and load into user articles template
$articles = get_articles($user_id);
$template->load('user_articles.tpl', $articles);
// get a random ad based on user info
$ads = random_ad($user_info);
$template->load('advertisements.tpl');
// load the footer template and display final page
$template->load('footer.php');
$template->display();
Where every file loaded contains a small portion of what needs to be displayed on the final page.
Because of the Dont Repeat Yourself technique, I would think B, but i would like to know which and why
I would personally say the first approach is best, because it keeps all documents and document fragments semantically complete.
The second approach means that you'll have a <div> in your header.tpl that is closed by a </div> in your footer.tpl (except likely there will be a few tags that applies to). This means if you change your layout, by adding a wrapper div (for example) somewhere, you have to remember to also close it in another file (or, depending on your layout, two or three different files).
It's worse with several different embedded files. Think of how hard it is to debug a site, when one file - that gets included conditionally - has an extra </div>. You get a vague bug report "sometimes the page looks completely messed up, doesn't matter what browser I use" that is very very hard to track down. It's MUCH worse if you're using table-based layouts..
Using the first approach, you can still use the DRY principle. You load the template into a variable. eg:
$userVars['name'] = $currentUser->name;
$templateVars['userinfo'] = $template->load('userinfo.php', $userVars);
...
$template->display('template.tpl', $templateVars);
You can continually nest documents that way. There are many benefits:
Each file is semantically complete HTML - all tags that are opened, are also closed in the same document. It's easy to edit one part of the layout without breaking (possibly unknowningly) anything else.
It's each to cache the output of certain templates, and re-use them
It's easy to apply AJAX to the site. For example, you have a stats.tpl template rendering inside a <div id="stats"> on the first page load. You also have a view that just renders the stats.tpl template by itself, and then use jquery to do $('#stats').load('/ajaxstats.php'), which refreshes that div but without repeating code at all.
Template inheritance for structures common to every template (e.g. layout; header/footer), and template embedding (i.e. including) for reusable bits (e.g. forms).
With approach A and without inheritance, you'd be either including common layout elements (which is IMHO ugly), or duplicating entire layout in every template (which is even worse). And plain approach B would create massive amounts of tiny template bits for everything, which may reduce maintainability.
And for that, I really recommend using real, dedicated templating engine instead of plain PHP. They make life easier (inheritance is one thing; another - variable auto-escaping).
template inheritance would probably make the cleanest code. you can do this now in straight php using PHP Template Inheritance
There is no good or bad solution. There are techniques and guidelines but in time you will learn what approach is better than others.
Just by looking at it i would say that the second approach allows you to be more flexible and breaks down the page into smaller parts. Smaller might some times mean more manageable.
Also the second solution also allows more than 1 persons working on the page since they will only need to work/change parts of the page and not the whole page.
regards,
As gregmac suggested, the first solution is probably preferable. Having said that, I would also suggest to have a look at the various PHP frameworks available, most of which implement templates using various techniques.
Have a look at this list for a start. You may also want to take a look at some stand-alone template engines, such as Smarty, in order to get some ideas or to avoid implementing your own engine.
I have a web application developed using PHP. I want my users to select themes for their pages throughout the application.
Where should I start before using PHP themes?
What should I know about Themes in a PHP application?
Edit:
My question about themes is only about changing the color of the layout, not the images.
Suppose My ADMIN user will have white and Orange, but my staff user will have white and green...
How it can be done in PHP with CodeIgniter?
There are lots of directions you can go with this.
1) "CSS ZEN"
This is where the markup remains unchanged, but you totally change the design just by using CSS and images. Demonstrated very well on http://www.csszengarden.com/
2) MVC Stylee
This is where you create a model that represents the page data and then pass it to a view, which contains some inline echo statements. The idea is that you could send the same model to a totally different view so it could look entirely different, HTML and all. Cake PHP is a good start for this: http://cakephp.org/
Example:
<div class="content">
<? echo $Page->Content ?>
</div>
3) Micro-Markup
With this method, you add your own "special tags" to an HTML page. You then read in your plain HTML page and replace the special tags with the information you want to display. This is good if you want your templates to be recognisable to HTML guys that don't know PHP and might break the PHP code in the MVC app.
Example:
<div class="content">
<#Content#>
</div>
Out of all of these, MVC is a very structured way of achieving what you want - however, I listed the other options as they cater for specific scenarios that might be relevant to you.
I have implemented the concept in all three of these, in situations that were appropriate for each.
Regarding The Edit In The Question
I imagine you'll have "something" that represents your user - so it is as easy as:
(In the event of just wanting to override a few settings...)
<link href="style.css" type="text/css" rel="stylesheet">
<?php if ($User->Type === USER_ADMIN) { ?>
<link href="admin.css" type="text/css" rel="stylesheet">
<?php } ?>
You can adjust this example in the following ways:
Use a switch statement if there will be many user types
If the replacement is total, rather than just a few overrides, you may want to completely swap the stylesheet.
You would usually set up template files that contain the HTML and CSS, and build in the PHP generated values at runtime.
The best approach to this is to have the theme reside in a separate directory, containing no code, just template variables like {mainmenu}, {backbutton}, {content} ... you get my drift. Those are then filled by your PHP script, possibly with the help of a template engine like Smarty (No need to re-invent the wheel here).
There is also the approach of having PHP markup directly in the template file(s) like echo $xyz; while this is a perfectly valid practice I use myself often, I recommend using a template engine over using PHP markup in the code if you want a solid, future-proof templating system because:
First, there is less that a designer can break when working on the HTML.
Second, having PHP markup in the code is a temptation to program PHP logic inside the template (loops, conditions) instead of properly preparing them in the PHP code at the point where the template variables are created. That is terrible for maintenance and the further use of your templates, because you have to replicate that PHP soup into every new template again. After all, you want to have a template engine so others can create new looks for your product, without having to know how to program it.
Third, with the templating engine based approach you have the possibility to add caching where necessary without any additional work. Not possible with the scripting approach. Yes, in a web application you won't be able to cache that much, but with a lot of data, there will be instances where it will help the user experience.
Fourth and least important, it makes your template less easy to export to other applications, and import templates from other applications.
The CSS Zen approach mentioned by Sohnee is great for websites, but is going to be too limited for a web application that uses complex input elements, JS based menus, and the like. It is too often that those elements need to be changed and customized in the markup.
If you have a look at my CodeIgniter Template library it briefly explains how you can set up themes and layouts (the equivalent of header & footer).
If you set up global code such as a Hook or a MY_Controller then you can dynamically set your theme based on the logged in user, the user type, etc.
Eg:
if($user->role == 'admin')
{
$this->template->set_theme('admin_skin');
}
else
{
$this->template->set_theme($user->theme);
}
That is just a VERY basic example of the sort of thing you could use this Template library for.
CMS Solutions
Magento and Wordpress package all theme related files into their own seperate directories. These contain the serverside code, stylesheets, images and javaScript for the theme. The user in effect chooses a directory to use which affects how the page is layed out and styled.
An easier approach
A much easier way to get started would be to accept that the actual content, e.g. HTML of a page would stay the same, but let the user choose from various CSS style sheets.
When choosing a style sheet the system could use JavaScript to load it in dynamically so that the user can preview the look they are choosing.
If you have really good semantic HTML it will be enough to change the CSS files. Unless the design changes are really heavy. Then it would make sense to provide PHP templates that are build with some sort of modules: variables which contain certain HTML structure like navigation or sidebar, etc.
For themes you do not need PHP. Just define your themes in CSS (the best way is one file for each theme) and use a simple JavaScript chooser like at this site: http://www.fotokluburan.cz/switchcss.js.