0

I've worked with WP/html/css casually for a long while but never dug deep before, I have a few questions about good practices.

My Background - totally skip this if uninterested

I've been left temporarily in charge of a WP site as we look for another professional webdev to replace our previous one. I'm a software engineer by trade but my education and job experience never touched html/css much - only experience is building my own portfolio website and maybe a class project or two in school.

As I've been adding functionality and content, I've been digging into the ex-dev's code and organization of templates. A lot of it seems to be bad practice and bad use of general CS principles, but I'm not quite experienced enough to know if these things are "the only way" or actually good practice in this specific domain.

Questions

Are templates supposed to have hardcoded values in them?


For example, I created a new page that integrated our 3rd party storefront directly into our own domain, so I had to go update the buttons across the entire site that linked to the store. Only 2 or 3 places I had to go update, but this one page would not receive the change. Dug through the whole site before discovering that the URL had been hardcoded into the button in this one template that this one page used - my bad practice alarm bells go off. There are similar hardcoded values like URL's to an image file hosted on the domain, for headers or backgrounds or w/e, across tons of templates.

Answered: Is code for Pages and Posts supposed to be mixed?

Update: a post in wordpress is any content type (internally: post_type) (from comments below)


Based on this documentation the 1st line of that code is just a post tag and CSS code in the theme's style sheet will apply to posts with that tag. Am I misunderstanding terminology here? Perhaps "Posts" and "Pages" are frontend terminology and <?php post_class(); ?> is unrelated to literal Posts?

Do I need to hardcode the ID's for every page I want a certain CSS style applied to?


Say page "Content" has template A assigned to it (corresponding to page-a.php). Template A uses get_template_part() to grab template a-modified (under say ../template-parts/a-modified.php)

I went and made a "Content New" Page that uses the same template A as "Content". With no modifications to this new page, a few things in the header were messed up already. Based on this SO thread I figured out that everywhere in the CSS stylesheet the ID for "Content" (say 111) I had to duplicate that line for the ID 222 of "Content New", like so:

.page-id-111 .entry-header img,
.page-id-222 .entry-header img {
        width: 100%;
        left: 0;
}

Had to do this just under 20 times in the stylesheet to get the header of "Content New" looking just like "Content". Again seems like bad practice, and a pain in the ass anytime you want something new to use existing templates/functionality (or change the template applied to something that already existed). Is there no better way to apply the same CSS to all Pages that use template A?


Thanks for anyone that reads this, apologies for the novel. I couldn't find a solid answer for any of these types of questions, mostly threads where people give answers of what seems to be more bad practice or bad code.

  • 1
    "Perhaps "Posts" and "Pages" are frontend terminology", a post in wordpress is any content type (internally: post_type) existing in the wp_posts table. Both posts and pages are two types of a Post. A more in-depth explanation of the nomenclature – hwl Aug 5 '17 at 16:22
  • 2
    body_class() is useful for targeting specific templates. – Milo Aug 5 '17 at 16:30
  • 1
    Are templates supposed to have hardcoded values in them? One would hope not, at least not outside of their context. (i.e. a theme folder loading images may hardcode the relative url to the images folders, etc.) WP makes several functions available to aid in this: get_site_url(), get_stylesheet_directory(), get_template_directory() – hwl Aug 5 '17 at 16:33
  • 1
    Also, if you haven't read through Plugin Developers Handbook and/or Theme Developers Handbook they can cover a lot of ground for you. – hwl Aug 5 '17 at 16:39
  • 2
    Also note that these css functions have filters, so you can set up your own logic with conditions for adding special classes. – Milo Aug 5 '17 at 16:43
3

No, don't hardcode the ID's for pages in your CSS. You might want to use the same styles elsewhere, or if the stylesheet is cached for users, they might not immediately see your changes you push up if you don't version the stylesheet. Not only that it makes deciphering your styles just that much harder in the long run!

Yes the terminology can be a bit confusing if you're not used to WordPress. A page actually is a post technically as are a lot of other things. If your page template includes a call to post_class() - then the classes from core would be outputted on the tag that makes use of post_class(). This can be useful to target the display of a particular post type/format, or conditionally adding your own classes to it with a filter for different displays in different contexts.

There's several ways to target the elements based on where they come from, and how you want your styles to carry over in WordPress.

