Customising Theme - background-images

Permalink 4 users found helpful
Is it possible to add a customisable background image. I have followed the same code for customisable background color but with background-image and nothing comes up.

I am looking to create a theme where the logo in the header can be changed.

Cheers

Barry

novelnova
View Replies: View Best Answer
Adreco replied on at Permalink Reply
Adreco
Hey Barry,
Short answer: Yes

Many themes, your backgrounds can be replaced in the image folder. Be aware, you need to be cautious to use compatible images types and change the code found on the main CSS page( see http://www.concrete5.org/community/forums/customizing_c5/missing-ba... for example of code change from original in one instance )
Also, If you're only looking to change site name to logo, be sure to edit the my_site_name found in the Dashboards Global Scrapbook.
jordanlev replied on at Permalink Best Answer Reply
jordanlev
It's not possible in the way that you can with background colors and fonts, but it is possible by creating a custom attribute (Dashboard -> Pages and Themes -> Attributes, choose "Image/File" (or "File/Image"?) from the dropdown menu, click the "Go" button. Enter something like "background_image" for the handle and "Background Image" for the name, and leave the other checkboxes unchecked, then click the "Add Attribute" button. Now in the <head> of your theme (probably in elements/header.php), add some code like this:
<?php
$bg_img = $c->getAttribute('background_image');
$bg_img_src = $bg_img->getRelativePath();
?>
<style type="text/css">
body {
  background-image: url(<?php echo $bg_img_src; ?>);
}
</style>


You will probably still want to set a default background image in your theme's stylesheet in case none is selected for a specific page. (Unfortunately this code only works on a per-page basis, no way to set it across every page for example).
Also, if this theme is going on the marketplace for others to use, you'll want to automatically install that custom attribute instead of requiring people to add it themselves. This can be done in the theme's package installer, in the install() function, like this:
Loader::model('collection_attributes');
$bgImgAttrKey = CollectionAttributeKey::getByHandle('background_image');
if (!$bgImgAttrKey || !intval($bgImgAttrKey->getAttributeKeyID())) {
   $boolt = AttributeType::getByHandle('boolean');
   $bgImgAttrKey = CollectionAttributeKey::add($boolt, array('akHandle' => 'background_image', 'akName' => t('Background Image'), 'akIsSearchable' => false));
}


Hope that helps!

-Jordan
Adreco replied on at Permalink Reply
Adreco
Oops. I need to quit typing before having my morning coffee! (I assumed Barry was wishing to edit an existing theme, not create a new one with a dynamic background/logo edit feature)
Thanks for the thoughtful answer Jordan.
novelnova replied on at Permalink Reply
novelnova
Cheers for this, much appreciated
allcomm21 replied on at Permalink Reply
I’m trying to use a background image on my home (index) page. I've done what you said in your first paragraph, and I've added the attribute to the page properties. I've entered the code in the header.php, but I think I have a problem with what the RelativePath is. After finding the image using the MacHighway Web Disk utility, this is the best I can determine:
[...
$bg_img_src = $bg_img->getRelativePath("/home/allcommc/public_html/allcomm21-osd.com/index/files/8113/1216/7626/highway_with_sign.jpg");
...]
(allcommc is my main site on MacHighway)

But when I reload the page, I get this error message:
“Fatal error: Call to a member function getRelativePath() on a non-object in /home/allcommc/public_html/allcomm21-osd.com/index/concrete/themes/dark_chocolate/elements/header.php on line 14”

Is the problem in the RelativePath?
jordanlev replied on at Permalink Reply
jordanlev
I think you're misunderstanding the way that code works. You don't give it an image path, instead you choose an image from the file manager (so edit the page in question, click the "Properties" toolbar button, click the "Custom Attributes" tab, click the "**Add Attribute" dropdown list and choose the custom attribute you created for this purpose -- this will let you choose an image from the file manager and that image will be used in the code. (Just make sure your code matches the code samples I have up above -- not what you have because what you have won't work because you can't pass an image path into the getRelativePath() function).

Good luck!

-Jordan
allcomm21 replied on at Permalink Reply
Got it!. Cool, thanks.
spjuphigh replied on at Permalink Reply
spjuphigh
Jordan - I did what you said, and it worked perfectly! However, if I add a child page below the page I added the background image to, it throws the following error:

Fatal error: Call to a member function getRelativePath() on a non-object.... <insert location in code>.

How do I stop this? Do I have to go in and set values for these attributes on each page, even though it's a child of the one that has the attributes set? (I thought the child page just took its setup from the parent - unless changed?)
jordanlev replied on at Permalink Reply
jordanlev
Child pages do not inherit attributes (or anything at all -- except permissions I think) from their parent pages. So yeah, you need to set the background image on the new page too.
The most you can do is modify the code to check if the call to $c->getAttribute() actually returns an image, I think like this:
<?php
$bg_img = $c->getAttribute('background_image');
if ($bg_img && is_object($bg_img)) {
    $bg_img_src = $bg_img->getRelativePath();
    ?>
    <style type="text/css">
    body {
        background-image: url(<?php echo $bg_img_src; ?>);
    }
    </style>
<?php } ?>

This will make it so if you forget to set the background image on a page, it reverts to the regular background image (as defined in your theme stylesheet) instead of showing an error.
drconsolidated replied on at Permalink Reply
I'm trying to use this technique to add a background image to a full width section of my site without any luck. I added this code to my header, below the header required snippet:
<?php
      $bg_img = $c->getAttribute('gymMatPat');
      $bg_img_src = $bg_img->getRelativePath();
   ?>
   <style type="text/css">
      .bar4 {
        background: url(<?php echo $bg_img_src; ?>) repeat;
      }
   </style>

The file, gymMatPat.png, is located in the 'img' directory in the theme directory. Next, I went to the dashboard and created a new Image/File attribute with the handle gymMatPat.

For some reason it is still not working. Any idea what the problem could be?

I also posted the issue on StackOverflow out of desperation:http://stackoverflow.com/questions/17642165/concrete5-background-im...
jordanlev replied on at Permalink Reply
jordanlev
This code works with files in the file manager -- see one of the other comments in this thread for an explanation of how to upload the images to the file manager and assign them to the attribute:http://www.concrete5.org/community/forums/themes/customising-theme-...
drconsolidated replied on at Permalink Reply
Oh, okay, I see. So I updated it accordingly, and it is still not working. When I add the code to a page-type template, it makes the page completely unusable. When I navigate to it, it is just a blank page. Any idea what could cause this? Thanks!
baryongroup replied on at Permalink Reply
baryongroup
I'm fairly new to Concrete5, but I did this by creating a file set for my logo, named "Logo", where I only add 1 logo file in the set, and put the following code into my theme where the logo should be. I'm sure there's a better way to do this, but it worked for me:

<?php
//Add Logo from "Logo" set
Loader::model("file_set");
Loader::model('file_list');
$fs = FileSet::getByName('Logo');
$fl = new FileList();
$fl->filterBySet($fs);
$files = $fl->get();
if (count($files) === 1) {
foreach($files as $f) {
print '<a href="/"><img title="' . $f->getTitle() . '" src="' . $f->getDownloadURL() . '" /></a>';
}
}elseif (count($files) > 1) {
print "Please only set 1 image in the 'Logo' set";
}
?>

Shane Crockett
LocalPlugs, LLC
http://www.localplugs.com
jordanlev replied on at Permalink Reply
jordanlev
I think your way is just fine (hey, it works right :)

But I think a simpler alternative would be to hard-code a scrapbook block into your theme. Just add this to your theme page type template where needed:
<?php Block::getByName('Logo')->display(); ?>


Then go to Dashboard -> Scrapbook, create a new global scrapbook (call it whatever you want), then add an "image" block to that scrapbook. After you've added the image block, change the block name in the scrapbook list to "Logo".

Note that there is a difference between your situation and the OP's -- in your case you just have one image that appears in many places throughout the site. But the OP wanted to be able to change that image on a per-page basis. So that's why you'd choose one approach over the other.
baryongroup replied on at Permalink Reply
baryongroup
I'm still learning, and this is definitely awesome that the community is pretty responsive around C5. Thanks for the tip! A lot better and easier to manager than mine :)

Shane~
nico741019 replied on at Permalink Reply
Hello,

i'm trying to follow your procedure to add a picture in my theme, but nothing happens; i added the attribute to my page, and i updated the header.php located in /www/concrete/themes/dark_chocolate/elements like this:


<?php defined('C5_EXECUTE') or die("Access Denied."); ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>

<!-- Site Header Content //-->
<link rel="stylesheet" media="screen" type="text/css" href="<?php echo $this->getStyleSheet('main.css')?>" />
<link rel="stylesheet" media="screen" type="text/css" href="<?php echo $this->getStyleSheet('typography.css')?>" />


<?php Loader::element('header_required'); ?>

</head>
<body>
<div id="page">
<div id="headerSpacer"></div>
<div id="header">

<?php if ($c->isEditMode()) { ?>
<div style="min-height: 80px">
<?php } ?>

<div id="headerNav">
<?php
$a = new Area('Header Nav');
$a->display($c);
?>
</div>

<h1 id="logo"><!--
--><a href="<?php echo DIR_REL?>/"><?php
$block = Block::getByName('My_Site_Name');
if( $block && $block->bID ) $block->display();
else echo SITE;
?></a><!--
--></h1>

<?php
// we use the "is edit mode" check because, in edit mode, the bottom of the area overlaps the item below it, because
// we're using absolute positioning. So in edit mode we add a bit of space so everything looks nice.
?>

<div class="spacer"></div>

<?php if ($c->isEditMode()) { ?>
</div>
<?php } ?>

<div id="header-area">
<div class="divider"></div>
<div id="header-area-inside">
<?php
$ah = new Area('Header');
$ah->display($c);
?>
</div>

<?php if ($ah->getTotalBlocksInArea() > 0) { ?>
<div class="divider"></div>
<?php } ?>

<?php
$bg_img = $c->getAttribute('background_image');
$bg_img_src = $bg_img->getRelativePath();
?>
<style type="text/css">
body {
background-image: url(<?php echo $bg_img_src; ?>);
}
</style>
</div>
</div>

I begin with concrete5, so forgive me if i did something stupid...

Thanks

nicolas
hibernian56 replied on at Permalink Reply
hibernian56
Hi Nico,

I don't know if you got this solved. I had a similar issue but managed to get it fixed, this is what I did;

1. Create a page attribute, handle "bg_image", name "Background image", selected text is the type of attribute. (Don't use the quotes of course!!) This will give you a drop down menu later to choose your image name. Add the attributes to this, my ones where;
bg_about
bg_home
bg_contact_us
etc.

3. Create another text attribute, handle "page_bg_color", name "Page Background Colour". This will allow you to enter a different background color by page later by entering the hex code for the color, i.e. #ffffff for white, #000000 for black etc.

4. Create several images names as per your attributes, my ones where;
bg_about.gif
bg_home.gif
bg_contact_us.gif
etc.

5. REMOVE the code you placed into your header.php from your body section, i.e;
<?php
$bg_img =

6. IMPORTANT - place the following code in the <head> </head> markers BUT AFTER the <?php Loader::element('header......> code;
<style>
body {
background-image:url(<?=$this->getThemePath()?>/images/bg_<?php echo $c->getCollectionAttributeValue('bg_image');?>.gif);
background-repeat: repeat-x;
background-color: <?php echo $c->getCollectionAttributeValue('page_bg_color');?>
} 
</style>


7. This code assumes you use a vertical strip image, as it has the "repeat-x" attribute set so that it repeats the full width.

8. Grab a beer, sit back and relax. As you add pages you can add more attributes and thus more backgrounds.
jb1 replied on at Permalink Reply
jb1
If you want to make your background load a bit smoother try using the backstretch jquery script:
http://srobbin.com/blog/jquery-plugins/jquery-backstretch/...

It will fade in as well plus auto centre, auto resize and crop and look better on the iPhone.

JB
Blenderite replied on at Permalink Reply
Blenderite
At this point, I would be wary of a jquery solution. Jquery can cause painful conflicts with C5.

-Blenderite
harveyappleton replied on at Permalink Reply
harveyappleton
Developed a simple addon to do this for you across whole site, and free! :) -http://www.concrete5.org/marketplace/addons/background-image/...
pihlaka replied on at Permalink Reply
Harvey.. but it does not work for 5.7, 5.6.0 — 5.6.3.4 only ? .. as i seriously can not find it from settings ..

I just cant imagine, that so large production as Concrete5 makes adding background image so hard.. insane