ThemeShaper Forums » Thematic

[closed]

Different backgrounds on post

(50 posts)
  • Started 12 years ago by soren
  • Latest reply from daveread
  • This topic is resolved
  1. Hello!

    I have 25-30 different images that I want to use as backgrounds depending on topic of the post. I got this few lines that you should put in "single.php"

    if(is_single('17')){
    // When Post 17 (ID) is being displayed.
    
    echo "<style>
    body{
    background: #000 url(images/bgbody.jpg) top center no-repeat;
    }</style>";
    }

    I think this is might be good for few images...
    Is there a way to use function.php to get a different background image on post? The idea is that it will be behind the first paragraph of text and in the top left corner.

    Any thoughts on this?

    Thanks
    Soren

    Posted 12 years ago #
  2. This is one of those things that can be done a bunch of different ways. Since I like messing with CSS a whole lot more than the php, I would suggest CSS over single.php/function.php code (unless you built a way to select them into the WP interface, which is the most work but probably the best).

    Either way you can target them with CSS, there are plenty of classes to use, the postID in the body class, or only the post itself. The example below would target single posts.

    .single .post-17 { background: #000 url(images/bgbody.jpg) top center no-repeat; }

    Posted 12 years ago #
  3. agreed. i think thematic's dynamic body classes will be best.

    to get body classes, post classes and a few other thematic things make sure this is in your child's functions.php

    //Thematic 0.9.7.6 compatible
    define('THEMATIC_COMPATIBLE_BODY_CLASS', true);
    define('THEMATIC_COMPATIBLE_POST_CLASS', true);
    define('THEMATIC_COMPATIBLE_COMMENT_HANDLING', true);
    define('THEMATIC_COMPATIBLE_COMMENT_FORM', true);
    define('THEMATIC_COMPATIBLE_FEEDLINKS', true);
    Posted 12 years ago #
  4. @ScottNix

    Thanks I will have a look at CSS to begin with... but I guess it is not best way.... when you start getting over 1000 posts that will be another 1000 lines in CSS and probably slow down the website...

    Posted 12 years ago #
  5. @helgatheviking

    Could you by any chance give me an example how to use the body classes to start work with?:)

    I have also seen suggestions using custom fields...

    Thanks
    Soren

    Posted 12 years ago #
  6. scottnix already gave you one.

    regular body background looks like:

    body { background: red;}

    but attaching class makes it more specific and thus takes preference

    .post-17 {
       background: blue;
    }

    similarly

    .post-17 .entry-content{
       background: green;
    }

    is more specific than

    .entry-content {
       background: yellow;
    }

    but if you are going to be doing a different backgruond for every post then i think you might be right a more php oriented version might be in order. what about attaching the bg as meta data (either as a custom field or generating out a full meta box)?

    then you could add a single inline style in the head that should supercede anything in style.css

    function new_background(){
     if(is_single('17')){
         $bg = "body{background: #000 url(images/bgbody.jpg) top center no-repeat;}";
      }
    echo "<style>" . $bg . "</style>";
    }
    add_action('wp_head','new_background',99);
    Posted 12 years ago #
  7. If I use the custom field I guess I need to position with CSS

    Is this a correct function?

    function new_background(){
    if (is_single()) {
    $background = get_post_meta($post->ID, 'background', true);
    }
    add_action('wp_head','new_background',99);

    Thanks for your time
    Soren

    Posted 12 years ago #
  8. Did some modification, perhaps better...

    function new_background(){
    if (is_single()) {
    
    $background = get_post_meta($post->ID, 'background', true);
    
    if ($background) {
    
    <style type="text/css">background: url(bloginfo('template_url')top center no-repeat;</style>
    }
    }
    }
    add_action('wp_head','new_background',99);
    Posted 12 years ago #
  9. that looks pretty good. the key question is... does it work?

    Posted 12 years ago #
  10. Well my previous attempts did not work..

    the solution @helgatheviking suggested did work thanks... but... with this I need to create a new function for every single post as I need to call the specific post and the specific image...

    Is there a way to avoid this?
    Thanks for all help

    function new_background(){
     if(is_single('5252')){
         $bg = ".entry-content{background: #FFF url(wp-content/uploads/images/A.png) top left no-repeat;";
      }
    echo "<style>" . $bg . "</style>";
    }
    add_action('wp_head','new_background',99);
    Posted 12 years ago #
  11. soren, you said: "25-30 different images that I want to use as backgrounds depending on topic of the post". Is it a category, tag, or some other taxonomy decision?

    In your last post, you assign "A.png" to a specific post ID. It seems what you really need is a modification to that line to output "known" png's depending on your criteria. On a one by one basis (tedious), you could assign the names of the png's to the post id after the fact:

    $bg = ".entry-content{background: #FFF url(wp-content/uploads/images/<?php the_ID(); ?>.png) top left no-repeat;";

    So instead of using 'A.png' for a name, name the image with it's post ID. There are other ways to streamline this as well, perhaps based on a Category or specific Taxonomy.

    -Jeff

    Posted 12 years ago #
  12. Jeff,
    Yes it is letters I want to use faded caps in the background of the post so it can be the whole alphabet in the end. I have seen this in several magazines and like the typographic design and want to implement it to my website. I am playing around with it but do have some problem position it. Using margins moves the whole thing and not only the background... :(

    Thanks
    Soren

    Posted 12 years ago #
  13. Jeff, you mean like this?

    function new_background(){
     if(is_single()){
         $bg = ".entry-content{background: #FFF url(wp-content/uploads/images/<?php the_ID(); ?>.png) top left no-repeat;";
      }
    echo "<style>" . $bg . "</style>";
    }
    add_action('wp_head','new_background',99);

    To name the image with it's post ID will fill up my image folder I will then have several "A" instead of one only that I can use several of times. I am not there yet but If I will be using it a lot this problem will occur, just trying to find a smart way doing this in a proper way. About the margin I have tried to change ".entry-content" with body, wrapper, etc but then I have problem position it. I used margin-top: 400px and margin-left: -100px; but everything moves when putting this into the code. How do you position only the background image? I want it behind the post but a little of to the left to just break the line a little...

    Thanks
    Soren

    Posted 12 years ago #
  14. sounds like you need the "background-position" attribute in CSS.

    Posted 12 years ago #
  15. Perhaps a "custom field" in your posts. Your code can check the value of the custom field and assign 'A.png', or whichever, based on that.

    Posted 12 years ago #
  16. Jeff, thanks I will try with "custom field". Have been playing around with "background-position" it works...but... this get complicated :)! The problem is that the background moves when you resize the window when I have the background in "wrapper or body". ($bg = "#wrapper{background: #FFF url...) If I use the "content" the background follows the post but then I can not brake the"content" frame. I need to get the caps to "stick out" of the content frame but still be inte the same position within the text in the post when resizing the window!!

    When you fix one thing the next problem shows up!

    Thanks
    Soren

    Posted 12 years ago #
  17. Perhaps someone else knows how, but I don't think you can get a background image outside it's container.

    -Jeff

    Posted 12 years ago #
  18. kwight
    Member

    Are you using Featured Images in your posts? If not, you could assign whichever appropriate PNG as the Featured Image and style accordingly.

    Otherwise, you could filter the_content and add the image there, pulled from a custom field:

    function kwight_add_background_letter($content) {
    	if(is_single()) {
    		global $post;
    		$background = get_post_meta($post->ID, 'background', true);
    		$img = '<img class="bg-letter" src="' . get_bloginfo('stylesheet_directory') . '/img/' . strtolower($background) . '.png" />';
    		$content .= $img;
    	}
    	return $content;
    }
    add_filter('the_content','kwight_add_background_letter');

    Then set the background image as absolute in CSS, and use the z-index to push it to the back:

    .post {
    	position: relative;
    }
    
    .bg-letter {
    	position: absolute;
    	top: 0;
    	left: 0;
    	z-index: -1;
    }

    You could also use a custom walker (one of my new favourite things) to insert the img tag directly at the top of the post's HTML output. It would be cleaner and not require the z-index stuff, but it would be more work than just filtering the_content.

    Posted 12 years ago #
  19. @Jeff
    it is possible to display background images outside a div...
    using css pseudo classes
    :before or :after

    just threw a quick demo together
    http://virtualpudding.com/stuff/index.html

    #wrapper {
    	position:relative;
    	width:900px;
    	margin:auto;
    }
    .box {
    	height:200px;
    	width:200px;
    	background:#000;
    	color:#fff;
    	padding:20px;
    	font-size:18px;
    }
    .box:before {
    content:"";
    background-image:url(joy.jpg);
    width:500px;
    height:477px;
    display:block;
    position:absolute;
    right:0;
    }

    you can style :before however you like, therefore having its own background image. specifying absolute positioning we can force it out the containing div.

    note, these classes are not supported on ie6 & 7, as far as i know 8+ ok but not tested.

    Posted 12 years ago #
  20. @kwight

    Looks like a great solution, but I have problem getting the background image to the post. I get the "?" mark all the time. Tried to change the path but it does not help example below...

    The image ("?") is still in the content but I guess you can display the image outside the div together with Jonny's ":before"...

    Thanks a lot!

    function kwight_add_background_letter($content) {
    	if(is_single()) {
    		global $post;
    		$background = get_post_meta($post->ID, 'background', true);
    		$img = '<img class="bg-letter" src="/wp-content/uploads/images/' . get_bloginfo('stylesheet_directory') . ' /img/' . strtolower($background) . '.png" />';
    		$content .= $img;
    	}
    	return $content;
    }
    add_filter('the_content','kwight_add_background_letter');
    Posted 12 years ago #
  21. @soren: you don't need the '/wp-content/uploads/images/' part of your $img src= URL calculation. From get_bloginfo onwards is all you need.
    $img = '<img class="bg-letter" src="' . get_bloginfo('stylesheet_directory') . ' /img/' . strtolower($background) . '.png" />';

    @Jonny Janiero: Looks good. I knew someone would know how. :)

    -Jeff

    Posted 12 years ago #
  22. kwight
    Member

    Oh, I should have specified that the code, as it's written, will look for a file called "[lowercase letter].png" in an "img" subfolder of your theme, eg. /wp-content/themes/mytheme/img/f.png (that's what the get_bloginfo() and strtolower() are looking after). To use an uploads/images folder, as you seem to be doing, the following should work:

    function kwight_add_background_letter($content) {
    	if(is_single()) {
    		global $post;
    		$background = get_post_meta($post->ID, 'background', true);
    		$img = '<img class="bg-letter" src="' . get_bloginfo('url') . '/wp-content/uploads/images/' . strtolower($background) . '.png" />';
    		$content .= $img;
    	}
    	return $content;
    }
    add_filter('the_content','kwight_add_background_letter');

    Using strtolower() also means that the user can enter "A" or "a" and the code will choose the file called "a.png".

    I should also mention to our viewers that using a custom walker, mentioned above, is only for menus (see how much I love them? I try and use them no matter what).

    And I missed another method rather than mucking with the the_content filter; we could use the childtheme_override_single_post() override:

    function kwight_add_background_letter() {
    		global $post;
    		$background = get_post_meta($post->ID, 'background', true);
    		$img = '<img class="bg-letter" src="' . get_bloginfo('url') . '/wp-content/uploads/images/' . strtolower($background) . '.png" />';
    		return $img;
    }
    
    function childtheme_override_single_post() { 
    
    				thematic_abovepost(); ?>
    
    				<div id="post-<?php the_ID();
    					echo '" ';
    					if (!(THEMATIC_COMPATIBLE_POST_CLASS)) {
    						post_class();
    						echo '>';
    					} else {
    						echo 'class="';
    						thematic_post_class();
    						echo '">';
    					}
    
                                    // Insert background letter image
                                    echo kwight_add_background_letter();
    
         				thematic_postheader(); ?>
    					<div class="entry-content">
    <?php thematic_content(); ?>
    
    						<?php wp_link_pages('before=<div class="page-link">' .__('Pages:', 'thematic') . '&after=</div>') ?>
    					</div><!-- .entry-content -->
    					<?php thematic_postfooter(); ?>
    				</div><!-- #post -->
    		<?php
    
    			thematic_belowpost();
    }
    Posted 12 years ago #
  23. @Jeff,

    Sorry but I dont get it... :(
    What do you mean by "All I need is from "get_bloginfo"?
    I tried change the path ('stylesheet_directory') to ('wp-content/themes/my_theme/') but I still have the "?"
    I then also put in the path after stylesheet_directory...

    get_bloginfo('wp-content/themes/my_theme/') . ' wp-content/uploads/images/' . strtolower($background) . '.png" />';

    That did not work... I still have "?"
    I also change the custom field value to the full path to the image but still "?"!!!

    What is the secret sauce for the path to work? Or is there something I do totally wrong?

    Thanks
    Soren

    Posted 12 years ago #
  24. kwight
    Member

    'stylesheet_directory' is not to be replaced, it's a parameter of get_bloginfo():

    http://codex.wordpress.org/Function_Reference/get_bloginfo

    If this is confusing, and you just want to have your images in wp-content/uploads/images, then just use the code I mentioned above:

    function kwight_add_background_letter($content) {
    	if(is_single()) {
    		global $post;
    		$background = get_post_meta($post->ID, 'background', true);
    		$img = '<img class="bg-letter" src="' . get_bloginfo('url') . '/wp-content/uploads/images/' . strtolower($background) . '.png" />';
    		$content .= $img;
    	}
    	return $content;
    }
    add_filter('the_content','kwight_add_background_letter');

    This will make more sense if you use Firebug (getfirebug.com) for troubleshooting; you'll be able to see what each part of the code is contributing to the URL.

    Posted 12 years ago #
  25. There is no image showing up on the post I have used with customfield...

    In Safari I get the "?" with the the blue box and in Firefox I get nothing so with firebug I can't see anything regarding the background image!
    I moved the image to a new folder (Background_letter) to be sure there was no interference with other images that have ".png" and update the paths but that did not help...

    @kwight I tried both your examples but no images shows up in the background! There is something I do wrong but I can't figure it out... I have used full path to the image in custom field value as well but now back to "wp-content/uploads/images/a.png"

    I almost go crazy by now....

    Thanks
    Soren

    Posted 12 years ago #
  26. @kwight,

    If I use "strtolower($background) . '.png" />';" I get this error when trying to download the image from Safari:
    Safari can’t show the file “a.png.png” in the Finder because “a.png.png” has not yet been created.

    If I use "strtolower($background) . '" />';" I get this error when trying to download the image from Safari:
    Safari can’t show the file “a.png” in the Finder because “a.png” has not yet been created.

    Can it be something with the code that makes the paths not working!?

    Thanks
    Soren

    Posted 12 years ago #
  27. OK, it seems like the path get double managed when you have it in the code. By removing the path and the ".png" the background finally shows up!

    function kwight_add_background_letter($content) {
    	if(is_single()) {
    		global $post;
    		$background = get_post_meta($post->ID, 'background', true);
    		$img = '<img class="bg-letter" src="' . get_bloginfo('url') . '' . strtolower($background) . '" />';
    		$content .= $img;
    	}
    	return $content;
    }
    add_filter('the_content','kwight_add_background_letter');
    
    Soren
    Posted 12 years ago #
  28. So ... do you have any hair left? :)

    It appears that you are supplying the path as the value in your custom field where I think we were assuming you were only supplying 'A';

    If you ever decide to change something, or move stuff around, you will now have to go back to each post and edit the value of your custom field for every post.

    I think the only value you should put in your posts for the custom field is the letter you want to use. Then have the code determine the URL and if you change anything, you only have to edit the code once. That is what the code kwight supplied does for you. What you have in your last example depends on the full path in the value parameter of your custom field and while it works now, it may not be what you want over the long haul.

    -Jeff

    Posted 12 years ago #
  29. Jeff,

    You are absolutely correct, this will be changed!
    Thanks I do still have some hair left but I do stil have the position problem left to fix!

    I can not get outside of the "content div" left margin with the background (just need 50-100px outside the content div depending on letter for example the letter "T") I tried the ":before" with the class "bg-letter" but that did not work in this case...

    I then tried to change the code from "$content" to "$wrapper" and "$body" but that did not move the background so I could position it where I want....

    Still one problem to fix :)

    Thanks

    Posted 12 years ago #
  30. kwight
    Member

    Do you mean like this?

    http://kirkwight.com/thematic/screenshot.png

    If so, use the code as I gave it to you above (using just the letter in the custom field as diverge said), and use negative values for top: and left:

    .bg-letter {
      position: absolute;
      top: -30px;
      left: -25px;
      z-index: -1;
    }

    Then set the wrapping divs to overflow: visible:

    #content,
    #container,
    #main {
    	overflow: visible;
    }

    If I'm not understanding you, just put up a sketch or give an example online so that we know what we're going for.

    Posted 12 years ago #

RSS feed for this topic

Topic Closed

This topic has been closed to new replies.