In your situation, yes you could hardcode the IDs, but I wouldn't really say it's a good choice - but that's just my opinion. If your plan is to create the new content, and eventually once it's done you will be removing the old content page which uses the same template - then it's probably best to create a new page template with a new name altogether in the mean time. A body class would be applied for you to use for specific styles on that template, so you would write your CSS definitions namespaced for that:

.page-template-your-custom-template .entry-header img,
.page-template-your-custom-template .entry-header img {
    width: 100%;
    left: 0;
}

You would then know that you are styling specifically things for that template, and won't confuse yourself in the future. You don't have to run back to the admin to see what page template something is using, and reading your stylesheet will make more sense.

Just like post_class() method, there's also a body_class() method which adds classes to the body element. The other option would be to conditionally add a body class to the page, so you can take care of it that way.

Take for example:

Working from the top down, probably in your theme's header.php there's a method body_class() on <body>.

You could add your own classes to this with the body_class filter, and then check for the page ID you want to manipulate with is_page() in your functions.php file - for example:

function theme_namespace_your_body_class( $classes ) {
    if ( is_page( array( 111, 222 ) ) ) {
        $classes[] = 'your-custom-body-class';
    }
    return $classes;
}
add_filter( 'body_class', 'theme_namespace_your_body_class' );

Now instead of writing out something like this:

.page-id-111 .entry-header img,
.page-id-222 .entry-header img {
    width: 100%;
    left: 0;
}

You stylesheet would have:

.your-custom-body-class .entry-header img {
    width: 100%;
    left: 0;
}

So once you're all done with your modifications, if you ever need to apply these styles to other pages, posts, templates or whatever - you can simply modify that method above to include other page ID's or use a variety of WordPress conditionals to apply those same styles elsewhere depending on the context.

Additionally if someone has the stylesheet cached, you're not forcing yourself to update your stylesheet version number with each minor change you're doing to bust the cache. Your PHP code is dictating what classes to apply and saying this is how this page, post, or whatever should be structured, while your stylesheet remains a stylesheet controlling how things in those contexts should actually appear.

From that top level, the same exact things can be done moving deeper on the post_class() level, and use something like is_single() to check if the post in the query is for the IDs you want to include the class on that element for. Take for instance this:

function theme_namespace_your_post_class( $classes ) {
    if ( is_single( array( 111, 222 ) ) ) {
        $classes[] = 'your-custom-post-class';
    }
    return $classes;
}
add_filter( 'post_class', 'theme_namespace_your_post_class' );

Now your element using the post_class() method will conditionally have that class included for those post IDs.

Just like creating a new page template - you can do this for posts. You could create a file like your-custom-post-single-post.php and designate it's for just posts to use:

<?php
/*
 * Template Name: Your custom template
 * Template Post Type: post
 */

Or maybe you want the same template to be able to be used for pages and posts:

<?php
/*
 * Template Name: Your custom templatee
 * Template Post Type: post, page
 */

You should definitely look into the WordPress template hierarchy as you expand upon your theme, and what works best for you might be a completely different solution, but that will definitely help guide you on what things belong where, and how to better structure your theme. Looking at a starter theme such as _s, or even any of the twentywhatevers to see how they structure things, is also a good way to see some of the best practices and methods of doing thing.

This all doesn't mean it's absolutely forbidden or a bad practice to use page or post IDs for styles, but I believe in 99% of those situations it's not necessary.

  • Thank you very much for both reading the post and answering in such great detail! To me it certainly seems like the current theme's structure and code creates unnecessary work, which in my mind translates to bad practice. What sort of 1% situation would it be useful to hardcode ID's in styles? As an aside, funny enough our WP has 3 of those twentysomething themes installed (not being used). Not sure if the original dev installed them to use as a reference, but none of his work seems to follow their structure. Will certainly look at those and _s. Thanks again <3 – Murkantilism Aug 5 '17 at 17:02
  • 1
    NP! :) I mean, if you had like an image that needed a slight bump in position for a particular post, then it might be okay - but even then maybe the image should be reprocessed to fit appropriately how you want it to. Maybe you need to highlight a particular item in a menu so you could do that with css instead of using js to add a class. That kind of stuff I guess is about the furthest I'd go to say it's okay. Those themes are included by default - they are a good reference/baseline as well if you write a plugin and need to test if a theme conflicts or if it's just your plugin. – Tim Elsass Aug 5 '17 at 19:30
  • Ah word, didn't know they were defaultly installed. Thanks mate – Murkantilism Aug 6 '17 at 1:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.