Як зробити чернетку доступною для всіх?


13

У мене на веб-сайті Wordpress є кілька неопублікованих публікацій, і я намагаюся зробити його доступним для звичайних користувачів (які не ввійшли в систему) за допомогою звичайних поштових слупок ( site.com/post-here). Я розумію, що це може бути не найкраща практика, але для моєї особливої ​​мети це потрібно зробити.

Я спробував додати у свій functions.phpфайл такий фрагмент коду :

function enable_view_drafts() {
$role = get_role( 'subscriber' ); 
$role->add_cap( 'read_private_posts' ); 
$role->add_cap( 'edit_posts' );
}
add_action( 'after_setup_theme', 'enable_view_drafts');

Я також спробував initгак замість after_setup_theme. Не вдалося.

Я розумію, що зміни ролей зберігаються в базі даних, тому їх потрібно зробити лише один раз. Ось чому я використовую after_setup_themeгачок для виклику функції.

Але коли я намагаюся отримати доступ до сторінки як звичайний користувач, мені показують сторінку 404, а не вміст публікації. Я також спробував завантажити URL-адресу попереднього перегляду ( site.com/?p=212&preview=true), але це також не спрацювало.

Це мої здогадки:

  • звичайному користувачеві недостатньо capsдля читання чернетки.
  • тестування та перегляд чернетки публікацій на передній частині неможливе для будь-яких користувачів (включаючи адміністраторів).

Які зміни я повинен внести, щоб виконати те, що намагаюся зробити? Якщо це неможливо, які альтернативні рішення ви пропонуєте?

Примітка. Я не шукаю плагінних рішень.


2
Я думаю, тут є трохи плутанини. Якщо хтось не зареєстрований, він / вона не є користувачем, тому у нього немає жодних обмежень. Ці абоненти є користувачами, тому вони повинні бути зареєстровані і зробити Ввійти , щоб бути визнаними в якості абонентів. Ви не можете надавати можливості тому, хто не ввійшов у систему. Якщо ви хочете, щоб хтось, хто не ввійшов у систему, переглянув ваші публікації, вони просто не відрізняються від опублікованих публікацій. Отже, чому б не опублікувати його? Або ви хочете показати чернетку передплатникам (увійшли в систему як підписники)?
gmazzap

@GM: Я намагаюся зробити неопубліковані публікації доступними для всіх, хто знає пряме посилання на цю публікацію. Це може здатися дивним вимогою, але мені це потрібно для проекту. Як я вже згадував у своєму запитанні, якщо це неможливо - чи можете ви запропонувати інші роботи (якщо ви, звичайно, знаєте)?
Амаль Муралі

@GM: Ви знаєте плагін, який це робить?
Амаль Муралі

Ви читали відповідь трохи нижче з 3 оновленнями? Він пояснює, як це зробити, і в кінці відповіді ви знайдете посилання для завантаження повного робочого плагіна з github.
gmazzap

2
Для пізніших читачів: Цей плагін Домініка Шиллінга доступний на GitHub.
кайзер

Відповіді:


12

Ви не можете призначити можливості невідомим користувачам. Якщо ви хочете зробити публікацію видимою для всіх, створіть окрему URL-адресу для цих публікацій та додайте елемент керування до редактора публікацій, щоб увімкнути попередній перегляд лише для вибраних публікацій.
Коли ця URL-адреса викликається, перевірте, чи дозволено попередній перегляд публікації та чи публікація ще не опублікована. Також переконайтесь, що пошукові системи ігнорують цю URL-адресу.

Для URL-адреси я використовую кінцеву точку :

add_rewrite_endpoint( 'post-preview', EP_ROOT );

Тепер ви можете створити такі URL-адреси, як ...

http://example.com/post-preview/123

… Де 123ідентифікатор пошти

Потім використовуйте обробник зворотного дзвінка, щоб перевірити ідентифікатор повідомлення, перевірити, чи він дійсний, і перезапишіть основний запит. Це, мабуть, єдиний прийнятний варіант використання query_posts(). :)

