Get term name by post ID

- Name:

                                         <?php $terms = get_the_terms($post->ID, 'projects_category');foreach($terms as $term){echo $term->name;} ?>

- Name with href

<?php   // Get terms for post
$terms = get_the_terms( $post->ID , 'oil' );
// Loop over each item since it's an array
if ( $terms != null ){
foreach( $terms as $term ) {
$term_link = get_term_link( $term, 'oil' );
 // Print the name and URL
echo '<a href="' . $term_link . '">' . $term->name . '</a>';
// Get rid of the other data stored in the object, since it's not needed
unset($term); } } ?>


Đọc thêm..

Hướng dẫn sử dụng nhiều domain cho 1 website WordPress

 

Vấn đề là khách có 1 website với tên miền là your-domain.com. Nhưng do yêu cầu khách hàng cần trỏ nhiều domain khác nhau vào 1 website đó ví dụ như your-domain.com.au, your-domain.com.uk … Vậy chúng ta sẽ làm như nào để có thể trỏ nhiều domain về 1 website chạy WordPress?

Chúng ta cần giải quyết 3 vấn đề:

  1. Parked domain (Aliases) về hosting đang chạy site chính và trỏ đúng về thư mục của site chính luôn (thường là /public_html)
  2. Chuyển WP_SITEURLWP_HOME về domain mà khách hàng truy cập
  3. Cài đặt SEO để tránh google đánh dấu nhiều website trùng nội dung.

Chuyển WP_SITEURLWP_HOME

Ví dụ khi ta thêm parked domain (Aliases) your-domain.com.au vào your-domain.com mặc định khi truy cập vào your-domain.com.au  trình duyệt sẽ tự động redirect về domain chính là your-domain.com vì vậy chúng ta cần thêm đoạn code sau vào file wp-config.php để khi khách vào bằng domain nào thì vẫn giữa nguyên ở domain đó và link các bài post, page vẫn ở domain mà khách truy cập.

Thêm đoạn code này vào file wp-config.php




//Multi Domain for a site
define('WP_SITEURL', 'http://' . $_SERVER['HTTP_HOST']);
define('WP_HOME', 'http://' . $_SERVER['HTTP_HOST']);

Khi bạn thêm vào thì công việc gần như đã xong. Bạn đã có thể truy cập vào các parked domain (Aliases) bình thường. Nhưng có 1 vấn đề đặt ra là khi có nhiều domain trỏ về về website như vậy thì sẽ ảnh hưởng tới SEO. Google sẽ nhận diện copy bài viết và bạn sẽ bị mất thứ hạng trên công cụ tìm kiếm Google. Đừng lo lắng, mình cũng có 1 giải pháp giành cho các bạn.

Cài đặt SEO tránh giảm thứ hạng trên Google

Nếu các bạn dùng plugin Yoast SEO thì hãy thêm đoạn code sau vào file functions.php trong theme để có thể chuyển toàn bộ lưu lượng truy cập canonical về toàn bộ site chính và sẽ không bị google đánh dấu trùng nội dung khi có nhiều parked domain (Aliases)

Thêm đoạn code này  vào file functioins.php









//canonical - old domain to new domain
add_filter('wpseo_canonical', 'swpseo_canonical_domain_replace');
function swpseo_canonical_domain_replace($url){
    $domain = 'your-domain.com';// Thay đổi cái này về site chính của bạn vd ở đây là your-domain.com
    $parsed = parse_url(home_url());
    $current_site_domain = $parsed['host'];
    return str_replace($current_site_domain, $domain, $url);
}

Vậy là đã okie. Bạn có thể sử dụng thoải mái mà không sợ ảnh hưởng tới SEO rồi

 

Khắc phục lỗi font khi chạy với domain phụ

Khi đã cài đặt xong nhiều domain chạy trên 1 source wordpress nhưng bị lỗi khi load các font . Như font icon không load được như hình bên dưới

Cách khắc phục lỗi Access to Font at … form origin … has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin … is therefore not allowed access.

Bạn hãy copy đoạn code sau vào file .htaccess là được






<IfModule mod_headers.c>
    <FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|font.css|css|js)$">
    Header set Access-Control-Allow-Origin "*"
    </FilesMatch>
