Skip to content

Instantly share code, notes, and snippets.

@kuzminT
Last active December 21, 2019 07:11
Show Gist options
  • Save kuzminT/6d629b78aa77267d5a77c0838cdc9b0a to your computer and use it in GitHub Desktop.
Save kuzminT/6d629b78aa77267d5a77c0838cdc9b0a to your computer and use it in GitHub Desktop.
Wordpress tips for custom theme creating
<?php
/**
* Class autoloader
* @param string $class fully qualified class name
* @return void
*/
function plugins_autoloader($class)
{
$prefix = 'Foo\\Bar\\';
$base_dir = __DIR__ . '/plugins/';
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
return;
}
// get the relative class name
$relative_class = strtolower( substr($class, $len) );
// First, separate the components of the incoming file.
$file = explode( '\\', $relative_class );
$last_part_post = count($file) - 1;
// add class prefix to the file name by wp standart
$file[ $last_part_post ] = 'class-' . $file[ $last_part_post ];
$file = implode(DIRECTORY_SEPARATOR, $file);
$file = str_replace('_', '-', $file);
$file = $base_dir . $file . '.php';
if (file_exists($file)) {
require_once $file;
} else {
print $file;
}
return;
}
try {
spl_autoload_register('\\plugins_autoloader');
} catch (\Exception $e) {
print 'Something Wrong!';
}

Custom login and register

Example custom login page

	<?php
	/**
	 * Template Name: Sign In
	 */
	get_header();


	if($_POST)
	{

	    global $wpdb;

	//We shall SQL escape all inputs
	    $username = $wpdb->escape($_REQUEST['username']);
	    $password = $wpdb->escape($_REQUEST['password']);
	    $remember = $wpdb->escape($_REQUEST['rememberme']);

	    if($remember) $remember = "true";
	    else $remember = "false";

	    $login_data = array();
	    $login_data['user_login'] = $username;
	    $login_data['user_password'] = $password;
	    $login_data['remember'] = $remember;

	    $user_verify = wp_signon( $login_data, false );

	    if ( is_wp_error($user_verify) )
	    {
		echo '<span class="mine">Invlaid Login Details</span>';
	    } else
	    {
		echo "<script type='text/javascript'>window.location.href='". home_url() ."'</script>";
		exit();
	    }

	}
	else {
	    ?>

	    <form id="wp_login_form" action="" method="post">
		<label for="tab-1" class="tab">Sign In</label><br>

		<label class="my-username">Username</label><br>
		<input type="text" name="username" class="text" value=""><br>
		<label class="my-password">Password</label><br>

		<input type="password" name="password" class="text" value=""> <br>
		<label>
		    <input class="myremember" name="rememberme" type="checkbox" value="forever"><span
			class="hey">Remember me</span></label>
		<br><br>
		<input type="submit" id="submitbtn" name="submit" value="Login">
	    </form>
	    <?php
	}
	get_sidebar();
	get_footer();
	 ?>

Custom rewrite rules

function custom_rewrite_rule() {
    add_rewrite_rule('^profile/([0-9]+)/?$', 'index.php?page_id=9&user_id=$matches[1]', 'top');
}
add_action('init', 'custom_rewrite_rule', 10, 0);

function custom_rewrite_tag() {
    add_rewrite_tag('%user_id%', '([^&]+)');
}
add_action('init', 'custom_rewrite_tag', 10, 0);

PHP OOP with Wordpress

Static front page

  • Designing a Custom Home Page for Your WordPress Website - about Customizer and Kirki toolkit for customization wordpress theme.

  • Creating a Static Front Page - официальное руководство.

      # Custom loop on static front page
      $paged = (get_query_var('page')) ? get_query_var('page') : 1;
      $args=array('category_name'=>'portfolio','posts_per_page'=>4,'paged'=>$paged);
      query_posts($args);
      if (have_posts()) : while (have_posts()) : the_post();
      /...
      endwhile;
      posts_nav_link();
      wp_reset_query();
      endif;
    

Example custom wp_query with pagination and offset

$per_page     = 1;
$offset_start = 1;
$offset       = ( $current_page - 1 ) * $per_page + $offset_start;
$current_page = max( get_query_var( 'page' ), 1 ); // page or paged in other case
$args = array(
	'posts_per_page' => 1,
	'paged'          => $current_page,
	'post__not_in'   => get_option( 'sticky_posts' ), // exclude "sticky posts"
	'orderby'        => 'post_date',
	'order'          => 'DESC',
	'offset'         => $offset
);
$main_articles = new WP_Query( $args );

// Manually count the number of pages, because we used a custom OFFSET (i.e.
// other than 0), so we can't simply use $post_list->max_num_pages or even
// $post_list->found_posts without extra work/calculation.
$total_rows    = max( 0, $main_articles->found_posts - $offset_start );
$total_pages   = ceil( $total_rows / $per_page );