Скажімо, кінцевою точкою є клас T5_Endpoint(модель), а вихідний обробник - клас T5_Render_Endpoint(вид), який отримує модель, передану раніше. Тоді, ймовірно, існує метод, render()закликаний template_redirect:

public function render()
{
    $post_id = $this->endpoint->get_value();

    if ( ! $post_id )
        return;

    if ( 1 !== $this->meta->get_value( $post_id )
        or 'publish' === get_post_status( $post_id )
        )
    {
        wp_redirect( get_permalink( $post_id ) );
        exit;
    }

    $query = array (
        'suppress_filters' => TRUE,
        'p'                => $post_id,
        'post_type'        => 'any'
    );

    query_posts( $query );

    add_action( 'wp_head', 'wp_no_robots' );
}

$this->meta- інша модель (клас T5_Post_Meta) для мета-значення пост, яка контролює, чи дозволено попередній перегляд. Елемент керування встановлюється у поле Опублікувати ( діяpost_submitbox_misc_actions ), подане іншим представленням, що отримує той самий мета-клас.

знімок екрана

Тож T5_Post_Metaзнає, де і коли зберігати мета-значення, погляди щось роблять із цим.
Крім того, підключітьсяtransition_post_status до видалення метаполя публікації після публікації публікації. Ми не хочемо витрачати ресурси, правда?

Це лише контур. Є багато деталей для висвітлення… Я написав невеликий плагін, який показує, як це здійснити: T5 Public Preview .


Дуже дякую. Нарешті я досяг декількох налаштувань своєї мети. Дивовижно. : D
Амаль Муралі

6

Я вирішив цю проблему тим, що, на мою думку, був більш простим способом, ніж відповідь @ toscho вище.

Моя ситуація використання - я використовую ту саму базу даних для внутрішнього сайту інтрамережі та загальнодоступного веб-сайту, а робочий процес полягає в тому, що автори пишуть чернетки та діляться ними з іншими користувачами, які переглядають ці чернетки на сайті інтрамережі, перед публікацією. Я спеціально не хотів вимагати від рецензентів увійти, щоб побачити чернетки, тому я просто залежно від константи, ENV_PRODUCTIONяка встановлюється у файлі wp-config на основі імені хоста в $_SERVER['SERVER_NAME']. Ось що ENV_PRODUCTIONтут роблять перевірки ; просто скорочуючи всі ці фільтри, якщо переглядається виробничий сайт.

Це трохи дивно, тому що ви повинні підключитися після того, як WP_Query видаляє всі повідомлення з масиву $ wp_query->, але мені це здається стабільним і безпечним.

/*
 * On staging site home and archives, drafts should be visible.
 */
function show_drafts_in_staging_archives( $query ) {
    if ( ENV_PRODUCTION )
        return;

    if ( is_admin() || is_feed() )
        return;

    $query->set( 'post_status', array( 'publish', 'draft' ) );
}

add_action( 'pre_get_posts', 'show_drafts_in_staging_archives' );


/*
 * Make drafts visible on staging site single views.
 *
 * (Because on single views, WP_Query goes through logic to make sure the 
 * current user can edit the post before displaying a draft.)
 */
function show_single_drafts_on_staging( $posts, $wp_query ) {
    if ( ENV_PRODUCTION )
        return $posts;

    //making sure the post is a preview to avoid showing published private posts
    if ( ! is_preview() )        
        return $posts;

    if ( count( $posts ) )
        return $posts;

    if ( !empty( $wp_query->query['p'] ) ) {
        return array ( get_post( $wp_query->query['p'] ) );
    }
}

add_filter( 'the_posts', 'show_single_drafts_on_staging', 10, 2 );

До фільтрів є дві окремі частини.

  • Фільтр на гачку "pre_get_posts" встановлює за замовчуванням post_status "опублікувати, скласти" на сайті постановки. Це поверне чернетки публікацій у списки архівів.
  • Для окремих представлень потрібен окремий фільтр, оскільки в класі WP_Query є певна логіка для видалення чернетки публікацій з результатів запиту, якщо поточний cuser не може їх редагувати. Я обійшов це, відфільтрувавши "the_posts" і додавши публікацію, яку я хотів повернути до результатів.

