Global Attributes

Permalink 2 users found helpful
I finally figured out how to give users the ability to change background images themselves using attributes. VERY COOL! If you combine this with the customization page.. You've pretty much given the customer the ability to do anything they want.

My questions is.. if you set up attributes for background, navigation background, header background, etc.. Does the user have to go in and literally change the background on every single page? Or like the customization page.. is there any way to give the user the ability to change the site background on all pages with the same attribute?

getjoel
View Replies:
jelthure replied on at Permalink Reply
jelthure
this depends on how your css is written, but it should be global if changed within the themes "customize" page.
getjoel replied on at Permalink Reply
getjoel
Again. Doesn't the customization page only change colors.. not background images?
getjoel replied on at Permalink Reply
getjoel
Anyone?
TheRealSean replied on at Permalink Reply
TheRealSean
Could you add $class to your page templates? and then set that dependant on your attribute.


<?php
$image = $c->getAttribute('page_bg');//I believe this gets the object?? rather then just the value
$im = Loader::helper('image');
$r = $im->getThumbnail($image, $width, $height
$style=" background:{$r->src};";
if($style!=""){
$style = " background:images/default.jpg;";
}
?>
<div id="central" $style>


Thinking about this too it should be possible to pull in a file from the Global Scrapbook? and retrieve its fileID and then work backwards from there.

I know its stored in as an image block but somewhere in the object should be the fileID? then you could grab the object($imageObject=File::getByID($fID);, then set it up as above

I am not to sure if it would work but in theory, Ill have a play and see if I can work out the relevant bit.
TheRealSean replied on at Permalink Reply
TheRealSean
this seems to work,
//I added an image in the global scrabook that I called test_image
$block = Block::getByName('test_image');
if( $block && $block->bID ) { $fID=$block->instance->fID;}

then you should be able to grab the object from that id, then grab its relative path and have it set as a bg

A switch could also be put in place to use the attribute if found, otherwise use the scrapbook default. Or even depending on the attribute value(select box) choose a different scrapbook block.

$block = Block::getByName('test_'.$c->getAttributeValue('page_class'));
as long as your blocks are in place and refer to an attribute option its not ideal and they could break it by renaming the scrapbook block but it should work.

You could even have a Scrapbook "Background Images"
jordanlev replied on at Permalink Reply
jordanlev
Wow, this is brilliant! I never thought of this approach before, but I think it would be the best way to go.
jordanlev replied on at Permalink Reply
jordanlev
You're correct that the css customization feature doesn't let you set background images (unfortunately). And global attributes don't exist in C5 (and setting attributes in Page Defaults doesn't work unfortunately, although that would be ideal).
So... the first and easiest solution is to set a default in your code (like if the attribute isn't set, use a default image). But the only way you could let the user change this default is by telling them to replace that specific image in the file manager (since the code would reference the file by ID, changing the image for that ID would do the trick here). A more robust solution would be to create a dashboard page that allowed the user to choose this default image, and use that as the default in your code -- but that's a lot of development work and not something I could give a quick answer on how to do.

Sorry, wish I had a better answer for you :(

-Jordan
kirkroberts replied on at Permalink Reply
kirkroberts
So... I have this weird habit of replying to old threads, and here I go again.

If you want to set a site default I would consider adding a property to the home page.
In this case, create and add a file attribute, maybe with the handle "background_image".

Then you can access that property from any page in your template, like this:
$home = Page::getByID(HOME_CID); // home id is probably 1, but use this constant instead
$f = $home->getAttribute('background_image'); // assuming you set up a 'background_image' attribute

Now you have a File object in your $f variable to do with what you will.
Such as:
$ih = Loader::helper('image');
$ih->outputThumbnail($f, 1200, 900, true); // 1200 x 900, cropped


It seems most intuitive to have these kinds of "global" things (properties, footer, etc) on the home page rather than the Scrapbook, but your mileage may vary.

Hope that helps someone!
jordanlev replied on at Permalink Reply
jordanlev
This is a great idea! I'm curious how you handle "collateral damage" -- for example, what if you wanted a different background image on the homepage than the default that you want to use for other pages?
beebs93 replied on at Permalink Reply
beebs93
I've had to do custom background images on the last two projects where unless a particaluar page attribute was set (page_bg), the page would randomly choose an image from a particular file set.

If this can be of any help feel free:
<?php
defined('C5_EXECUTE') or die("Access Denied.");
Loader::model('file_set');
Loader::model('file_list');
// First, we attempt to get the background image page attribute file object
$objFile = $c->getAttribute('page_bg');
$strPath = NULL;
if(is_object($objFile) && $objFile instanceof File && !$objFile->error){
   $strPath = $objFile->getVersion()->getRelativePath();
   $intX = abs(intval($objFile->getAttribute('width')));
   $intY = abs(intval($objFile->getAttribute('height')));
// If it is empty (or an invalid file), we attempt to grab a random file from the background images fileset
}else{
   $fs = FileSet::getByName('0-3-Background Images');
   $fsl = new FileList();


I actually hard-code a default image in the template directory and not as a File object. My logic being that files from the File Manager can be deleted and I'd rather have a hard-coded fallback if someone pushes a button they shouldn't have.

I suppose you could implement the home page's bg image as the default, but it's still a File object that can be removed/cleared so having some type of last resort image is a good way to go (unless the design can suffer without one).
jordanlev replied on at Permalink Reply
jordanlev
Thanks for sharing this. I've done something like this before as well. For a fallback, I agree that it's best to have a hardcoded file, but I just declare that in the theme's stylesheet as normal, then the code that puts in a random one outputs it as a style in the page <head> -- if it exists, it overrides the one declared in the stylesheet, if not then the stylesheet one is there as a fallback.

Also, at the bottom of your code you have "return", but I think that should be "echo".
beebs93 replied on at Permalink Reply
beebs93
If you're talking about CSS background images then, yes, that is a good way to implement a fallback.

The snippet I provided was using actual <img> elements to get around cross-browser full-screen scalable background images (without resorting to CSS3 or a JS shimmy).

And the reason for return vs echo is I believe this was snippet where I simply included this file from the header.php file like:

echo include_once($strThemePath . '/includes/get_page_bg.php');
jordanlev replied on at Permalink Reply
jordanlev
Ahh, yes that all makes sense.
BTW, instead of doing include_once, I'd probably use an element instead (an element that goes in your site's top-level "elements" directory, not in your theme's elements directory). Then you could just put this in your page type templates:
<?php Loader::element('get_page_bg'); ?>


...both work just fine, but I think using an element keeps the page type template code cleaner (and also you don't have to worry about setting that $strThemePath variable).
beebs93 replied on at Permalink Reply
beebs93
You know, it's one of those things where what you say makes perfect sense, but I can't remember for the life of me why the Hell I did it that way.

Cheers!
jordanlev replied on at Permalink Reply
jordanlev
Heh... I do this all the time. Can't go through life questioning every decision, so once you figure out how to make something work it's time to move on :)
In my opinion, this is what's great about an active developer community around an open-source system -- people are willing to share their code and methodologies, and everyone learns along the way.
kirkroberts replied on at Permalink Reply
kirkroberts
Love the fallback idea, thanks!
That neatly takes care of the issue of having (optional) different images on different pages, including the home page.

If you want to extend that, you could have:
- optional page image attribute (set on any page)
- user-defined fallback image for all pages (just set on the home page)
- hard-coded fallback image, in case everything goes to pot

Thank you everybody for sharing!