if ( $main_articles->have_posts() ):
	/* Start the Loop */
	while ( $main_articles->have_posts() ) :
		$main_articles->the_post();
		// output articles
	endwhile; 
	// output pagination
	echo paginate_links( array(
			'total'     => $total_pages,
			'current'   => $current_page,
			'type'      => 'plain',
			'end_size'  => 10,
			'mid_size'  => 1,
			'prev_next' => true,
			'prev_text' => "&lt;",
			'next_text' => "&gt;",
		) );
	wp_reset_postdata();
endif;

Example of custom wp_query order by meta value

# Display posts with ‘Product’ type ordered by ‘Price’ custom field:
$args = array(
    'post_type' => 'product',
    'orderby'   => 'meta_value_num',
    'meta_key'  => 'price',
);
$query = new WP_Query( $args );

Admin dashboard customization

Custom Admin footer

function wpexplorer_remove_footer_admin () {
  echo '<span id="footer-thankyou">Built with love by <a href="http://www.wpexplorer.com/" target="_blank">WPExplorer</a></span>';
}
add_filter( 'admin_footer_text', 'wpexplorer_remove_footer_admin' );

Thumbnails

Get alt of the attachment image

$thumbnail_id = get_post_thumbnail_id( $post->ID );
$alt = get_post_meta( $thumbnail_id, '_wp_attachment_image_alt', true );

Plugins

Multilingual WordPress

Cache

Custom Widgets

  • Widgets API

  • How to Create a Custom WordPress Widget

      class My_Widget extends WP_Widget {
      	/**
      	 * Sets up the widgets name etc
      	 */
      	public function __construct() {
      		$widget_ops = array( 
      			'classname' => 'my_widget',
      			'description' => 'My Widget is awesome',
      		);
      		parent::__construct( 'my_widget', 'My Widget', $widget_ops );
      	}
    
      	/**
      	 * Outputs the content of the widget
      	 *
      	 * @param array $args
      	 * @param array $instance
      	 */
      	public function widget( $args, $instance ) {
      		// outputs the content of the widget
      	}
    
      	/**
      	 * Outputs the options form on admin
      	 *
      	 * @param array $instance The widget options
      	 */
      	public function form( $instance ) {
      		// outputs the options form on admin
      	}
    
      	/**
      	 * Processing widget options on save
      	 *
      	 * @param array $new_instance The new options
      	 * @param array $old_instance The previous options
      	 *
      	 * @return array
      	 */
      	public function update( $new_instance, $old_instance ) {
      		// processes widget options to be saved
      	}
      }
    

Search form

Comments form

Example function search by title only

	function __search_by_title_only( $search, \WP_Query $wp_query )
	{
	    global $wpdb;
	    if(empty($search)) {
		return $search; // skip processing - no search term in query
	    }
	    $q = $wp_query->query_vars;
	    $n = !empty($q['exact']) ? '' : '%';
	    $search = '';
	    $searchand = '';
	    foreach ((array)$q['search_terms'] as $term) {
		$term = esc_sql($wpdb->esc_like($term));
		$search .= "{$searchand}($wpdb->posts.post_title LIKE '{$n}{$term}{$n}')";
		$searchand = ' AND ';
	    }
	    if (!empty($search)) {
		$search = " AND ({$search}) ";
		if (!is_user_logged_in())
		    $search .= " AND ($wpdb->posts.post_password = '') ";
	    }
	    return $search;
	}
	add_filter('posts_search', '__search_by_title_only', 500, 2);

Like and dislike buttons

Create tables

Upload images

Add multipart/form-data for user profile to upload images.

add_action('user_edit_form_tag', 'make_form_accept_uploads');
function make_form_accept_uploads() { echo ' enctype="multipart/form-data"'; }

The code to save the attachment

	<?php
	// Check that the nonce is valid, and the user can edit this post.
	if ( 
		isset( $_POST['my_image_upload_nonce'], $_POST['post_id'] ) 
		&& wp_verify_nonce( $_POST['my_image_upload_nonce'], 'my_image_upload' )
		&& current_user_can( 'edit_post', $_POST['post_id'] )
	) {
		// The nonce was valid and the user has the capabilities, it is safe to continue.

		// These files need to be included as dependencies when on the front end.
		require_once( ABSPATH . 'wp-admin/includes/image.php' );
		require_once( ABSPATH . 'wp-admin/includes/file.php' );
		require_once( ABSPATH . 'wp-admin/includes/media.php' );

		// Let WordPress handle the upload.
		// Remember, 'my_image_upload' is the name of our file input in our form above.
		$attachment_id = media_handle_upload( 'my_image_upload', $_POST['post_id'] );

		if ( is_wp_error( $attachment_id ) ) {
			// There was an error uploading the image.
		} else {
			// The image was uploaded successfully!
		}

	} else {

		// The security check failed, maybe show the user an error.
	}

Отправка писем и подтверждение регистрации

