markmcwilliams / wp-timeline

Easily record and display events from the past, present, and future! Check out the demo while things are being built ...
http://wpkid.com/timeline-demo/
7 stars 0 forks source link

Figure out the best way to include an archive template? #1

Closed markmcwilliams closed 11 years ago

markmcwilliams commented 11 years ago

I have a rough idea for the template (designed around Twenty Twelve) which can be dropped in the /twentytwelve/ folder, but how to include that within the plugin so the user would just need to activate a Child Theme for example?

Would I need to go down a different route?

Create some kind of function which outputs the HTML markup in any theme?

pmgllc commented 11 years ago

I'll venture being completely wrong but try to help anyway. I know that in Genesis, to create an archive for a CPT, you need only create a template file with the name format of the CPT as in archive-timeline.php and include a regular index/page/post template (without the normal "this is a template" verbiage in the file header).

That leads me to wonder if you can simply add an include function to the plugin to include that php file in the plugin folder or if you can even add that code to the timeline.php itself to fake out a template. I'd imagine the former more likely than the latter, but I am just giving you my best guess to go down a road to trial and error the way I would.

evansolomon commented 11 years ago

It's hard to tell from the question exactly how you're planning for this to work. If you're going to do this through a child theme (which you mention) then you can just put the template file in there like a regular theme. If you want to do it entirely through the plugin then you should probably check out the template_include filter.

emzo commented 11 years ago

Take a look at http://wordpress.stackexchange.com/questions/3396/create-custom-page-templates-with-plugins

markmcwilliams commented 11 years ago

Yup, I see I wasn't very clear on what I'm attempting Evan, apologies!

Because I want to release this on the WordPress.org Plugin Repo, I'd like to make the plugin compatible with at least the default themes. Because I'm creating a CPT, I can make use of the has_archive which gives me the /timeline/ index, and utilises the archive-timeline.php (as Jesse said). Without wanting the user to need to move any files into their current theme, I wanted to see if there was a way to include Child Themes within the plugin folder directly, and make them available within the Installed Themes of your WordPress Dashboard.

The template is trying to achieve a look something like http://demo.woothemes.com/statua/templates/timeline/ but mine could do with a little more redefining. The template will utilise the Post Title, whatever you insert in the Editor, and make use of the Date and Time you set using the built-in WordPress features.

I should maybe take a look at The Events Calendar and see how it includes their templates?

Anyway, I hope this gives you a better idea of what I'm hoping to achieve? :)

markmcwilliams commented 11 years ago

I looked at Google, but all it could throw up was what turned into the above commit. I'm genuinely not sure if I've done something wrong, but I'm also not 100% sure I like that approach?

As a thought, would using register_theme_directory(); work within the plugin? Just specify /wp-content/plugins/timeline/template/ was the place that included the Child Themes?

Really didn't enjoy looking at the code in The Events Calendar, it was more confusing to me than anything!

markmcwilliams commented 11 years ago

So next up on the agenda: find some nice Timeline Display code! :)

emzo commented 11 years ago

Try http://csswizardry.com/2011/03/coding-up-a-semantic-lean-timeline/

markmcwilliams commented 11 years ago

I'd seen that one before but lost a link to it, thanks once again; it's been implemented!

emzo commented 11 years ago

I'd suggest making it easier for theme developers to override the timeline templates provided by looking for the specific template files in the child/parent theme before deciding to use the template in the plugin. You can do this fairly easily by checking for a named template, something like this...

public function include_timeline_template( $template ) {

    if ( is_post_type_archive( 'timeline' ) ):
        $template_name = 'archive-timeline.php';
    elseif ( is_singular( 'timeline' ) ):
        $template_name = 'single-timeline.php';
    else:
        return $template; // return early if it's not a template we care about
    endif;

    $template = locate_template( array( $template_name ) );

    if ( empty( $template ) )
        $template = dirname( __FILE__ ) . '/template/archive-timeline.php';

    return $template;
}