</IfModule>

(https://levantoan.com/huong-dan-su-dung-nhieu-domain-cho-1-website-wordpress/)

Đọc thêm..

Mapping Multiple Domains into Single Instance of WordPress

 

Editing wp-config.php

  • Go to WordPress installed root directory and look for wp-config.php file
  • Place below lines after the table_prefix line; order is very important in wp-config.php , more info
  • Go to wordpress admin page and take a look at Settings -> General. You will have WordPress Address (URL) and Site Address (URL) will be in disabled state.  It means your wordpress installation dynamic enoungh to accomadate both domain address
Mapping Multiple Domains into Single Instance of WordPress

WordPress Admin -> Settings -> General

Đọc thêm..

WordPress behind an nginx SSL reverse proxy

/etc/nginx/conf.d/ssl.conf (inside the ssl server block)
location /blog/ {
  proxy_pass http://backend:8081/;
  proxy_set_header X-Forwarded-Host $host;
  proxy_set_header X-Forwarded-Proto $scheme;
}
Add this to wp-config.php
/**
 * Handle SSL reverse proxy
 */
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
    $_SERVER['HTTPS']='on';

if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
    $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
}
If the URI on the proxy is different than the URI on the backend, add this to wp-config.php too
$_SERVER['REQUEST_URI'] = "/blog".$_SERVER['REQUEST_URI'];
where “/blog” is the URI prefix on the proxy
Đọc thêm..

Prevent SSL redirect loop using WordPress and HAProxy

This is a first post in a series on how to use HAProxy in front of WordPress. I’m using HAProxy to offload SSL connections to a WordPress site. The site itself runs on an internal IP address on port 80 while HAProxy listens on incoming connections on *:80 and *:443. Connections to *:443 will be presented the correct certificate using HAProxy’s SNI-based certificate matching algorithm. I’ll write more about that SNI-based configuration in a future post. In this post I’m going to focus on the SSL redirect loop which is happening if you use
define('FORCE_SSL_ADMIN', true);
and/or
define('FORCE_SSL_LOGIN', true);
in wp-config.php. Since HAProxy offloads the SSL connection, the web server running the WordPress site has no way to know the connection was SSL-based initially. Edit wp-config.php and add the following lines:
 define('FORCE_SSL_ADMIN', true);
define('FORCE_SSL_LOGIN', true);
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
  $_SERVER['HTTPS']='on';
We’re telling WordPress that if an X-Forwarded-Proto header is present with the value https, the connection was initially based on SSL. Obviously, the X-Forwarded-Proto header has to be injected into the HTTP header of the request by HAProxy in the first place:
frontend ft_web_ssl
  mode http
  bind 0.0.0.0:443 ssl crt /etc/haproxy/certs.d
  reqadd X-Forwarded-Proto:\ https
  ...
  ...
Make sure to use option http-server-close as well or the reqadd setting might not work as expected.
Đọc thêm..

How to add a back-to-top button on your WordPress website

Landing website pages have been all the rage for a while now and although many of them come with a great design they can also come with a caveat: long body heights. This usually means that after users are done going through our awesome content they are forced into a scrolling sprint back to our website’s header in order to examine more navigation options (which also kinda means our landing page should have more interesting calls to action, but that’s a different story).
One way to mitigate this terrible experience and improve our website’s user friendliness would be to make our header sticky (which we’ll cover in another tutorial), but that’s something that’s not always desirable. Another way, one which we’ll cover in this tutorial, is to add a so-called “back to top” button which stays fixed as we scroll down and smoothly transitions us back to the very top when it gets clicked. This kind of “scroll to top” behavior is so necessary in some use-cases that iOS even has it embedded as a feature in pretty much the core of the OS (by tapping the status bar).
Let’s go ahead and see how simple it is to add this kind of functionality to any website with a simple button.

Our button’s requirements

We’re going to start, as always, by listing our requirements; what we need to accomplish. Thus, the button must:
  1. Appear only when the user has scrolled enough so that its existence is justified.
  2. Hide itself if the user manually scrolls up into that threshold again.
  3. Always remain visible after the threshold and follow along as the user scrolls.
  4. Get us smoothly back to the very top when it’s clicked.

