I am trying to create a separate download page in WordPress when the visitor clicks on a download button having link https://example.com/(any_post)/download, it will open a download page having the destination url.
What i have done?
I have created a custom field that takes link from post for this I uses below:
// Meta Box Class: DownloadLinkMetaBox
// Get the field value: $metavalue = get_post_meta( $post_id, $field_id, true );
class DownloadLinkMetaBox{
private $screen = array(
'post',
);
private $meta_fields = array(
array(
'label' => 'Download Link',
'id' => 'download_id',
'type' => 'text',
)
);
public function __construct() {
add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
add_action( 'save_post', array( $this, 'save_fields' ) );
}
public function add_meta_boxes() {
foreach ( $this->screen as $single_screen ) {
add_meta_box(
'DownloadLink',
__( 'DownloadLink', '' ),
array( $this, 'meta_box_callback' ),
$single_screen,
'normal',
'default'
);
}
}
public function meta_box_callback( $post ) {
wp_nonce_field( 'DownloadLink_data', 'DownloadLink_nonce' );
$this->field_generator( $post );
}
public function field_generator( $post ) {
$output = '';
foreach ( $this->meta_fields as $meta_field ) {
$label = '<label for="' . $meta_field['id'] . '">' . $meta_field['label'] . '</label>';
$meta_value = get_post_meta( $post->ID, $meta_field['id'], true );
if ( empty( $meta_value ) ) {
if ( isset( $meta_field['default'] ) ) {
$meta_value = $meta_field['default'];
}
}
switch ( $meta_field['type'] ) {
default:
$input = sprintf(
'<input %s id="%s" name="%s" type="%s" value="%s">',
$meta_field['type'] !== 'color' ? 'style="width: 100%"' : '',
$meta_field['id'],
$meta_field['id'],
$meta_field['type'],
$meta_value
);
}
$output .= $this->format_rows( $label, $input );
}
echo '<table ><tbody>' . $output . '</tbody></table>';
}
public function format_rows( $label, $input ) {
return '<tr><th>'.$label.'</th><td>'.$input.'</td></tr>';
}
public function save_fields( $post_id ) {
if ( ! isset( $_POST['DownloadLink_nonce'] ) )
return $post_id;
$nonce = $_POST['DownloadLink_nonce'];
if ( !wp_verify_nonce( $nonce, 'DownloadLink_data' ) )
return $post_id;
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return $post_id;
foreach ( $this->meta_fields as $meta_field ) {
if ( isset( $_POST[ $meta_field['id'] ] ) ) {
switch ( $meta_field['type'] ) {
case 'email':
$_POST[ $meta_field['id'] ] = sanitize_email( $_POST[ $meta_field['id'] ] );
break;
case 'text':
$_POST[ $meta_field['id'] ] = sanitize_text_field( $_POST[ $meta_field['id'] ] );
break;
}
update_post_meta( $post_id, $meta_field['id'], $_POST[ $meta_field['id'] ] );
} else if ( $meta_field['type'] === 'checkbox' ) {
update_post_meta( $post_id, $meta_field['id'], '0' );
}
}
}
}
if (class_exists('DownloadLinkMetabox')) {
new DownloadLinkMetabox;
};
That takes link perfectly and also able to show on front but not able to create another page.
Below code used to show in frontend
add_action( 'generate_after_entry_header', 'wpsh_single_posts_custom_meta_fields', 9 );
function wpsh_single_posts_custom_meta_fields(){
$post_id = get_the_ID();
$post = get_post( $post_id );
$download_id = get_post_meta( $post->ID, 'download_id' );
if( $download_id ) { ?>
<div >
<div >
<a style='text-transform: uppercase;' href="<?php the_permalink();?>download/" >
<i >
<svg fill="currentColor" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M0 0h24v24H0z" fill="none" />
<path d="M19.35 10.04C18.67 6.59 15.64 4 12 4 9.11 4 6.6 5.64 5.35 8.04 2.34 8.36 0 10.91 0 14c0 3.31 2.69 6 6 6h13c2.76 0 5-2.24 5-5 0-2.64-2.05-4.78-4.65-4.96zM17 13l-5 5-5-5h3V9h4v4h3z" />
</svg>
</i> Download</a>
</div>
</div>
<?php }
}
Above code will show button if the download id have link and the button have link example.com/any_post/download. Now here i don't know how to serve the link that the download_id holds of the post from it visits to .../download
I'm thinking to create a template page that serve the link but not able to do
CodePudding user response:
in your functions:
Once you have added all your code make sure to flush your rewrite rules by going to: Settings > Permalinks and clicking 'save changes'
Set your rewrite rules:
function custom_add_rewrite_rule(){
$posts = get_posts( array( 'numberposts' => -1, 'post_type' => 'post') );
if( $posts ){
foreach($posts as $post ){
add_rewrite_rule(
$post->post_name . '/download/?$',
'index.php?name=' . $post->post_name . '&post_action=download&post_id=' . $post->ID,
'top'
);
}
}
}
add_action('init', 'custom_add_rewrite_rule');
add your query_vars
:
function add_query_vars_filter( $vars ){
$vars[] = "post_action";
$vars[] = "post_id";
return $vars;
}
add_filter( 'query_vars', 'add_query_vars_filter' );
then include your custom template:
function include_custom_template($template){
if( get_query_var('post_action') && get_query_var('post_action') == 'download'){
$template = get_template_directory() ."/download.php";
}
return $template;
}
add_filter('template_include', 'include_custom_template');
and finally make a file called download.php
in your theme root and call your parameters
$download_id = get_post_meta( get_query_var('post_id'), 'download_id' );
//Your Code