I know how to enable/disable comments on all pages. But how can I enable only a few, WITHOUT USING THE UI. In functions.php I just wanna go
if($this_is_a_page_i_want_comments_on) { enable_comments(); }
enable_comments(); doesn't exist, this is the part I need help with.
I could do this using WordPress Admin by allowing comments on all pages, then going to each page and disabling comments where I don't want them. This would take too long though.
P.S. I'm using Genesis framework.
Simply hook to the comments_open filter :) If you look-up in the source how the comments_open() function works, you'll notice that the function gets the post in question and then runs it's reposnse through the comments_open filter. Here's an example function to override that:
function my_override_comments_open( $open ) {
if ( $this_is_a_page_i_want_comments_on ) {
$open = true;
}
return $open;
}
add_filter('comments_open', 'my_override_comments_open', 1000);
I assume that you know how you'll identify the pages that you want to enable comments on - so that's up to you.
PP: I don't know if it will work in Genesis or not(I presume that it should though).
if (is_single('page_name_here') || is_single('other_page')) {
// Show the comment form here
}
Not sure if there's a better way, that's just my solution!
Related
I have a WordPress site that has a standard Page called Places with URL
example.com/places/
And I have several child Pages called by cities
example.com/places/city-1
example.com/places/city-2
Now, I have a custom post type Place that should indicate a single place and should have permalink like
example.com/places/place-1
But then if I go to one of the previous links with city-1, city-2 I get 404 obviously because there is no place with that permalink.
Is there a way for WordPress to drop to previous permalink. So if there is no place with that name, look for a page with it.
You could probably use the the REFERER-value from the PHP server variable $_SERVER, but it´s not very reliable and can be altered.
I am using the plugin "Permalink Finder" in one of the pages I am maintaining and that works quite well for finding changed URL. You could give it a try and see if it works for you, too.
In case somebody ever having a similar problem, it can be done by using verbose page rules. This is an example I found at WordPress Stack Exchange
https://wordpress.stackexchange.com/questions/22438/how-to-make-pages-slug-have-priority-over-any-other-taxonomies-like-custom-post
add_action( 'init', 'wpse16902_init' );
function wpse16902_init() {
$GLOBALS['wp_rewrite']->use_verbose_page_rules = true;
}
add_filter( 'page_rewrite_rules', 'wpse16902_collect_page_rewrite_rules' );
function wpse16902_collect_page_rewrite_rules( $page_rewrite_rules )
{
$GLOBALS['wpse16902_page_rewrite_rules'] = $page_rewrite_rules;
return array();
}
add_filter( 'rewrite_rules_array', 'wspe16902_prepend_page_rewrite_rules' );
function wspe16902_prepend_page_rewrite_rules( $rewrite_rules )
{
return $GLOBALS['wpse16902_page_rewrite_rules'] + $rewrite_rules;
}
I've been asked to fix a problem on a wordpress site. The problem is caused by the fact posts should of been used instead of pages. However the site is up and running and quickest option would be to fix the problem using a hack of sorts.
The site has an events section, each event is a page (this is the issue, should really be a post). In order to have upcoming and past events the post date is used, therefore upcoming events has a post status of 'future'.
There's are list page of events which shows them fine by using the correct query_post(). Although the problem arises when you click through to actual event (which is a future page). If your logged in as an Admin then the page shows but if your not logged in you get a 404 page.
Now if they where posts then the "The Future is Now!" plugin would solve this problem. I have a feeling the only way round the problem is to rewrite part of core Wordpress files.
Any advice would be great, I have a lot of experience with Wordpress so even if you can point me in the right direction.
Cheers,
Jason
[Update]
Thanks maiorano84 for your detailed response. In the long run I intend to move them to posts but in the meantime they've requested we fix it asap without changing any urls (today they sent out a mass email with a list of events without checking any links)
Your solution of including post_status future doesn't work in this case as wordpress doesn't get to the stage of loading the template. Something in wordpress core stops it from getting that far. Ideally if they was a hook I could use to override this behavior in the meantime that would be excellent but if it comes to it I will temporarily edit the core files.
[Update 2]
I now know the two functions that need editing or use a hook that relates to them.
First of we is_404() which needs changed to not add future pages as 404
Second we have is_page() need to return true if a page is future
[Update 3]
I've found how to do this in the core. If you go to wp-includes/query.php line 2682. Copy this in instead of the old function it works correct. If you have a better way please let me know. Thanks.
/** Future Pages **/
// Check post status to determine if post should be displayed.
if ( !empty($this->posts) && ($this->is_single || $this->is_page) ) {
$status = get_post_status($this->posts[0]);
$post_status_obj = get_post_status_object($status);;
if ( !$post_status_obj->public ) {
if ( $post_status_obj->protected ) {
$this->is_preview = true;
print_r($status);
if ( 'draft' != $status ) {
$this->posts[0]->post_date = current_time('mysql');
} else {
$this->posts = array();
}
} elseif ( $post_status_obj->private ) {
if ( ! current_user_can($read_cap, $this->posts[0]->ID) )
$this->posts = array();
} else {
$this->posts = array();
}
}
/** END **/
You can actually add a post_status parameter of 'future' to your page queries. You REALLY shouldn't be modifying your core files in order to do what you want. So on your page.php and archive.php templates (or other relevant templates that's controlling your Event display), you can do something like this:
<?php
$params = array('posts_per_page'=>-1, 'post_status'=>'publish,future');
$query = new WP_Query($params);
if($query->have_posts()) : while($query->have_posts()) : $query->the_post();
?>
<!-- YOUR PAGE HTML HERE -->
<?php
endwhile;endif;
wp_reset_postdata();
?>
This is an oversimplification, but using the correct queries in the corresponding files will allow you to display your pages however you like.
More information here: http://codex.wordpress.org/Class_Reference/WP_Query
Another thing worth considering, and I realize that this wasn't a part of your question, but may very well solve your issue:
Why not create a subdomain on your client's server where you can work on fixing everything without interrupting the user experience? You can easily either import the existing database into your development environment, and make all the changes you need without affecting the live version.
Food for thought. My advice would be to nip this in the bud, and convert the pages over to posts as soon as possible, otherwise the website will turn into a giant mess very quickly, but that's your call.
Hope this helps.
UPDATE:
I would still advise against altering the core files, but if it's a last resort until everything gets fixed, then have at it. Here's is a "WP Friendly" solution I think might help:
add_action('wp','future_redirect', 0);
function future_redirect($WP_Object)
{
$page = is_page() ? get_page(get_the_ID()) : false;
if($page && $page->post_status == 'future')
{
wp_redirect(/*YOUR REDIRECT URL*/);
exit();
}
return $WP_Object;
}
I'd like to use a custom post type archive as a site's front page, so that
http://the_site.com/
is a custom post type archive displayed according to my archive-{post-type}.php file.
Ideally I would like to alter the query using is_front_page() in my functions.php file. I tried the following, with a page called "Home" as my front page:
add_filter('pre_get_posts', 'my_get_posts');
function my_get_posts($query){
global $wp_the_query;
if(is_front_page()&&$wp_the_query===$query){
$query->set('post_type','album');
$query->set('posts_per_page',-1);
}
return $query;
}
but the front page is returning the content of "Home" and seems to be ignoring the custom query.
What am I doing wrong? Is there a better way, in general, of going about this?
Note: I did post this in WordPress Answers but that community is comparatively tiny.
Posting the final solution as an answer (Isaac placed it as a comment) just for anyone still looking.
Isaac was on the right track with adding a filter via functions.php. What he did wrong was call is_front_page(), which doesn't work yet because we're in pre_get_posts and the query hasn't been executed yet.
We do have the current page ID however. So we can still solve this, by looking into the WordPress option register for an option called page_on_front, which returns the ID of the page the user set as frontpage.
(For an overview of all WordPress options, just visit <yourwordpressinstallation>/wp-admin/options.php in your browser.)
Which makes for the following solution as suggested by Ijaas:
add_action("pre_get_posts", "custom_front_page");
function custom_front_page($wp_query) {
// Compare queried page ID to front page ID.
if(!is_admin() && $wp_query->get("page_id") == get_option("page_on_front")) {
// Set custom parameters (values based on Isaacs question).
$wp_query->set("post_type", "album");
$wp_query->set("posts_per_page", -1);
// WP_Query shouldn't actually fetch the page in our case.
$wp_query->set("page_id", "");
}
}
You might have to alter a few conditional tags to make sure all plugins still work, depending on how heavily the query gets altered.
Hope this helps someone.
Update: as noted below, add !is_admin() to the if-statement to make sure the function only runs on the frontend. If you only want this action to run for the initial query, you could also add the main query check $wp_query->is_main_query().
In response to Robberts solution:
answered May 6 '13 at 12:04
adding && !isAdmin() to the if function other wise it replaces the post type query for all admin pages as well.
Just in case anyone has issues with this.
edit:
also adding && $wp_query->is_main_query() to the if statement stops it affecting widgets and the menu
so total code I have
if($wp_query->get("page_id") == get_option("page_on_front") && !isAdmin() && $wp_query->is_main_query()) {}
In order to get that query to work, you're going to have to add that code to a page template, create a page, set your template as the template for the page you just created, and then set that page as the home page in Settings => Reading in the admin area.
By the way, the is_front_page() function only returns true if you're on a page that's been set as the home page from the admin menu.
The other option would be to modify index.php, but if you did that, is_front_page() would always return false. In that case, you'd want to use is_home() instead.
I hope that helps.
Isaac, you are correct, I didn't thoroughly read your question and I made the assumption that you were looking to do this the "easy" way.
Anyway, I put your code on my test site and, indeed, it didn't work. I looked at my SQL log and it turns out that your code produces this in the query wp_posts.post_status = 'private'.
So, I tried adding the line $query->set('post_status', 'public'); to your function, and it worked just fine.
In summary, try this:
add_filter('pre_get_posts', 'my_get_posts');
function my_get_posts($query){
global $wp_the_query;
if(is_front_page()&&$wp_the_query===$query){
$query->set('post_type','album');
$query->set('posts_per_page',-1);
$query->set('post_status', 'public');
}
return $query;
}
Ok, here's the deal: I am constructing a Drupal website that has several different sections. Each section is a view that displays a content type. (Each section has it's own content type) For example, I have a view that points to ?q=blog which displays content type blog.
All the sections look a little different than each other. Not like 'website-within-a-website' different but different enough that they can't all use the same template file and each be modified with CSS. Each section needs it's own page.tpl.php.
Unfortunately, AFAIK Drupal theme's .info files can only either assign one page.tpl.php for the entire theme or assign a page-node-####.tpl.php for each node. There is going to be lots of content on this website so setting Drupal to make a new identical page-node-####.tpl.php for every created node would get unmanagable very fast.
To solve this problem, I am going to use pathauto to create an alias for each content type. For example, all nodes of content type blog are given an alias ?q=blog/[post title]. Modify template.php to use page-blog.tpl.php for any page who's alias starts with the word 'blog'.
Other people have tried doing this sort of thing and have created functions such as the one described. Unfortunately, all the ones I have seen are for Drupal 6 or below. I have tried modifying existing ones with no success. So far, though, I think this is on the right track:
function basic_preprocess_page(&$vars, $hook) {
...
if( module_exists('path') ) {
$alias = drupal_get_path_alias( $_GET['q'] );
$site_section = "blog";
if( strpos( $alias, $site_section ) === 0 ) {
$VARIABLE_THAT_TELLS_THE_PAGE_WHAT_TEMPLATE_TO_USE = "/path/to/page-blog.php";
}
}
}
I cannot find $VARIABLE_THAT_TELLS_THE_PAGE_WHAT_TEMPLATE_TO_USE does anyone know what it is?
Maybe my site is structured badly. If anyone knows how to restructure my site so I can more easily make a theme with seperate sections please share how!
Thanks a million! (c:
EDIT: Perhaps I need to use template suggestions instead. Does anyone know the function or variable to use to set this?
They changed the name of this array key in D7 and I haven't seen it documented anywhere. I finally figured this out after a good bit of debugging. You can override the theme template in template.php with a hook_preprocess_page() like so:
function myTheme_preprocess_page(&$vars) {
global $node;
if ($node->type == 'blog') {
$vars['theme_hook_suggestions'] = array('my__blog_template'); // use my--blog-template.tpl.php, note '-' = '_'
}
elseif ($node->type == 'articles') {
$vars['theme_hook_suggestions'] = array('article__node_template'); // use article--node-template.tpl.php
}
}
Oh and don't forget to flush the Drupal caches after making changes to your template.php.
Ok, I found it:
http://drupal.org/node/223440#comment-991840
$alias = drupal_get_path_alias($_GET['q']);
if ($alias != $_GET['q']) {
$template_filename = 'page';
foreach (explode('/', $alias) as $path_part) {
$template_filename = $template_filename . '-' . $path_part;
$variables['template_files'][] = $template_filename;
}
}
Credit to this function goes to user mfb.
I had a lot of trouble with this so I will explain it here in case anyone finds it useful.
This function goes in your template.php. It needs to be part of the <theme name>_preprocess_page function. What it does is it takes the alias and then explodes it into a bunch of different components. For example if you are on a page with the alias ?q=blog/blog-post-title it would be exploded into blog and blog-post-title. It then turns each component into a name for a template suggestion. It puts each template suggestion into the template_files[] array (inside the $variables[] array) so that the page now has two new template suggestions:
page-blog, and page-blog-blog-post-title
Template suggestions are alternate template files. In this case they are for pages, but they don't necessarily have to be. You can have template suggestions for anything you can think of including blocks, nodes and the like. Don't let the name 'template suggestion' fool you. Template suggestions will be used over default templates as long as they exist. I don't know why it was named like that. I think it should be renamed.
What you do, then, now that you've set up Drupal to look for a template suggestion that points to your alias, is create a new template file where all the rest are in your theme. In this case, let's say I want to theme my entire blog section. In the templates folder I should create a file named page--blog.tpl.php (note the --double hyphens--) with the layout I want.
Drupal will use the most specific template suggestion it can find so if you wanted you could make one blog post to look completely different than the rest of the site long as you make a template for it named page--blog--blog-post-title and put it in your theme's templates directory. (again, note the double hyphens.)
I have an idea for running multiple wordpress themes at ounce. This might be a good thing to build into a wordpress plugin, if possible. And yes, I might undertake such a task if it isn't ridiculously hard.
(Also, if you are interested in teaming up with me, let me know (leave a comment), I am decent at javascript and php, but not to great, and would love some help!)
This is how I see it working:
Current "set" theme is accessible here: "www.foo.com/"
Second theme accessible here: "www.foo.com/index.php?set_theme=theme2&"
Third theme accessible here: "www.foo.com/index.php?set_theme=THEME_NAME_HERE&"
etc...
This could be used for javascript fall backs. For example, if you go to www.foo.com/?page_id=9 and have javascript turned on, you will hit a javascript redirect to "www.foo.com/index.php?set_theme=THEM_WITH_JAVASCRIPT&page_id=9".
This is how I imagine the plugin code looking/working:
if(isset($_GET['set_theme'])){
$loadme = cleaned($_GET['set_theme']);
if($loadme exists){
loadtheme($loadme);
} else {
//go on as usual, as if this plugin doesnt exist
}
} else {
//go on as usual, as if this plugin doesnt exist
}
And of course, all the links would have to ad ?set_theme=FOOBAR&
So, my main questions are:
How and where does Wordpress select the current theme?
How/where would you ad this to modify internal links-
if(isset($_GET['set_theme'])){
echo "?set_theme=" . $_GET['set_theme'];
}
Do you know of any good websites to point me in the right direction as to how to make WP plugins?
You might like to look at the Theme Switcher plugin to see how that accomplishes this task - should give you some ideas.
Don't really need a plugin, just add this to functions.php:
function theme_switcher() {
if(isset($_GET['theme']) $theme = $_GET['theme'];
global $wpdb;
if (isset($theme)) {
$wpdb->prefix
$queries = “UPDATE “.$wpdb->prefix.”options SET option_value = ‘”.$theme.”‘ WHERE option_name = ‘template’ OR option_name = ‘stylesheet’ OR option_name = ‘current_theme’;”;
$wpdb->query($query);
}
}
add_action('wp_head','switchTheme')
then use mywebsite.com/?theme=myNewTheme to switch them
Disclaimer: untested!!
Found a plugin that was 98% of the way there. Wordpress Theme Switcher Reloaded.
Just changed the ts_get_theme() function as follows:
function ts_get_theme() {
if (!empty($_GET["wptheme"])) {
return $_GET["wptheme"];
} else {
return '';
}
}