Markup and styling

The HTML we’ll need is extremely simple: just a button element. Go ahead and open your WordPress (child) theme’s footer.php file and right before the body element closes add the following:
<button class="button-top"></button>
footer.php
Of course the icon is up to you, I chose a simple up arrow entity for brevity.
If we refresh the page right now we should see an ugly button sitting below our website’s footer, so let’s give it some style; in our (child) theme’s stylesheet:
.button-top {
  position: fixed;
  bottom: 20px;
  right: 20px;
  z-index: 100;
  width: 60px;
  height: 60px;
  border: 0;
  border-radius: 2px;
  box-shadow: none;
  background: #145474;
  color: #fff;
  font-size: 26px;
  line-height: 20px;
  text-align: center;
  cursor: pointer;
}
style.css
And here’s how it should look:
Pretty cool so far, but before we go any further let’s add a few more styles. We want to start by having the button hidden, and then we’ll define a new class which we’ll later enable via JavaScript and turn it back to visible.
.button-top {
  ...previous code
  pointer-events: none;
  opacity: 0;
  transition: opacity .18s ease;
}

.button-top-visible {
  opacity: 1;
  pointer-events: auto;
}
style.css

Making it functional

All righty, we’ve got our button styled and ready (and invisible), time to actually make it work. First thing we need to do is to actually make it smooth scroll back to the top when it’s clicked. Let’s add that code in our theme’s scripts file (make sure jQuery is loaded!):
jQuery(function ($) {
  var $buttonTop = $('.button-top');

  $buttonTop.on('click', function () {
    $('html, body').animate({
      scrollTop: 0,
    }, 400);
  });
});
scripts.js
Now every time the button is clicked, it’ll scroll us to the very top of our website within 400 milliseconds (feel free to adjust the timing to your liking).
If we hadn’t required that the button starts hidden we’d be done right now. But we want to show it only when the user has scrolled enough to actually be useful.
What we need for this is to tap into the scroll event of the browser’s window object and check if we’re scrolled enough from the top; if we are, we’ll add that .button-top-visible CSS class and show it. If we aren’t we’ll remove it (and consequently hide the button).
So, the actual event we’re after is probably the scroll event as the name implies, but how are we going to figure out how much we’ve scrolled so far? Let’s see what jQuery offers.
.scrollTop(): Get the current vertical position of the scroll bar for the first element in the set of matched elements.
Well, that sounds exactly what we need. Let’s amend our code and do just that.
jQuery(function ($) {
  var $window = $(window);
  var $buttonTop = $('.button-top');

  $buttonTop.on('click', function () {
    $('html, body').animate({
      scrollTop: 0,
    }, 400);
  });

  $window.on('scroll', function () {
    if ($window.scrollTop() > 100) { // 100 is our threshold in pixels
      $buttonTop.addClass('button-top-visible');
    } else {
      $buttonTop.removeClass('button-top-visible');
    }
  });
});
scripts.js
Perfect! Inside our scroll event listener we check for a simple condition, if we’re scrolled more than 100 pixels we’ll show the button, if not, we’ll hide it!

Advanced: Optimizing for performance

Our button is ready at this point, it fulfills all the requirements we’ve specified when we started, but I couldn’t possibly end this tutorial without bringing awareness to the fact that our code, although elegant, comes with a performance headache: the callback function we provide to the window’s scroll event listener is going to be called an inordinate amount of times, because the scroll event by nature is fired every time the scroll position changes (which is, again, a lot lot lot more than we need).
We don’t really need to check every millisecond or so. We’ll be good sports and debounce our function so that it gets called only once we’ve stopped scrolling and X amount of time (let’s say every quarter of a second) has passed since the last call.
A naïve, quick and dirty approach is the following:
jQuery(function ($) {
  var $window = $(window);
  var $buttonTop = $('.button-top');
  var scrollTimer;

  $buttonTop.on('click', function () {
    $('html, body').animate({
      scrollTop: 0,
    }, 400);
  });

  $window.on('scroll', function () {
    clearTimeout(scrollTimer);
    scrollTimer = setTimeout(function() {
     if ($window.scrollTop() > 100) {
        $buttonTop.addClass('button-top-visible');
      } else {
        $buttonTop.removeClass('button-top-visible');
      }         
    }, 250);
  });  
})
scripts.js
We’re not exactly debouncing here, but it comes very close, and with minimal code (credits go to css-tricks). In this iteration our check will run only once we’ve stopped scrolling and 250ms have passed since the last check.
For more advanced/robust usage you can use an actual debounce implementation like the one Underscore provides.
Here’s the final outcome (feel free to scroll and click):
And that’s it! We’re ready to add a simple back-to-top button to our WordPress (or any kind of) website! Feel free to post in the comments if you decide to add it on your own website or have already done so!