Manual user Approve:

  • Eonet Manual User Approve

  • WP Approve User

      add_action( 'user_register', 'so27450945_user_register', 10, 1 );
      function so27450945_user_register( $user_id )
      {
          $user = get_user_by( 'id', $user_id );
    
          $blogname = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES );
    
          $message  = sprintf( __( 'New user registration on your site %s:' ), $blogname ) . "\r\n\r\n";
          $message .= sprintf( __( 'Username: %s'), $user->user_login ) . "\r\n\r\n";
          $message .= sprintf( __( 'E-mail: %s'), $user->user_email ) . "\r\n";
    
          @wp_mail( get_option( 'admin_email' ), sprintf( __( '[%s] New User Registration' ), $blogname ), $message);
      }
    
  • Build a Custom WordPress User Flow — Part 3: Password Reset

retrieve_password() - Handles sending password retrieval email to user.

Custom images types

Add webp type:

//enable upload for webp image files.
function webp_upload_mimes($existing_mimes) {
    $existing_mimes['webp'] = 'image/webp';
    return $existing_mimes;
}
add_filter('mime_types', 'webp_upload_mimes');

//enable preview / thumbnail for webp image files.
function webp_is_displayable($result, $path) {
    if ($result === false) {
	$displayable_image_types = array( IMAGETYPE_WEBP );
	$info = @getimagesize( $path );

	if (empty($info)) {
	    $result = false;
	} elseif (!in_array($info[2], $displayable_image_types)) {
	    $result = false;
	} else {
	    $result = true;
	}
    }

    return $result;
}
add_filter('file_is_displayable_image', 'webp_is_displayable', 10, 2);

Custom tag fields

Hooks: For editing:

  • {$taxonomy}_edit_form
  • {$taxname}_add_form_fields For saving:
  • create_{$taxname}
  • edited_{$taxname}

For tags $taxname == 'post_tag'.

	add_action( "{$taxname}_edit_form_fields", 'tag_edit_form_fields', 10, 1 );
	add_action( "{$taxname}_add_form_fields", 'tag_new_form_fields', 10, 1 );
	add_action( "create_{$taxname}", 'save_custom_taxonomy_meta' );
	add_action( "edited_{$taxname}", 'save_custom_taxonomy_meta' );

Link:

Frameworks with wordpress

Templates

Modify wp queries

Remove useless rewrites from array

  • Add filter rewrite_rules_array

      /**
       * Remove rewrites for attachment pages
       * 
       * */
      function cleanup_default_rewrite_rules( $rules ) {
      	foreach ( $rules as $regex => $query ) {
      		if ( strpos( $regex, 'attachment' ) || strpos( $query, 'attachment' ) ) {
      			unset( $rules[ $regex ] );
      		}
      	}
    
      	return $rules;
      }
    

Localization

Wordpress async tasks

All in one seo

Add custom links to sitemap.

	# @link https://wordpress.org/support/topic/dynamic-sitemap-generation-hook/?replies=7
	add_filter( 'option_aioseop_options', 'itdge_sitemap_addl_pages' );
	function itdge_sitemap_addl_pages( $option ) {
	
	 	$uri = $_SERVER['REQUEST_URI'];
			$uriSegments = explode('/', $uri);
			if ($uriSegments[ count($uriSegments) - 1 ] != 'sitemap.xml') return $option;
		
		if (   !empty( $option )
			&& !empty( $option['modules'] )
			&& !empty( $option['modules']['aiosp_sitemap_options'])
		  ) {
			$my_sitemap_entries = Array(
			'/test1' => Array( 'prio' => '0.1', 'freq' => 'daily', 'mod' => '2014-04-01' ),
			'/test2' => Array( 'prio' => '0.3', 'freq' => 'weekly', 'mod' => '2014-03-02' )
			);
			if ( empty( $option['modules']['aiosp_sitemap_options']['aiosp_sitemap_addl_pages'] ) ) {
				$option['modules']['aiosp_sitemap_options']['aiosp_sitemap_addl_pages'] = Array();
			}
			foreach( $my_sitemap_entries as $k => $v ) {
				$option['modules']['aiosp_sitemap_options']['aiosp_sitemap_addl_pages'][$k] = $v;
			}
		}
		return $option;
	}

Usefool command, tips and links for wp cli

# Add posts with dummy content for development:
wp post generate --count=10
curl http://loripsum.net/api/4 | wp post generate --post_content --count=10

# lists constants and globals as defined in your current wp-config.php file:
wp config get
# simply displays a path to the current wp-config.php file:
wp config path
# list db tables and their sizes:
wp db size --tables
# update wordpress:
wp core update
# plugins
wp plugin deactivate plugin-name-example
wp plugin delete plugin-name-example
wp plugin update --all
# check the status of the plugins currently on your site:
wp plugin status
# Reset user password:
wp user update [email protected] --user_pass=new-password-example
# operations with db:
wp db optimize
wp db repair
wp db query "SELECT * FROM wp_options"
# comments:
wp comment delete $(wp comment list --status=spam --format=ids)
# media:
wp media regenerate
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment