EzDevInfo.com

wordpress-theming interview questions

Top wordpress-theming frequently asked interview questions

How do I generate a custom menu/sub-menu system using wp_get_nav_menu_items in wordpress?

I have an html structure that requires customization of the wp_nav_menu code.

This is the html I need to generate:

<ul class="main-nav">
    <li class="item">
        <a rel='nofollow' href="http://example.com/?p=123" class="title">Title</a>
        <a rel='nofollow' href="http://example.com/?p=123" class="desc">Description</a>
        <ul class="sub-menu">
            <li class="item">
                <a rel='nofollow' href="http://example.com/?p=123" class="title">Title</a>
                <a rel='nofollow' href="http://example.com/?p=123" class="desc">Description</a>
            </li>
        </ul>
    </li>
     <li class="item">
        <a rel='nofollow' href="http://example.com/?p=123" class="title">Title</a>
        <a rel='nofollow' href="http://example.com/?p=123" class="desc">Description</a>
    </li>
</ul>

I am currently using wp_get_nav_menu_items to get all the items from my menu as an array.

Right now I am able to generate the above html without the sub-menus using the following code:

<?php

$menu_name = 'main-nav';
$locations = get_nav_menu_locations()
$menu = wp_get_nav_menu_object( $locations[ $menu_name ] );
$menuitems = wp_get_nav_menu_items( $menu->term_id, array( 'order' => 'DESC' ) );

foreach ( $menuitems as $item ):

    $id = get_post_meta( $item->ID, '_menu_item_object_id', true );
    $page = get_page( $id );
    $link = get_page_link( $id ); ?>

    <li class="item">
        <a rel='nofollow' href="<?php echo $link; ?>" class="title">
            <?php echo $page->post_title; ?>
        </a>
        <a rel='nofollow' href="<?php echo $link; ?>" class="desc">
            <?php echo $page->post_excerpt; ?>
        </a>
    </li>

<?php endforeach; ?>

I would have generated the menu using the wp_nav_menu function but I still need the description shown using $page->post_excerpt.

I've found that there is a property for each item called $item->menu_item_parent which gives the ID of the parent menu item.

How would I generate the sub-menu in my foreach loop? Or is there a really simple way using wp_nav_menu which Google forgot to mention?


Source: (StackOverflow)

Path to WordPress Template Directory inside jQuery?

My header is calling a javascript file which sends out an email:

<script type="text/javascript" src="<?php bloginfo('template_directory') ?>/css/effects.js"></script>

But inside this file, I have a jQuery code that calls a .php file that does the actual sending of the email:

$.ajax({
  type: "POST",
  url: "css/sendmail.php",
  data: dataString`

But the script doesn't work, unless the url is:

<?php bloginfo('template_directory') ?>/css/sendmail.php

and not just:

css/sendmail.php

Is there any way to include a path to the wordpress template directory inside js?


Source: (StackOverflow)

Advertisements

Get Wordpress Category from Single Post

I'm finishing up a WP theme, and I'm on the single.php template. I'm having some issues because I need to access the parent category that a post is in in order to display certain images and XML content.

Here is an example of what I'm talking about. The following is the end url of a single post:

/andrew/leaf-art-2/

/andrew/ is the category, and leaf-art-2 is the single post. When I am on the single post, I am having trouble getting single_cat_title(); to return the category that the current post is in. I am using single_cat_title(); instead of the_category(); because it displays the string value of the category which I then use to place a picture of the artist (whose category this is) on their posts. I don't have any use for the url, I just need the string with the category name.

Any good ways of doing this? I have been searching the Wordpress Codex and lots of forums, and haven't found any answers yet.


The following was my original post.

I have set up a category called "artists" which when I run single_cat_title("", false); I can get the string value of the category and then use it to search for the appropriate artist image using XML.

This works fine on the category.php template page.

The problem is that when I'm actually inside of a single post that has the "artists" category, single_cat_title(); doesn't output any information to the page, thereby keeping me from accessing the XML data.

I need to, while in the "artists" > "sample" post, be able to get from WP the category.

P.S. the above category is one of many that is using this setup, which is why I can't hardcode it.


Source: (StackOverflow)

WooCommerce - where can I edit HTML generated by hooks?

I'm new to WooCommerce. Anyhow, I want to create my own theme, so I followed the guidelines and copied accross the core template files to /mywordpresstheme/woocommerce/.

That all works great and I'm editing the templates just fine.

However, the way hooks and actions work in WooCommerce is baffling me and I can't work out where certain parts of generated HTML are coming from.

For example, in content-product.php, there is a hook that gets the image:

<?php
/*
* woocommerce_before_shop_loop_item_title hook
*
* @hooked woocommerce_show_product_loop_sale_flash - 10
* @hooked woocommerce_template_loop_product_thumbnail - 10
*/
do_action( 'woocommerce_before_shop_loop_item_title' );
?>

But what is this? Where does it come from?? Is there any clue in the action name as to where I could locate the HTML being generated for the purpose of editing it?

I've read the article on 'hooks and filters' on WooCommerce, but it explains nothing regarding where or how to change these on a case for case basis.

Any help would be greatly appreciated.

I'm new to this system and I'm sure I'm simply over-looking something very obvious.

Thanks, Mikey.


Source: (StackOverflow)

Using Sass compressed output while leaving theme comment header for Wordpress

How do other Wordpress theme developers incorporate Sass into their theme development while taking advantage of its compressed output style? Sass compressed removes ALL comments, so I currently have an empty style.css with my theme declaration and an @import calling the minified css from compass, but this hardly seems like the best solution.

Has anybody found a way around this? What would be the best solution if not?

http://codex.wordpress.org/Theme_Development#Theme_Stylesheet

http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#id40


Source: (StackOverflow)

how to render a single page wordpress template with twig

I've been trying to render a single page wordpress template with Twig, but so far everything has failed.

{% extends 'layouts/base.twig' %}

{% block content %} 
    {% for page in pages() %}{{ set_up_page(page) }}                                
        {% include 'content/content-' ~ page.post_name ~ '.twig' %}
    {% endfor %}
{% endblock %}

What one of the templates looks like :

<section id="about" {{ wp.post_class }}>
    <div class="container">
        <div class="row">
            <div class="col-lg-12 text-center">
                <h2 class="section-heading">{{ wp.the_title }}</h2>
                <h3 class="section-subheading text-muted">{{ wp.get_post_meta(wp.get_the_ID() , 'st_page_subtitle', true)  }}</h3> <!-- To be Changed to subtext for title  -->
            </div>
        </div>
        <div class="row">
            <div class="col-lg-12">
             {{ wp.the_content }}
            </div>
        </div>
    </div>

The corresponding functions :

        $wpgetpages = new Twig_SimpleFunction("pages", function() { 

                $currentID = get_the_ID();

                $menu_order = wp_get_nav_menu_items('header');

                $menu_items = array();

                foreach($menu_order as $item) {

                    $menu_items[] = $item->ID;
                }

                $args = array('post_type' => 'page',
                              'status' => 'publish',                                  
                              'exclude'=> $currentID,
                              'orderby' => 'menu_order',                                  
                              'order' => 'ASC'
                           );

                $pages = get_posts($args);

                return $pages;

        });     

        $wpsetpages = new Twig_SimpleFunction("set_up_page", function($arg) {   

                setup_postdata($arg);                       

        });

        self::$twig_environment->addFunction($wpposts);
        self::$twig_environment->addFunction($get_theme_options);
        self::$twig_environment->addFunction($wppostdata);          
        self::$twig_environment->addFunction($wpgetpages);
        self::$twig_environment->addFunction($wpsetpages);  

This brings out the templates but it sets the page title from the template as the title of the home pageenter image description here

Would really appreciate any help on fixing this.


Source: (StackOverflow)

Can jQuery .load append instead of replace?

I have a WordPress install and I'm trying to use jQuery to create a Load More effect. I'm having some trouble using the basic .load feature for page fragments. I don't mind using .get as I saw some threads here regarding that as a better solution.

Here's my page URL structure and the contents:

First Page: http://example.com/page/1/

The HTML:

<div id="articles">
  <div class="story">blah blah blah</div>
  <div class="story">blah blah blah</div>
  <div class="story">blah blah blah</div>
  <div class="story">blah blah blah</div>
</div>

Second Page: http://example.com/page/2/

The HTML:

<div id="articles">
  <div class="story">blah blah blah</div>
  <div class="story">blah blah blah</div>
  <div class="story">blah blah blah</div>
  <div class="story">blah blah blah</div>
</div>

I have a link at the bottom of the page and I've tried doing the following:

jQuery(#articles).load('http://example.com/page/2/ #articles');

Sadly, there are 2 issues. First the .load function grabs the #articles div and its contents from the second page and places it into the existing #articles div. That means, even if this were to work, there would be recursive divs within divs resulting from each click. It's just messy.

Could someone help me with the command to simply append the .story classes from the second page into the #articles div on the first page? I can figure out the logistics of automating it with variables, loops, and PHP for WordPress after. Just need some assitance with the proper jQuery script.

P.S. Bonus Question: If anyone knows whether jQuery .load/.get will harm pageviews, which is important for those with advertising-based revenue, please let me know! If each .load/.get counts as another hit for Google Analytics, we're good!

Thanks!


Source: (StackOverflow)

Masonry.js failing on load. Cannot call 'create' of undefined (Outerlayer) in Wordpress

So I've got a strange problem that I can't seem to find anywhere else, regarding masonry.js.

I've got the latest (3.10) version and I'm including it in my wordpress theme's functions.php file as so:

function enqueue ()
{
    wp_register_script( 'masonry', get_stylesheet_directory_uri() . '/js/masonry.js', array( 'jquery' ) );
    wp_enqueue_script( 'masonry' );
}

add_action( 'wp_enqueue_scripts', 'enqueue');

Which is loading the script fine. As it is now, I'm not doing anything else with it, but the script is failing:

Uncaught TypeError: Cannot call method 'create' of undefined masonry.js?ver=3.5.2:37

Seems like it cannot call create on the window.Outerlayer as it doesnt exist.

Here's the code in question, starting at line 34 from the masonry.js:

// used for AMD definition and requires
function masonryDefinition( Outlayer, getSize ) {
  // create an Outlayer layout class
  var Masonry = Outlayer.create('masonry');

  Masonry.prototype._resetLayout = function() {
    this.getSize();
    this._getMeasurement( 'columnWidth', 'outerWidth' );
    this._getMeasurement( 'gutter', 'outerWidth' );
    this.measureColumns();

    // reset column Y
    var i = this.cols;
    this.colYs = [];
    while (i--) {
      this.colYs.push( 0 );
    }

    this.maxY = 0;
  };

I've tried enqueueing the script in different ways, as well as pulling it in only when $(document).ready() (which I believe wordpress' enqueue_script does anyway?).

So, does anyone have any ideas what the problem or conflict could be here? Or has anyone experienced anything similar?

(I'm using jQuery 1.83, though masonry shouldn't require jquery according to the site.)


Source: (StackOverflow)

Wordpress fake post with fake postmeta.

Several days ago I have made a post "How to make a fake WordPress post for each user separately"

I managed to make a Fake post by using this resource. Everything was good unless I tried to do the same with custom field option. The theme I'm using has a separate custom field in wp_postmeta which includes the embedded video in separate <div>.
Here is the code I tried to use for setting the custom field option.

function kpg_f_content() {
    global $wp_query;

    $post = new stdClass();
    $post -> ID = 1;
    $post -> post_category = array('uncategorized');
    //Add some categories. an array()???
    $post -> post_content = 'hey here we are a real post';
    //The full text of the post.
    $post -> post_excerpt = 'hey here we are a real post';
    //For all your post excerpt needs.
    $post -> post_status = 'publish';
    //Set the status of the new post.
    $post -> post_title = 'Fake Title 1';
    //The title of your post.
    $post -> post_type = 'post';
    //Sometimes you might want to post a page.
    $post -> post_date = '[ 2013-12-19 5:34:3 ]';
    //The time post was made.
    $post -> post_date_gmt = '[ 2013-12-19 5:34:3 ]';
    //The time post was made, in GMT.

    $vid = new stdClass();
    $vid -> meta_key = 'video_url';
    $vid -> meta_value = 'http://www.youtube.com/watch?v=ucivXRBrP_0';

    $vid1 = new stdClass();
    $vid1 -> meta_key = '_oembed_576540b29025537e24e5bcdcae946a46';
    $vid1 -> meta_value = '<iframe width="500" height="281" src="http://www.youtube.com/embed/ucivXRBrP_0?feature=oembed" frameborder="0" allowfullscreen></iframe>';

    $wp_query -> queried_object = $post;
    $wp_query -> post = $post;
    $wp_query -> found_posts = 2;
    $wp_query -> post_count = 2;
    $wp_query -> max_num_pages = 2;
    $wp_query -> is_single = 1;
    $wp_query -> is_404 = false;
    $wp_query -> is_posts_page = 0;
    $wp_query -> posts = $post;
    $wp_query -> page = false;
    $wp_query -> is_post = true;
    $wp_query -> page = false;
    $wp_query -> meta_query = array($vid, $vid1);

}

add_action('wp', 'kpg_f_content'); 

The part I improvised is $wp_query->meta_query=array($vid,$vid1);, but it doesn't help as it expected to be as if even it would set these 2 options it would not set the post_id and the theme could not find for which post was the option made. Guys any ideas how can I perform this?


Source: (StackOverflow)

How to add custom post type archive to menu

I have been searching for weeks and I still haven't found a proper solution to this problem.

I am writing a Wordpress Theme. I have a custom post type called Works. I would like to add my Works archive to my menu and have it as well as it's posts highlighted when I access them.

I can access my archive and posts on the following links

Works archive: /works/

Works single post: /works/postname/

My solution so fare have been to name my archive-works.php template file with a template name (Work archive). Then create an empty page using that template and adding the page to the menu. This highlights the archive in the menu but not the single posts.

I can easily solve this with a custom link and some javascript but there must be a better and cleaner way.


Source: (StackOverflow)

Adding a jQuery script to wordpress Admin

I cannot for some reason get the wordpress /wp-admin pages to execute a simple query file. It only works if i deregister jquery in my functions.php within my theme folder, but then i must re-register all the jquery.ui files separately which is tedious. Im using wordpress 3.0 multisite installation. I'm trying not to touch the core wp files.

It will show in the source and links to the file ok but won't execute the script. heres what i have in my functions.php:

function my_script() {
if (!is_admin()) {
    wp_deregister_script('jquery');
    wp_register_script('jquery', 'https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js', false, '1.4.4');
    wp_enqueue_script('jquery');
    wp_enqueue_script('custom_script', get_bloginfo('template_url').'/js/myScript.js', array('jquery'));
}
if(is_admin()){
    wp_enqueue_script('custom_admin_script',  get_bloginfo('template_url').'/js/admin_script.js', array('jquery'));
}   }

add_action('init', 'my_script');

Here's My jquery file (admin_script.js):

$(document).ready(function(){
alert("Hello"); });

any help would be great.


Source: (StackOverflow)

In Wordpress, how do I set the default admin sort order for a custom post type to a custom column?

I've set up a custom post type called clientarea, and set up several custom columns for it in the admin area - the custom columns are all custom meta fields, as you can see from my code. I'd like to sort by 'Appointment Date' descending by default.

All of the columns work fine, and can be sorted manually as expected, but I can't get the default sort order to work.

If I change the default sort field to a standard field (e.g. 'title') it works as expected; it only seems not to work when I'm trying to set a custom column as the default sort order. The order works (i.e. I can change between asc and desc by default even with a custom column), but it's not picking up the orderby so is reverting back to sorting by the date the custom post was published.

What am I missing?

My code is as follows:

add_action( 'manage_posts_custom_column' , 'custom_columns', 10, 2 );

function custom_columns( $column, $post_id ) {
    global $wpdb;
    switch ( $column ) {
        case 'extranet_case_office':
            $get_office_ID = get_post_meta( $post_id, 'extranet_case_office', true );
            $get_office_name = $wpdb->get_results('SELECT post_title FROM `cn_bf_posts` WHERE `ID` = '.$get_office_ID);
            echo $get_office_name[0]->post_title;
            break;
        case 'extranet_appointment_date':
            echo date('d/m/Y',strtotime(get_post_meta( $post_id, 'extranet_appointment_date', true ))); 
            break;
        case 'extranet_appointment_type':
            echo get_post_meta( $post_id, 'extranet_appointment_type', true ); 
            break;
        case 'extranet_insolvency_practioner':
            $get_person_ID = get_post_meta( $post_id, 'extranet_insolvency_practioner', true );
            $get_person_name = $wpdb->get_results('SELECT post_title FROM `cn_bf_posts` WHERE `ID` = '.$get_person_ID);
            echo $get_person_name[0]->post_title;
            break;
        default:
            break;
    }
}

add_filter( 'manage_edit-clientarea_sortable_columns', 'my_sortable_clientarea_columns' );

function my_sortable_clientarea_columns( $columns ) {
    $columns['extranet_case_office'] = 'extranet_sort_office';
    $columns['extranet_appointment_date'] = 'extranet_sort_date';
    $columns['extranet_appointment_type'] = 'extranet_sort_type';
    $columns['extranet_insolvency_practioner'] = 'extranet_sort_IP';
    return $columns;
}

add_action( 'pre_get_posts', 'extranet_orderby' );

function extranet_orderby( $query ) {
    if( ! is_admin() )
        return;

    $orderby = $query->get( 'orderby');

    switch ( $orderby ) {
        case 'extranet_sort_office':
            $query->set('meta_key','extranet_case_office');
            $query->set('orderby','meta_value_num');
            break;
        case 'extranet_sort_date':
            $query->set('meta_key','extranet_appointment_date');
            $query->set('orderby','meta_value');
            break;
        case 'extranet_sort_type':
            $query->set('meta_key','extranet_appointment_type');
            $query->set('orderby','meta_value');
            break;
        case 'extranet_sort_IP':
            $query->set('meta_key','extranet_insolvency_practioner');
            $query->set('orderby','meta_value_num');
            break;
        default:
            break;
    }
}

add_action('pre_get_posts','clientarea_default_order');
function clientarea_default_order( $query ){
    if( $query->get('post_type')=='clientarea' ){
        if( $query->get('orderby') == '' )
            $query->set('orderby','extranet_sort_date');

        if( $query->get('order') == '' )
            $query->set('order','desc');
    }
}

Source: (StackOverflow)

How do I add custom fields to my custom post type in Wordpress 3?

I created a custom post type with the register_post_type function, and now I want to add custom fields to it. These must be as user friendly and integraded in the GUI as possible.

I tried the custom field template but I dont really like it for end users. I prefer to add the new field and a new meta box with code.


Source: (StackOverflow)

remove li class & id for menu items and pages list

Example of WordPress default CSS class output:

<li id="menu-item-55" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-55">

<li class="page_item page-item-37">

The menu and pages list item come with various own li class and id.

How to remove them in functions.php file for the menu and for the pages list?


Source: (StackOverflow)

Template Overriding using a customization section

I am trying to override my default templates from customization section, I am using code to do that, but if I am using it I am unable to assign a template to the edit-page page, Can anyone give an idea how both the customization section and edit-page assign template work. I want to set the template when I am creating a page and after assigning it I want to override. Consider I have a blog page, I want to assign it archive.php template and ten want to override It from customization section. There is the particular condition where I want it to work.

 <?php
    /**
     * Adds the Customize page to Select template For Pages
     */

    add_action( 'wp_footer', 'cur_page_template' );
function cur_page_template(){
    var_dump( get_option('current_page_template') );
    var_dump( get_page_template() );
    exit;
}
 function widgetsite_template_override($wp_customize){
    $wp_customize->add_panel( 'template_options', array(
        'title' => __( 'Template Options', 'widgetsite' ),
        'description' => $description, // Include html tags such as <p>.
        'priority' => 160, // Mixed with top-level-section hierarchy.
    ) );

    $wp_customize->add_section('theme_template_override', array(
        'title'    => __('Override  Templates', 'widgetsite'),
        'panel' => 'template_options',
        'description' => '',
        'priority' => 120,
    ));


    $templates = get_page_templates();

    $cats = array();
    $i = 0;
    foreach($templates as $template_name => $template_file){
        //$cats[$template_name] = $template_name;   
        if (strpos($template_file,'layouts') !== false) {
            $cats[$template_file] = $template_name;
        }
    }


    $wp_customize->add_setting('widgetsite_archive_template');
    $wp_customize->add_setting('widgetsite_page_template');
    $wp_customize->add_setting('widgetsite_index_template');
    $wp_customize->add_setting('widgetsite_post_template');
    $wp_customize->add_setting('widgetsite_search_template');

    $wp_customize->add_control( 'widgetsite_archive_template', array(
        'settings' => 'widgetsite_archive_template',
        'label'   => 'Override Archive Template:',
        'section'  => 'theme_template_override',
        'type'    => 'select',
        'choices' => array_merge(array( "archive.php"=>get_option('current_page_template')), $cats)
    ));
    $wp_customize->add_control( 'widgetsite_page_template', array(
        'settings' => 'widgetsite_page_template',
        'label'   => 'Override Page Template:',
        'section'  => 'theme_template_override',
        'type'    => 'select',
        'choices' => array_merge( array( "page.php" =>get_option('current_page_template')), $cats)
    ));
    $wp_customize->add_control( 'widgetsite_index_template', array(
        'settings' => 'widgetsite_index_template',
        'label'   => 'Override Index Template:',
        'section'  => 'theme_template_override',
        'type'    => 'select',
        'choices' => array_merge(array( "index.php"=>get_option('current_page_template')), $cats)
    ));
    $wp_customize->add_control( 'widgetsite_post_template', array(
        'settings' => 'widgetsite_post_template',
        'label'   => 'Override Post Template:',
        'section'  => 'theme_template_override',
        'type'    => 'select',
        'choices' => array_merge(array( "post.php"=>get_option('current_page_template')), $cats)
    ));
    $wp_customize->add_control( 'widgetsite_search_template', array(
        'settings' => 'widgetsite_search_template',
        'label'   => 'Override Search Template:',
        'section'  => 'theme_template_override',
        'type'    => 'select',
        'choices' => array_merge(array( "search.php"=>get_option('current_page_template')), $cats)
    ));

}
add_action('customize_register', 'widgetsite_template_override');

$theme_mode_templates['archive.php'] = get_theme_mod("widgetsite_archive_template");
$theme_mode_templates['page.php'] = get_theme_mod("widgetsite_page_template");
$theme_mode_templates['index.php'] = get_theme_mod("widgetsite_index_template");
$theme_mode_templates['post.php'] = get_theme_mod("widgetsite_post_template");
$theme_mode_templates['search.php'] = get_theme_mod("widgetsite_search_template");


function widgetsite_template_redirect($template){

    global $wp_query;
    global $post;
    $cur= basename($template);
    if(  $cur === 'page.php' && get_theme_mod("widgetsite_page_template")){  //note $cur will never be empty!
        $template=  get_template_directory() . '/' . get_theme_mod("widgetsite_page_template");// assuming this will return correct template...
        //if issues try hardcoding a path to test...
    }
    if(  $cur === 'archive.php' && get_theme_mod("widgetsite_archive_template")){  //note $cur will never be empty!
        $template=  get_template_directory() . '/' . get_theme_mod("widgetsite_archive_template");// assuming this will return correct template...
        //if issues try hardcoding a path to test...
    }
    if(  $cur === 'index.php' && get_theme_mod("widgetsite_index_template")){  //note $cur will never be empty!
        $template=  get_template_directory() . '/' . get_theme_mod("widgetsite_index_template");// assuming this will return correct template...
        //if issues try hardcoding a path to test...
    }
    if(  $cur === 'post.php' && get_theme_mod("widgetsite_post_template")){  //note $cur will never be empty!
        $template=  get_template_directory() . '/' . get_theme_mod("widgetsite_post_template");// assuming this will return correct template...
        //if issues try hardcoding a path to test...
    }
    if(  $cur === 'search.php' && get_theme_mod("widgetsite_search_template")){  //note $cur will never be empty!
        $template=  get_template_directory() . '/' . get_theme_mod("widgetsite_search_template");// assuming this will return correct template...
        //if issues try hardcoding a path to test...
    }
    return $template;


}
add_filter( 'template_include', 'widgetsite_template_redirect', 99 ); 

Source: (StackOverflow)