(https://www.cssigniter.com/add-back-top-button-wordpress-website/)
Đọc thêm..

How to Create Custom WordPress Write/Meta Boxes

Creating meta boxes is a crucial part of WordPress theme/plugin development. It's a way to add an appealing editor to the post screen and avoids forcing users to rely on custom fields. If you've ever created a custom post type in WordPress, you've probably wanted to add some sort of additional data to it. Sure, you could use custom fields, but that's ugly. Getting started with custom meta boxes is easy, so let's dive in!
A custom meta (or write) box is incredibly simple in theory. It allows you to add a custom piece of data to a post or page in WordPress.
Imagine that you're working on a theme for a client that wants to catalog his extensive collection of concert posters. You immediately start looking to the core WordPress functionality to see how you might organize the theme: Every post will represent a poster, which is perfect for adding an image, title and description. We can also use the categories and tags system inside of WordPress to organize the posters. But what if we wanted to add a new type of meta data for the "artist" of each poster? Hmph. WordPress doesn't quite have anything for that right out of the box... which brings us to custom meta boxes.
A custom meta (or write) box is incredibly simple in theory. It allows you to add a custom piece of data to a post or page in WordPress - what's better is that it can fit directly into most of the default pages inside WP, so you can easily place it inside the Post-Editor for easy use by non-technical types. As I said in the intro, you can add this same kind of "meta data" to your post using the built in custom fields for a post or page. There's nothing wrong with this persay, but it's not a very graceful or user-friendly.
Instead, you want to create a custom meta box that contains fields for all of your data and saves all of that stuff right when the post is published. That's what we're covering here. This is broken down into three big steps:
  • Adding the meta box
  • Rendering the meta box
  • Saving the data (the right way - yes, there is a wrong way)
It's worth noting that a lot of this information can also be used inside the custom post types API (we'll get to that point later!), but for the sake of keeping things focused today, we're going to add this directly to the default post editor.
For the advanced readers in the audience: Yes, custom post types is where we'll be going with this eventually, but it's important to setup some fundamentals first. Plus, as you can use the custom meta boxes in all sorts of places, it's good for anyone to know.
Anything in this tutorial will work in a theme's functions.php file. That is not the correct place for it, however. If you're adding data to a post, chances are you want it there regardless of your front end design. As such, you should place this code some place that isn't dependent on your design: a plugin file.
The Meta Box Title
Conveniently, WordPress provides a function for adding meta boxes to a given admin screen: add_meta_box.
The codex entry is well done for this function, but here's a brief overview. Its prototype:
$id is the html ID attribute of the box. This is useful if you're loading custom CSS or Javascript on the editing page to handle the options. Otherwise, it doesn't really matter all that much.
$title is displayed at the top of the meta box.
$callback is the function that actually renders the meta box. We'll outline this in step 2.
$page is where you want the meta box to be displayed. This should be a string with 'post' or 'page' or 'some_custom_post_type'.
$context is where you want the meta box displayed. 'normal' puts it below the post editor. 'side' moves the meta box to editing screen's right sidebar (by the categories and tags, etc). 'advanced' also put the box in the same column as the post editor, but further down.
$priority tells wordpress where to place the meta box in the context. 'high', 'default' or 'low' puts the box closer to the top, in its normal position, or towards the bottom respectively. Since all meta boxes are drag-able, $priority is not a huge deal.
Finally $callback_args lets you pass data to your $callback function in the form of an array. We're not going to use this here, but it could be useful for passing some data to the meta box. Say, if your plugin had several options that influenced what was displayed in the meta box. You could pass those options values through the $callback_args array.
So, our add_meta_box call will look like this:
We can't just pop this into our plugin file alone. Doing so will result in the white screen of death, and PHP fatal error: call to undefined function. Why? Because we called add_meta_box function before WordPress was loaded. So we need to use a WordPress hook, which is part of the plugin api. Basically, functions get hooked into a given WordPress action or filter hook, then those functions are fired when that hook loads. By wrapping our add_meta_box call in a function, then hooking that function into the add_meta_boxes action hook, we avoid the fatal error.
Our code to add the meta box to our post screen would look like this:
The above code is enough to add the meta box, but now we have to render the thing and actually add fields. This is just an HTML form code mixed in with a bit of PHP to display the saved data. We don't need to include the form tags as WordPress does that for us.
Remember the string we passed as the $callback in add_meta_box? We're now going to create a function with the same name. This function will take care of all the display inside the meta box.
We're going to add several fields to our meta box: a text input, a drop down menu, and a check-box. Let's start with the text input.
But what about actually displaying the data? Well, as you'll see in step 3, we'll store this data in the wp_postmeta table using the update_post_meta function. That function has two sister functions called get_post_meta and get_post_custom, which grab data from wp_postmeta. get_post_meta only grabs data from one key, while get_post_custom grabs all of it. Because we're only really using one field at this point, let's use get_post_meta.
Also note that the add_meta_box function passes one variable to our callback: $post, which is a post object.
With the addition of a second field, we changed or get_post_meta call to get_post_custom, which returns an associative array of all the post's custom keys and values. We then just access our fields via their names. The ternary statements keep our code from throwing PHP warnings (undefined indices and such). We'll cover the esc_attr function in step three.
In the drop down, we're going to use one of WordPress's most handy functions: selected. This compares the first value, the data we saved, with the second, the <option>'s value attribute. If they're the same, the function will echo selected="selected", which makes that value display on the drop down. Pretty sweet, and it saves us from writing a bunch of if or ternary statements. You can also use the selected() function with radio buttons.
Again WordPress provides the handy function checked(). It works just like selected() comparing the first value (our saved data) to the second and echoing out checked="checked" if they're the same.
wp_nonce_field adds two hidden fields to our meta box. One of them is a nonce. These are random strings of numbers that are valid on per user per blog basis for 24 hours. Nonces are a way of verifying intention, and they make sure that WordPress doesn't do anything unless the request came from a very specific place. In other words, we don't want to accidentally update our data by somehow running our save function (see step 3) in another location other than the save_post hook, so we check to make sure the nonce is valid before doing anything.
Advertisement
The number one rule when putting anything into your database or on your site is don't trust the user. Even if that user is you.
To save our data, we're going to rely on another WordPress hook: save_post. This works just like our action hook above:
The cd_meta_box_save function will receive one argument, the post id, and take care of cleaning and saving all of our data. The save_post hook fires after the update or save draft button has been hit. So we have access to all the $_POST data, which includes our meta box fields, within our saving function. Before we can do anything, however, we have to do three things: check if the post is auto saving, verify the nonce value we created earlier, and check to make sure the current user can actually edit the post.
Now the fun stuff: actually saving our data. The number one rule when putting anything into your database or on your site is don't trust the user. Even if that user is you. To that end, before we save any data, we want to make sure there's nothing malicious in there. Fortunately WordPress provides a bunch of functions for data validation.
You already saw esc_attr() above (step 2). This one encodes ' " and < > into HTML entities. Why use this? So users couldn't type a <script> into your meta box. If you'd like to allow certain HTML tags in, but strip others, wp_kses can do that. It takes two arguments, the first of which is the string you'd like to check and the second is an associative array of allowed tags. WordPress provides many more data validation tools, just don't be afraid to use them.
We're going to use the update_post_meta function to date care of saving our data. It takes three arguments: a post ID, the meta key, and the value.
That's it! You should have a fully working meta box. Other examples you may find around the web loop through a bunch of fields without really cleaning the data. This is the wrong approach. Always use the built in data validation functions; different fields/values may require different data validation.
To use these custom fields on the front end of your site, use the get_post_meta or get_post_custom functions (see step 2).
Đọc thêm..