This way, following WordPress theming standard practices, the timeline templates can be overridden by dropping template files in the theme directory. If no suitable templates are found in the child/parent theme, the templates from the plugin are used instead.

markmcwilliams commented 11 years ago

Yes, that's a very valid point!

Including a template is really just designed as the fallback method.

Because I have the checks in place for is_post_type_archive() and is_singular() I would just do something like ...

if ( empty( $template ) ) {

    if ( is_post_type_archive( 'timeline' ) )

        $template = dirname( __FILE__ ) . '/template/archive-timeline.php';

    is ( is_singular( 'timeline' ) )

        $template = dirname( __FILE__ ) . '/template/single-timeline.php';

    return $template;

}

In the bottom half of that function right?

emzo commented 11 years ago

I don't think that's quite right. I'm not 100% sure on this, haven't looked into it well enough, but from what I understand, the template path value provided by the template_include filter will never be empty. Unless WordPress can find a more specific template file, it'll always revert to using index.php, so even in the worst case scenario (no template found), your $template variable will contain the string value index.php.

I think you'll have to do what I've shown above, and use the locate_template() function, passing in an array of template files to search for in priority order. Since we only specify one possible template file to use in that array, if it doesn't exist, it'll return an empty string, and then we can use the template provided by the plugin. Does that make sense?

As I said, I haven't looked into this deeply, so I might be missing something, but try replacing your include_timeline_template function with the one I provided above and see if it works.

markmcwilliams commented 11 years ago

I'm maybe misunderstanding you slightly, let me try and explain.

Looking at the first 11 lines, we check in the Parent Theme for the two template files, we also check in the Child Theme for the two template files. Hopefully I'm understanding that part rightly? :)

With the last few lines, basically it's saying if $template is empty, use the fallback archive-timeline.php file which comes included inside the plugin. What about the single-timeline.php file, how will it know to include that? That's what my little snippet of code was hoping to achieve?

Have I got it wrong?

markmcwilliams commented 11 years ago

See my next commit, there was a problem with my code!

The return $template; was in the wrong place! :(

emzo commented 11 years ago

Sorry, just realised I have a mistake in my code, it should be...

public function include_timeline_template( $template ) {

    if ( is_post_type_archive( 'timeline' ) ):
        // if this is a timeline post type archive,
        // the template we want to use is 'archive-timeline.php'
        $template_name = 'archive-timeline.php';
    elseif ( is_singular( 'timeline' ) ):
        // if this is a singular timeline post type,
        // the template we want to use is 'single-timeline.php'
        $template_name = 'single-timeline.php';
    else:
        // we're not interested in anything else, so return early
        return $template;
    endif;

    // look for the template in child/parent theme directory
    $template = locate_template( array( $template_name ) );

    if ( empty( $template ) )
        // if we didn't find a template in the theme,
        // fall back to the one in our plugin
        $template = trailingslashit( dirname( __FILE__ ) ) . $template_name;

    return $template;
}

Looking at the first 11 lines, we check in the Parent Theme for the two template files, we also check in the Child Theme for the two template files. Hopefully I'm understanding that part rightly? :)

No, is_post_type_archive() and is_singular() have nothing to do with the actual template mechanism, they simply tell us that what kind of "page" we're working with.

With the last few lines, basically it's saying if $template is empty, use the fallback archive-timeline.php file which comes included inside the plugin.

Yes, that's right.

What about the single-timeline.php file, how will it know to include that?

This was the bug in my code, which the above fixes ;)

emzo commented 11 years ago

Ack, my bad again! If you'r plugin template is in a 'template' sub-directory within your plugin, the last but one line should be:

$template = dirname( __FILE__ ) . '/template/' . $template_name;

I'm going to send you pull requests from now on ;)

markmcwilliams commented 11 years ago

Oh don't worry, I figured out what you meant! :) They sound fun ... LOL

markmcwilliams commented 11 years ago

I think we can call this one complete!