2
Це неймовірно , дуже дякую, що поділилися цим. Абсолютно ідеально і саме те, що мені було потрібно.
Крістіан Варга

Куди я кладу цей код? (який файл (и)?)
Жоеліо

@Joelio Чи можете ви бути конкретними щодо проблеми, яку ви вирішуєте? Як простий підхід, я просто додав цей код до моїх функцій.php і додав просте визначення до свого wp-config.php, який встановив константу ENV_PRODUCTION на істинну або помилкову залежно від домену запиту.
goldenapples

@goldenapples Я додав цей фрагмент коду до своєї function.php, що мені додати до wp-config? Дякуємо за допомогу
Graham Slick

@MatthiasGrahamSlick - Вам просто потрібно щось, що встановить ENV_PRODUCTIONконстанту, якщо ви працюєте. Я використовував domain.com для виробництва та staging.domain.com для постановки, тож моя лінія: define( 'ENV_PRODUCTION', false === stripos( $_SERVER['HTTP_HOST'], 'staging' ) );Чи це допомагає?
goldenapples

0

Я думаю, що плагін "Редактор ролей користувачів", доступний на веб-сайті WordPress.org, може бути тим, що ви шукаєте. До речі, чому ви хочете надати доступ до своїх чернеток усім? Я особисто не можу придумати екземпляр, де це було б потрібно.


Ні, як згадувалося в питанні, я не шукаю плагінних рішень. Корпус використання трохи складний, але я впевнений, що це найкраще рішення для цього конкретного завдання, яке я намагаюся виконати. :-)
Амаль Муралі

Мене також бентежить причина. Якщо ви хочете, щоб усі бачили публікацію, чому б просто не опублікувати публікацію? Ви можете використовувати спеціальні поля на пошті для відстеження будь-якого спеціального стану, який ви хочете визначити.
КенБ

Я дозволяю користувачам переглядати вміст, але з певної причини я не хочу публікувати публікації.
Амаль Муралі

0

Ви можете просто змінити видимість на сторінці / публікації на "Приватне", яке видно лише для редакторів та адміністраторів, а не для публічних відвідувачів, пошукових систем, RSS-каналів тощо.


0

Я думаю, що коментар GM є найкращим тут. Я припускаю, що ви намагаєтесь зробити наступне:

  1. Написати допис
  2. Зберегти як чернетку
  3. Дозволити зовнішньому користувачеві (не ввійшов у систему) переглянути проект для затвердження
  4. Опублікувати

Це правильно?

На жаль, я не можу придумати жодного простого способу зробити це. Ви можете опублікувати його як приватну публікацію, щоб їм було потрібно ввести пароль, щоб переглянути його, але для цього вам потрібно увійти. Ви також можете захистити його паролем, але тоді він все ще з’явиться у вашій стрічці та списку останніх публікацій тощо. Чи не можете ви створити обліковий запис гостя та не вказати ім’я користувача / пароль, коли ви дасте їм URL?

Прочитайте тут для отримання додаткової інформації: http://codex.wordpress.org/Content_Visibility

Крім того, є плагін, який може відповідати вашим потребам: http://wordpress.org/extend/plugins/shareadraft/ Я швидко ознайомився з кодом, і, здається, розробник змінює значення, повернене get_post_status, щоб ви могли бути вміє пограти з цим:

http://codex.wordpress.org/Function_Reference/get_post_status

HTH


0

Якщо вам все одно, чи публікація "опублікована" чи ні, просто хочете, щоб вона була доступною будь-кому за звичайною опублікованою URL-адресою і не відображалася на головній сторінці / результатах пошуку / RSS-каналах тощо тощо, цей плагін працював із WP 4.6. 1 і дозволяє точно настроїти місце, де з’являється публікація:

https://wordpress.org/plugins/wp-hide-post/

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.