{"id":15039936,"url":"https://github.com/automattic/liveblog","last_synced_at":"2025-05-15T15:07:35.626Z","repository":{"id":3487063,"uuid":"4542883","full_name":"Automattic/liveblog","owner":"Automattic","description":"Liveblogging done right. Using WordPress.","archived":false,"fork":false,"pushed_at":"2025-02-18T11:30:35.000Z","size":36519,"stargazers_count":309,"open_issues_count":140,"forks_count":123,"subscribers_count":136,"default_branch":"master","last_synced_at":"2025-05-11T07:12:16.479Z","etag":null,"topics":["wordpress","wordpress-plugin","wpvip-plugin"],"latest_commit_sha":null,"homepage":"https://wordpress.org/plugins/liveblog/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Automattic.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2012-06-04T03:14:54.000Z","updated_at":"2025-04-04T03:01:51.000Z","dependencies_parsed_at":"2024-12-28T08:02:26.628Z","dependency_job_id":"f043d48a-bc5b-4ae5-aa53-49511a072fc7","html_url":"https://github.com/Automattic/liveblog","commit_stats":{"total_commits":1290,"total_committers":83,"mean_commits":"15.542168674698795","dds":0.758139534883721,"last_synced_commit":"52fe0e2e3319e7d06582f3050e7655f3988f31ef"},"previous_names":[],"tags_count":30,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Automattic%2Fliveblog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Automattic%2Fliveblog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Automattic%2Fliveblog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Automattic%2Fliveblog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Automattic","download_url":"https://codeload.github.com/Automattic/liveblog/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254364270,"owners_count":22058878,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["wordpress","wordpress-plugin","wpvip-plugin"],"created_at":"2024-09-24T20:44:00.668Z","updated_at":"2025-05-15T15:07:30.615Z","avatar_url":"https://github.com/Automattic.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Liveblog\n\n* Contributors: [automattic](http://profiles.wordpress.org/automattic), [nbachiyski](http://profiles.wordpress.org/nbachiyski), [batmoo](http://profiles.wordpress.org/batmoo), [johnjamesjacoby](http://profiles.wordpress.org/johnjamesjacoby), [philipjohn](http://profiles.wordpress.org/philipjohn)\n* Tags: liveblog\n* Requires at least: 4.4\n* Requires PHP: 5.6\n* Tested up to: 4.9.8\n* Stable tag: 1.9.7\n* License: GPLv2 or later\n* License URI: http://www.gnu.org/licenses/gpl-2.0.html\n\n[![Build Status](https://travis-ci.org/Automattic/liveblog.svg?branch=master)](https://travis-ci.org/Automattic/liveblog)\n\nEmpowers website owners to provide rich and engaging live event coverage to a large, distributed audience.\n\n## Description\n\nYour readers want your updates as quickly as possible, and we think we provide the easiest and the most flexible publishing environment to make that happen. Sometimes though, that’s just not enough.\n\nWhen you’re covering a fast-paced event — the latest Apple unveiling, an F1 Grand Prix, or the Super Bowl — a full blog post for each individual update is a poor experience for your authors and your audience.\n\nThe [WordPress.com VIP Liveblog Add-On](http://vip.wordpress.com/liveblog-add-on/) was purpose-built to address these issues specifically.\n\nHere’s what makes it special:\n\n * Post updates right from the front-end of your site (no need to use the `/wp-admin` dashboard)\n * Viewers of your Liveblog get new entries served to them instantly and automatically, without needing to refresh their browser.\n * Your authors can drag-and-drop photos right into the Liveblog area, without needing to navigate to separate browser tabs or windows.\n * There’s no need for a separate site dedicated to liveblogging: *every* post can be a liveblog, even existing ones.\n\nIf you'd like to check out the code and contribute, [join us on github](https://github.com/Automattic/liveblog), pull requests are more than welcome.\n\n## Installation\n\n1. Upload the `liveblog` folder to your plugins directory (e.g. `/wp-content/plugins/`)\n2. Activate the plugin through the 'Plugins' menu in WordPress\n3. You can enable the liveblog on any post's edit page\n\n### Overview\n\nThe entry system supports `#hashtags`, `/commands`, `@authors` and `:emoji:` with an autocomplete system to help speed up the process. These extensions are filtered on save, for example a hashtag `#football` would be saved as `\u003cspan class=\"liveblog-hash term-football\"\u003efootball\u003c/span\u003e` allowing easy styling. The container of the entry will also receive the same class `term-football`.\n\nThe command system has one inbuilt command:\n\n`/key`: Which defines an entry to a key event, it adds the meta key to entry `liveblog_key_entry`. A key event can be styled using the `.type-key` class.\n\nTo display a key event box you can add the `[liveblog_key_events]` shortcode in your theme, e.g. in the sidebar, or you can use the Liveblog Key Events widget. Entries used with the key command will be inserted to both this box and the main feed. It also acts an anchor system to jump to parts of the main feed. It's not necessary to include the shortcode for the /key command to be enabled.\n\nAn example of using the key command would be an author writing the following in the New Entry box:\n\n```\nNew iPad announced, launching next week — more info to come. /key\n```\n\nYou can add new commands easily with a filter, the most basic command will add a class to entry, so you could do a simple  `/highlight` which would add `type-highlight` to the entry container, letting you style the background color:\n\n``` php\nadd_filter( 'liveblog_active_commands', 'add_highlight_command', 10 );\n\n\nfunction add_highlight_command( $commands ) {\n  $commands[] = highlight;\n  return $commands;\n}\n```\n\nA command can have both a filter called before the entry is saved, or an action that is called after it’s saved:\n\n``` php\napply_filter( \"liveblog_command_{$command}_before\", $arg );\ndo_action( \"liveblog_command_{$command}_after\", $arg );\n```\n\n#### Customizing Key Events Shortcode\n\nAs mentioned earlier you can add the key events section by using `[liveblog_key_events]`. If you wish to change the title from the default `Key Events` then you can add a title attribute:\n\n ``` php\n [liveblog_key_events title=\"My New Title\"]\n ```\n If want to remove the title, good example when placing the shortcode in a widget.\n\n ``` php\n [liveblog_key_events title=\"false\"]\n ```\n\nA key event entry can be altered in to two ways:\n\n**Template:** This is how each entry will be rendered. There are two inbuilt templates: list and timeline, or you can add your own using a filter:\n\n```php\nadd_filter( 'liveblog_key_templates', 'add_template' );\n\nfunction add_template( $templates ) {\n  $templates['custom'] = array( 'key-events.php', 'div', 'liveblog-key-custom-css-class' );\n  return $templates;\n}\n```\n\nThere's a few things to note here:\n\n* `key-events.php` points to `liveblog` folder in the current active theme directory, in this case we our loading template file `liveblog/key-events.php`.\n* `div` is where we set the element type that wraps all entries, in the case where you wanted to build a list, you would set this to `ul`.\n* `liveblog-key-custom-css-class` is a class that will be added to the wrapper element of the entry to help with styling, in this case it would look like: `\u003cdiv class=\"liveblog-key-custom-css-class\"\u003e...\u003c/div\u003e`\n\nAn example of a template file is:\n\n```php\n\u003cdiv class=\"\u003c?php echo esc_attr( $css_classes ); ?\u003e\" \u003e\n\t\u003ca href=\"#liveblog-entry-\u003c?php echo esc_attr( $entry_id ); ?\u003e\"\u003e\n\t\t\u003c?php echo WPCOM_Liveblog_Entry_Key_Events::get_formatted_content( $content, $post_id ); ?\u003e\n\t\u003c/a\u003e\n\u003c/div\u003e\n```\n\n**Format:** This is how each entries content is filtered, there are three inbuilt formats:\n\n* Full - which shows content without filtering\n* First Sentence - which will return everything until it hits either `.?!`\n* First Linebreak - which will return everything until it hits a linebreak (Shift + Enter) or `\u003cbr /\u003e`.\n\nFormats add an extra level of control to how the key events section looks. If using the `timeline` template with `first sentence` and the following is entered into the new entry box:\n```\nNew iPad announced. With plan to ship next month, pre-orders starting 23rd September retailing at $499 for 16gb $599 32gb. /key\n```\n\nThe main feed would show the full text, and the key events section would only show:\n```\nNew iPad announced\n```\n\nYou can add your own using a filter:\n\n```php\nadd_filter( 'liveblog_key_formats', 'add_format' );\n\nfunction add_format( $formats ) {\n  $formats['strip-tags'] = 'new_format';\n  return $formats;\n}\n\nfunction new_format( $content ) {\n  $content = strip_tags( $content );\n  return $content;\n}\n```\n\nIn the example above we are adding a format `Strip Tags`, which removes any HTML tags from the content.\n\nBelow is the full example of adding both:\n\n``` php\nfunction liveblog_add_key_event_template() {\n\n\tadd_filter( 'liveblog_key_templates', 'add_template' );\n\tadd_filter( 'liveblog_key_formats',   'add_format' );\n\n\tfunction add_template( $templates ) {\n\t\t$templates['custom'] = array( 'key-events.php', 'div', 'liveblog-key-custom-css-class' );\n\t\treturn $templates;\n\t}\n\n\tfunction add_format( $formats ) {\n\t\t$formats['strip-tags'] = 'new_format';\n\t\treturn $formats;\n\t}\n\n\tfunction new_format( $content ) {\n\t\t$content = strip_tags( $content );\n\t\treturn $content;\n\t}\n}\n\nadd_action( 'init', 'liveblog_add_key_event_template' );\n```\n\nSelecting which template or format to use for liveblog happens in the admin panel on the edit of page of the post:\n\n\u003cimg width=\"961\" alt=\"687474703a2f2f73686172652e61676e65772e636f2f477961692b\" src=\"https://user-images.githubusercontent.com/12199101/199851010-3a893bcd-f4e6-4634-8ccc-45bd98131941.png\"\u003e\n\n#### Managing Hashtags\nHashtags are manageable in the admin area. Under Posts there will be a menu for Hashtags. Please note that the slug is used, not the name.\n\n#### Emojis\nWhen a `:emoji:` is inserted into an entry it is converted into:\n\n`\u003cimg src=\"//s.w.org/images/core/emoji/72x72/1f44d.png\" class=\"liveblog-emoji emoji-+1\"\u003e`\n\n#### Extending the Admin Meta Box\nIf you need to extend the Admin Meta Box there are a few filters and actions to make this easier. As an example, let's add a section with a text input and a button to save. To start we need to add the fields:\n\n**Filter**\n``` php\nadd_filter( 'liveblog_admin_add_settings', array( __CLASS__, 'add_admin_options' ), 10, 2 );\n\npublic static function add_admin_options( $extra_fields, $post_id ) {\n  $args = array(\n    'new_label'  =\u003e __( 'My new field', 'liveblog' ),\n    'new_button' =\u003e __( 'Save', 'liveblog' ),\n  );\n\n  $extra_fields[] = WPCOM_Liveblog::get_template_part( 'template.php', $args );\n  return $extra_fields;\n}\n```\n**Template**\n``` php\n\u003chr/\u003e\n\u003cp\u003e\n  \u003clabel for=\"liveblog-new-input\"\u003e\u003c?php echo esc_html( $new_label ); ?\u003e\u003c/label\u003e\n  \u003cinput name=\"liveblog-new-input\" type=\"text\" value=\"\" /\u003e\n  \u003cbutton type=\"button\" class=\"button button-primary\" value=\"liveblog-new-input-save\"\u003e\u003c?php echo esc_html( $new_button ); ?\u003e\u003c/button\u003e\n\u003c/p\u003e\n```\nNext we catch when the user has clicked our new save button `liveblog-new-input-save`:\n\n``` php\nadd_action( 'liveblog_admin_settings_update', array( __CLASS__, 'save_template_option' ), 10, 3 );\n\npublic static function save_template_option( $response, $post_id ) {\n  if ( 'liveblog-new-input-save' == $response['state'] \u0026\u0026 ! empty( $response['liveblog-new-input-save'] ) ) {\n      //handle your logic here\n  }\n}\n```\n\n### Hooking into Entries\nThere is five useful filters to alter entries at current stages:\n\n**Before inserting into the database**\n``` php\nadd_filter( 'liveblog_before_insert_entry', array( __CLASS__, 'filter' ), 10 );\n\npublic static function filter( $entry ) {}\n```\n\n**Before inserting updated entry into the database**\n``` php\nadd_filter( 'liveblog_before_update_entry', array( __CLASS__, 'filter' ), 10 );\n\npublic static function filter( $entry ) {}\n```\n\n**Before we show preview (how we convert `:emoji:` back to `\u003cimg\u003e`)**\n``` php\nadd_filter( 'liveblog_preview_update_entry', array( __CLASS__, 'filter' ), 10 );\n\npublic static function filter( $entry ) {}\n```\n\n**Before we allow the entry to edited (how we convert `\u003cimg\u003e` back to `:emoji:`)**\n``` php\nadd_filter( 'liveblog_before_edit_entry', array( __CLASS__, 'filter' ), 10 );\n\npublic static function filter( $content ) {}\n```\n\n**Before the entry JSON is sent to the frontend**\n``` php\nadd_filter( 'liveblog_entry_for_json', array( __CLASS__, 'filter' ), 10, 2 );\n\npublic static function filter( $entry, $object ) {}\n```\n\n### Altering hashtags, commands, authors and emoji\nIt is possible to set your own symbol and / or change the class prefix for `#hashtags`, `/commands`, `@authors` and `:emoji:`. These are handled by filters:\n\n``` php\nadd_filter( 'liveblog_{type}_prefixes', array( __CLASS__, 'filter' ) );\nadd_filter( 'liveblog_{type}_class', array( __CLASS__, 'filter' ) );\n```\nLet’s say you decide to use `!` instead of `#` for `#hashtags`, therefore you expect them to be `!hashtag`:\n\n``` php\nadd_filter( 'liveblog_hashtags_prefixes', array( __CLASS__, 'filter' ) );\n\npublic static function filter( $prefixes ) {\n  $prefixes = array( '!', '\\x{21}' );\n  return $prefixes;\n}\n```\nCurrently hashtags use the class prefix `term-`, you can change that to whatever you need - in this case let’s change to `hashtag-`:\n\n``` php\nadd_filter( 'liveblog_hashtags_class', array( __CLASS__, 'filter' ) );\n\npublic static function filter( $class_prefix ) {\n  $class_prefix = 'hashtag-';\n  return $class_prefix;\n}\n```\n\n### Shortcode Filtering\nDevelopers have to ability to exclude shortcodes from being used within the content of a live entry. By default the in built key events widget short code is excluded, but others can be added easily enough from within the themes ``` functions.php ```.\n\n``` php\n    // Added to Functions.php\n\n    function liveblog_entry_add_restricted_shortcodes() {\n\n    \tadd_filter( 'liveblog_entry_restrict_shortcodes', 'add_shortcode_restriction', 10, 1 );\n\n    \tfunction add_shortcode_restriction( $restricted_shortcodes ) {\n\n    \t\t$restricted_shortcodes['my-shortcode'] = 'This Text Will Be Inserted Instead Of The Shortcode!';\n    \t\t$restricted_shortcodes['my-other-shortcode'] = '\u003ch1\u003eHere is a Markup Shortcode Replacement\u003c/h1\u003e';\n\n    \t\treturn $restricted_shortcodes;\n    \t}\n    }\n\n    add_action( 'init', 'liveblog_entry_add_restricted_shortcodes' );\n\n```\n\nThe functionality takes a associative array of key value pairs where the key is the shortcode to be looked up and the value is the replacement string.\n\nSo, given the example above an editor adding any of the shortcode formats:\n\n``` [my-shortcode]``` / ``` [my-shortcode][/my-shortcode]``` / ``` [my-shortcode arg=\"20\"][/my-shortcode]```\n\nwould see ``` This Text Will Be Inserted Instead Of The Shortcode! ``` outputted on live entry.\n\nBy default the inbuilt ``` [liveblog_key_events] ``` shortcode is replaced with ```We Are Blogging Live! Check Out The Key Events in The Sidebar```.\n\nTo override this behaviour simple redefine the array key value:\n\n``` php\n$restricted_shortcodes['liveblog_key_events'] = 'Here is my alternative output for the shortcode! \u003ca href=\"/\"\u003eClick Here to Find Out More!\u003c/a\u003e';\n```\n\n### Auto Archiving of Live Blog Posts\nThis feature was added at the request of the community and solves the issues where Editors will forget to archive old Live Blog's leaving them live indefinitely.\n\nAuto archive works by setting an expiry to the Post Meta for live blog posts. This expiry is calculated using the date of the latest liveblog entry + the number of days configured.\n\nOnce the expiry date is met the live blog post will be auto archived. It is however possible to re-enable an auto archived Live Blog Post,\nsimply click the enable button in the post Liveblog meta box and the expiry will be extended by the number of days configured from the latest liveblog entry date. The auto archiving feature will then re-archive the post at the new expiry date.\n\nIn order to configure the number of days to autoarchive after, a filter has been implemented. By default the value is NULL and as such disables the feature. To enable it simply apply a value to the filter e.g:\n\n```\nadd_filter( 'liveblog_auto_archive_days', function( $auto_archive_days ) {\n  $auto_archive_days = 50;\n  return $auto_archive_days;\n}, 10, 1 );\n```\n\n### WebSocket support\n\nBy default this plugin uses AJAX polling to update the list of Liveblog entries. This means that there is a delay of a few seconds between the moment a entry is created and the moment it is displayed to the users. For a close to real-time experience, it is possible to configure Liveblog to use WebSockets instead of AJAX polling. To achieve this, Liveblog uses [Socket.io](http://socket.io), [Redis](http://redis.io) and [socket.io-php-emitter](https://github.com/rase-/socket.io-php-emitter) (responsible for sending messages from PHP to the Socket.io server via Redis).\n\nIt is important to note that, since for now the Socket.io server has no way to tell if a client is an authenticated WordPress user or not and what are its capabilities, WebSockets will be used only for public Liveblog posts.\n\nFollow the instructions below to enable WebSocket support.\n\n#### Requirements\n\nHere is a list of what needs to be installed on the server to enable WebSocket support:\n\n* [Node.JS](https://nodejs.org/) - to run the Socket.io server.\n* [Redis](http://redis.io) - responsible for sending messages from WordPress to the Socket.io server.\n* [Composer](https://getcomposer.org/) - to install [socket.io-php-emitter](https://github.com/rase-/socket.io-php-emitter) and [Predis](https://github.com/nrk/predis) (Redis client).\n* PHP \u003e= 5.3\n\n#### Install dependencies\n\nConnected via SSH on the server, it is necessary to run the following commands from the Liveblog plugin directory to install WebSocket support dependencies:\n\n```\ncomposer install     # to install socket.io-php-emitter and Predis (a PHP client for Redis)\ncd nodeapp\nnpm install     # to install socket.io and the adapter socket.io-redis\n```\n\n#### Configuration\n\nAdd the following constants to wp-config.php to configure Liveblog plugin to use WebSockets:\n\n* ```LIVEBLOG_USE_SOCKETIO```: set this constant to true to enabled WebSocket support. Default: false.\n* ```LIVEBLOG_SOCKETIO_URL```: URL used by the Socket.io client to connect to the Socket.io server. Default: YOUR_SITE_DOMAIN:3000.\n* ```LIVEBLOG_REDIS_HOST```: Redis server host. Default: localhost.\n* ```LIVEBLOG_REDIS_PORT```: Redis server port. Default: 6379.\n\n#### Running the Socket.io server\n\nTo start the Socket.io server go to the plugin directory and run:\n\n```\nnode nodeapp/app.js\n```\n\nThis will start a Socket.io server on port 3000 listening to a Redis server running on localhost:6379. It is possible to use the parameters bellow to change the app default values:\n\n```\n--socketio-port [port]\n--redis-host [host]\n--redis-port [port]\n```\n\nFor more information on the accepted parameters run:\n\n```\nnode nodeapp/app.js --help\n```\n\n#### Making sure everything is working\n\nTo test that everything is working, after following the steps above, open a Liveblog post in two different browser windows and check that whenever a user changes the list of entries in one window, the list in the other window is refreshed in \"real-time\". It is also possible to use the browser developer tools to verify that there are no AJAX requests being sent every few seconds to check for changes in the list of entries. Instead the browser is receiving changes using a single WebSocket connection whenever they occur.\n\n#### Important note about private Liveblog posts\n\nWhen using Liveblog with WebSocket, the plugin will create a unique key for each Liveblog post (based on the post ID and its status). This key is shared with the users with permission to see the corresponding post when the page is loaded. The key is then send by the user's browser to the Socket.io server when a connection is established. Whenever there is a new Liveblog entry (or a Liveblog entry is updated or deleted), the Socket.io server will send a message only to the clients that provided the right key. This system is enough to prevent someone without permission to see the post from receiving Liveblog entries emitted by the Socket.io server but it has an important limitation. Once a user with permission receives the post key, if he saves it somewhere, he will be able to receive messages from the Socket.io server for that particular post even if for some reason he loses access to the post (for example if the user is removed from WordPress).\n\nIf you are using private Liveblog posts to share sensitive data and it is important that, once a user loses access to the post, he is not able to receive messages emitted by the Socket.io server anymore, consider using the 'liveblog_socketio_post_key' filter to implement your own criteria to generate the post key. For example, you could generate a random post key for each post that is saved as a post meta and that can be manually invalidated by an editor whenever necessary.\n\n#### Tips for debugging\n\nIf for some reason the plugin is not able to use WebSockets to refresh the list of entries, below is a list of tips that might help you debug where is the problem:\n\n* Use your browser developer tools network tab to check if a WebSocket connection was established or check the browser console for errors when trying to establish it.\n* Check if the Node.js app that starts the Socket.io server is running. The app won't start or will stop running if unable to connect to the Redis server.\n* The plugin will fallback to AJAX polling if unable to connect to the Redis server.\n* It is possible to see all the messages received by the Redis server using the command ```redis-cli MONITOR```\n* To see Socket.io server debug messages start the Node.js app with the command ```DEBUG=socket.io* node nodeapp/app.js```\n\n## Screenshots\n\n![The entry form is the simplest possible](https://raw.github.com/Automattic/liveblog/master/.wordpress-org/screenshot-1.png)\n![Writers can preview before posting](https://raw.github.com/Automattic/liveblog/master/.wordpress-org/screenshot-2.png)\n![New posts are highlighted](https://raw.github.com/Automattic/liveblog/master/.wordpress-org/screenshot-4.png)\n![Adding images is a matter of just drag-and-drop](https://raw.github.com/Automattic/liveblog/master/.wordpress-org/screenshot-5.png)\n![Dragged photos are automatically inserted](https://raw.github.com/Automattic/liveblog/master/.wordpress-org/screenshot-6.png)\n![Typical liveblog view](https://raw.github.com/Automattic/liveblog/master/.wordpress-org/screenshot-8.png)\n\n## In-Depth Documentation\n\n#### Creating a Liveblog\nThe liveblog lives inside of a regular WordPress post. First create a new post, complete with title, category, and maybe a short introduction. Once the liveblog plugin is installed, you will see a liveblog box on your \"Edit Post\" page. Simply click \"Enable\" to activate it, and publish the post.\n\nIf you can't find the box, be sure that it is toggled on under \"Screen Options\" in the top right corner of posting page.\n\n![Screen options](http://vip.files.wordpress.com/2013/01/screen-shot-2013-01-18-at-12-19-13-pm.png)\n\n#### Posting to the Liveblog\nTo post to the liveblog, navigate to the live post, and start typing. Click \"Publish Update,\" and your readers will see the post appear at the top of their screen. That's all there is to it.\n\n![Click Publish Update](http://vip.files.wordpress.com/2013/01/screen-shot-2013-01-18-at-12-21-43-pm.png)\n\n#### Adding a Photo\nTo add a photo to your update, simply drag-and-drop it into the posting box from your desktop. It will upload the image and include a link. To see the image, click \"Preview.\"\n\nYou can also add photos from the internet by pasting in the direct URL to the image.\n\n![add photos](http://vip.files.wordpress.com/2013/01/drag.png)\n\n#### Embedding Media\nTo embed the media, simply paste the URL while viewing the media into the posting box on its own line. More details can be found about each media type in the links below:\n* [Tweets](http://en.support.wordpress.com/twitter/twitter-embeds/)\n* [YouTube videos](http://en.support.wordpress.com/videos/youtube)\n* [Vimeo videos](http://en.support.wordpress.com/videos/vimeo/)\n* [Instagram photos](http://en.support.wordpress.com/images/instagram/)\n* [Hulu clips](http://en.support.wordpress.com/videos/hulu/)\n* [Spotify songs](http://en.support.wordpress.com/audio/spotify/)\n\n![Screen shot for media embeds](http://vip.files.wordpress.com/2013/01/screen-shot-2013-01-18-at-12-32-59-pm.png)\n\n#### Formatting a Post\nThe liveblog posting box takes standard HTML formatting. To format text, simply wrap it in HTML tags.\n\nExamples:\n\n* \u0026lt;strong\u0026gt;\u003cstrong\u003ebold\u003c/strong\u003e\u0026lt;/strong\u0026gt;\n* \u0026lt;i\u0026gt;\u003cem\u003eitals\u003c/em\u003e\u0026lt;/i\u0026gt;\n* \u0026lt;u\u0026gt;\u003cspan style=\"text-decoration: underline;\"\u003eunderline\u003c/span\u003e\u0026lt;/u\u0026gt;\n\nLinks that are pasted directly the posting box will also be automatically hyperlinked.\n\n#### Manually embed a Liveblog\n\nSometimes you may need to manually insert the Liveblog into your theme. For this, we provide a function which simply outputs the Liveblog HTML on a post where the Liveblog is enabled.\n\u003e wpcom_liveblog_get_output\n\n#### Editing Previous Posts\nWhile a liveblog is enabled, you can edit previous posts by clicking the \"Edit\" button next to the update.\n\n![Edit post](http://vip.files.wordpress.com/2013/01/screen-shot-2013-01-18-at-11-40-43-am.png)\n\n#### Archiving a Liveblog\nOnce the event has wrapped up, you can archive your liveblog. This means that visitors will still be able to see the blog, but the editing tools will go away and the post will stop polling for updates. You can archive and re-enable a liveblog from the Edit Post page.\n\n![Archiving a liveblog](http://vip.files.wordpress.com/2013/01/screen-shot-2013-01-18-at-11-15-12-am.png)\n\nWhen a liveblog is archived, your editors will see a notification that says the liveblog must be enabled to accept new posts.\n\n![Notification that liveblog must be enables](http://vip.files.wordpress.com/2013/01/screen-shot-2013-01-18-at-11-19-52-am.png)\n\n#### \"Smart\" Updates\nThe liveblog uses smart updates, making it easy for your readers to enjoy your liveblog without being overwhelmed with updates. If the reader's browser is at the top of the post, new posts will automatically appear, highlighted in yellow.\n\n![Screenshot of smart updates](http://vip.files.wordpress.com/2013/01/screen-shot-2013-01-18-at-11-32-38-am.png)\n\nHowever, if your reader has scrolled down the post to catch up on previous updates, liveblog will wait to update with new posts. Instead, a notification bar will appear at the top of the screen. When the reader clicks on the bar, the new updates will resume loading at the top of the page.\n\n![Screenshot of notification](http://vip.files.wordpress.com/2013/01/screen-shot-2013-01-18-at-11-30-51-am.png)\n\nPost times are also now relative, which means it will display as “2 minutes ago,” with the time updating every minute.\n\n#### Overriding default templates\nTemplates used by the plugin can be found in the \u003ca href=\"https://github.com/Automattic/liveblog/tree/master/templates\"\u003e/templates/ directory\u003c/a\u003e of the plugin.\n\nYou can edit these files in an upgrade-safe way using overrides. Copy the files you want to change into a directory named /liveblog within the root of your theme, keeping the same filename.\n\nEg: In order to override a single entry template copy \u003ca href=\"https://github.com/Automattic/liveblog/blob/master/templates/liveblog-single-entry.php\"\u003etemplates/liveblog-single-entry.php\u003c/a\u003e to yourtheme/liveblog/liveblog-single-entry.php\n\nThe copied file will now override the Liveblog default template file.\n\nCheck out the [related code on GitHub.](https://github.com/Automattic/liveblog/blob/master/liveblog.php#L875,L896)\n\n#### Custom location for Liveblog templates\nIn case the /liveblog directory in the root of your theme is not what would suit your needs, you can take advantage of the `liveblog_template_path` filter and pass in a custom absolute path without trailing slash which would then be used for template look-up.\n\n[Check out the related code.](https://github.com/Automattic/liveblog/blob/master/liveblog.php#L262,L268)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fautomattic%2Fliveblog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fautomattic%2Fliveblog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fautomattic%2Fliveblog/lists"}