diff --git a/admin-style.css b/admin-style.css new file mode 100644 index 0000000..7ac7219 --- /dev/null +++ b/admin-style.css @@ -0,0 +1,5 @@ +.form_container { + margin-top: 1em; + border: 1px solid #c0c0c0; + padding: 10px 15px 25px 15px; +} \ No newline at end of file diff --git a/extended-toc.php b/extended-toc.php new file mode 100644 index 0000000..80cbb29 --- /dev/null +++ b/extended-toc.php @@ -0,0 +1,306 @@ +path = plugins_url( '', __FILE__ ); + $this->exclude_post_types = array( 'attachment', 'revision', 'nav_menu_item', 'safecss' ); + + // get options + $defaults = array( // default options + 'heading_text' => 'Contents', + 'start' => 3, + 'show_heading_text' => true, + 'auto_insert_post_types' => array('page', 'post'), + 'heading_levels' => array('1', '2', '3', '4', '5', '6'), + ); + $options = get_option( EXTENDED_TOC_ID, $defaults ); + $this->options = wp_parse_args( $options, $defaults ); + + add_action( 'plugins_loaded', array(&$this, 'plugins_loaded') ); + + if( is_admin() ) { + add_action('admin_init', array(&$this, 'admin_init')); + add_action('admin_menu', array(&$this, 'admin_menu')); + } + else { + /** Add the content filter and enqueue css **/ + add_filter( 'the_content', array(&$this, 'the_content'), 10 ); + add_action( 'wp_enqueue_scripts', array(&$this, 'wp_enqueue_scripts') ); + } + } + + public function __destruct() { + } + + public function admin_init() { + wp_register_style( EXTENDED_TOC_ID, $this->path . '/admin-style.css', array(), EXTENDED_TOC_VERSION ); + wp_enqueue_style(EXTENDED_TOC_ID); + } + + public function admin_menu() { + // Create menu tab + $page = add_submenu_page( 'plugins.php', EXTENDED_TOC_NAME, EXTENDED_TOC_NAME, 'manage_options', EXTENDED_TOC_ID, array(&$this, 'admin_options') ); + } + + private function save_admin_options() + { + global $post_id; + + // security check + if ( !wp_verify_nonce( @$_POST[EXTENDED_TOC_ID], plugin_basename(__FILE__) ) ) + return false; + + // require an administrator level to save + if ( !current_user_can( 'manage_options', $post_id ) ) + return false; + + $this->options = array_merge( + $this->options, + array( + 'heading_text' => stripslashes( trim($_POST['heading_text']) ), + 'auto_insert_post_types' => @(array)$_POST['auto_insert_post_types'], + ) + ); + + // update_option will return false if no changes were made + update_option( EXTENDED_TOC_ID, $this->options ); + + return true; + } + + public function admin_options() { + if( isset($_GET['update']) ) { + if( $this->save_admin_options() ) + $msg = '

' . __('Options saved.', EXTENDED_TOC_ID) . '

'; + else + $msg = '

' . __('Save failed.', EXTENDED_TOC_ID) . '

'; + } +?> +
+
+
+
+ +

+ + + +
+ + +
+ + + + + + + + + + + + +
+ + exclude_post_types) ): ?> + options['auto_insert_post_types'])?' checked="checked"':''?> /> +
+ + +
+
+ +

" name="submit" />

+
+
+path . '/style.css', array(), POWER_TOC_VERSION); + wp_enqueue_style(EXTENDED_TOC_ID); + } + + public function plugins_loaded() { + load_plugin_textdomain( EXTENDED_TOC_ID, false, dirname(plugin_basename(__FILE__)) . '/locale/' ); + } + + public function the_content($content) { + global $post; + + if ( is_feed() ) + return $content; + + if( !in_array(get_post_type($post), $this->options['auto_insert_post_types'])|| is_search() || is_archive() || is_front_page() ) + return $content; + + /** Extract the content, and extract the part content if was used **/ + $this->content = $content; + $this->extract_full_post_content(); + + $toc_content = "
"; + + if( $this->options['show_heading_text'] == true ) + $toc_content .= "

" . $this->options["heading_text"] . "

"; + + $toc_content .= "
"; + + if( $this->totalHeadings >= $this->options['start'] ) + return $toc_content . $this->content; + else + return $this->content; + } + + /** Extract the full unshortened content from the post **/ + private function extract_full_post_content() { + global $post; + $this->fullcontent = $post->post_content; + $this->ID = $post->ID; + } + + private function extract_toc() { + /** check within the full content how many pages exists */ + $this->extract_pages(); + + $headers = ""; + + /** Extract headings from every pages */ + for( $pagenum = 1; $pagenum <= count($this->pages); $pagenum++ ) { + $headers .= $this->exctract_headings($pagenum); + } + + return $headers; + } + + private function extract_pages() { + /** Split the content by "nextpage"-tags if some exists */ + $this->pages = preg_split("//msuU", $this->fullcontent); + } + + private function exctract_headings($pagenum) { + /** find all header tags within the page **/ + preg_match_all('/(]*>).*<\/h\2>/msuU', $this->pages[$pagenum-1], $matches, PREG_SET_ORDER); + + /** Check the headings that are desired */ + if ( count($this->options['heading_levels']) != 6 ) { + $new_matches = array(); + for ($i = 0; $i < count($matches); $i++) { + if ( in_array($matches[$i][2], $this->options['heading_levels']) ) + $new_matches[] = $matches[$i]; + } + $matches = $new_matches; + } + + $items = ""; + + for( $i = 0; $i < count($matches); $i++ ) { + /** get anchor and add to find and replace arrays **/ + $anchor = $this->url_encode_anchor($matches[$i][0]); + $find[] = $matches[$i][0]; + $this->content = str_replace( + array( + $matches[$i][1], // start of heading + '' // end of heading + ), + array( + $matches[$i][1] . '', + '' + ), + $this->content + ); + + /** build html */ + $items .= '
  • '; + $items .= ''; + $items .= "" . $this->counter++ . " "; + $items .= strip_tags($matches[$i][0]) . ''; + $items .= '
  • '; + + $this->totalHeadings++; + } + + return $items; + } + + private function url_encode_anchor($anchor) + { + $return = false; + + if(!empty($anchor) ) { + /** Remove tags */ + $return = trim( strip_tags($anchor) ); + + /** remove & */ + $return = str_replace( '&', '', $return ); + + /** remove all unknown chars **/ + $return = preg_replace("/[^0-9a-zA-Z \-_]+/", "", $return); + + /** Remove backspace etc */ + $return = preg_replace("/[\s]+/", "-", $return); + + /** If we now start or end with a - or _ remove it */ + $return = preg_replace("/^[-_]/", "", $return); + $return = preg_replace("/[-_]$/", "", $return); + } + + return $return; + } + } +} + +/** Initialise the class */ +$tocPlugin = new ExToC(); + +?> \ No newline at end of file diff --git a/locale/extended_toc-de_DE.mo b/locale/extended_toc-de_DE.mo new file mode 100644 index 0000000..f8b9327 Binary files /dev/null and b/locale/extended_toc-de_DE.mo differ diff --git a/locale/extended_toc-de_DE.po b/locale/extended_toc-de_DE.po new file mode 100644 index 0000000..a105944 --- /dev/null +++ b/locale/extended_toc-de_DE.po @@ -0,0 +1,52 @@ +msgid "" +msgstr "" +"Project-Id-Version: Extended-Toc\n" +"POT-Creation-Date: 2013-06-12 12:49+0100\n" +"PO-Revision-Date: 2013-06-12 12:50+0100\n" +"Last-Translator: HappyBooking UG \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.5.5\n" +"X-Poedit-KeywordsList: _;gettext;gettext_noop;__\n" +"X-Poedit-Basepath: .\n" +"X-Poedit-SourceCharset: UTF-8\n" +"X-Poedit-SearchPath-0: D:\\1 - Aktuelle Projekte\\0 - happybooking\\projekte" +"\\wordpress\n" + +#: D:\1 - Aktuelle Projekte\0 +#: happybooking\projekte\wordpress/plugins/extended-toc/extended-toc.php:111 +msgid "Options saved." +msgstr "Konfiguration wurde gespeichert." + +#: D:\1 - Aktuelle Projekte\0 +#: happybooking\projekte\wordpress/plugins/extended-toc/extended-toc.php:113 +msgid "Save failed." +msgstr "Speichern fehlgeschlagen." + +#: D:\1 - Aktuelle Projekte\0 +#: happybooking\projekte\wordpress/plugins/extended-toc/extended-toc.php:121 +msgid "Extended Table of Contents" +msgstr "Extended Table of Contents" + +#: D:\1 - Aktuelle Projekte\0 +#: happybooking\projekte\wordpress/plugins/extended-toc/extended-toc.php:132 +msgid "Heading text" +msgstr "Überschrift" + +#: D:\1 - Aktuelle Projekte\0 +#: happybooking\projekte\wordpress/plugins/extended-toc/extended-toc.php:137 +msgid "Add table of contents to following content types" +msgstr "Inhaltsverzeichnis (ToC) zu folgenden Inhalten einfügen" + +#: D:\1 - Aktuelle Projekte\0 +#: happybooking\projekte\wordpress/plugins/extended-toc/extended-toc.php:151 +msgid "Save Options" +msgstr "Konfiguration speichern" + +#~ msgid "Contents" +#~ msgstr "Inhaltsverzeichnis" + +#~ msgid "Table of contents" +#~ msgstr "Inhaltsverzeichnis" diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000..ca59b01 --- /dev/null +++ b/readme.txt @@ -0,0 +1,48 @@ +=== Plugin Name === +Contributors: happybooking +Donate link: http://www.happybooking.de/wordpress/plugins/extended-toc/donate +Tags: table of contents, indexes, toc, sitemap, cms, options, list, page listing, category listing +Requires at least: 3.0.1 +Tested up to: 3.5.2 +Stable tag: 0.6.4 +License: GPLv2 or later +License URI: http://www.gnu.org/licenses/gpl-2.0.html + +This plugin automatically generates and inserts a table of contents (ToC) to your pages and posts, based on tags h1-h6. It can deal with nextpage-tag. + +== Description == + +This plugin automatically generates and inserts a table of contents (ToC) to your pages and posts, based on tags h1-h6. Whenever the plugin discovers more than a certain amount of headings (default: 3) the ToC is inserted at the top of the page. This plugin also can handle posts that are divided into pages by the nextpage-wordpress-tag. Any feedback or suggestions are welcome. + += Available Languages = +* English +* German + +== Installation == + +The normal plugin install process applies, that is search for `Extended Table of Contents (with nextpage support)` from your plugin screen or via the manual method: + +1. Upload the `extended-toc` folder into your `/wp-content/plugins/` directory +1. Activate the plugin through the 'Plugins' menu in WordPress + +That's it! + +You can change the default settings and more under Plugins > Extended-ToC + +== Screenshots == + +1. The options panel found in Plugins > Extended-ToC + +== Frequently Asked Questions == + +If you have any questions or suggestions please contact us at any time: support@happybooking.de or http://www.happybooking.de/ + +== Changelog == + += 0.6.4 = +* Released: 1 July 2013 +* First release of the ToC supporting nextpage-tag + +== Upgrade Notice == + +Update folder with the latest files. All previous options will be saved. diff --git a/screenshot-1.png b/screenshot-1.png new file mode 100644 index 0000000..909c91e Binary files /dev/null and b/screenshot-1.png differ diff --git a/style.css b/style.css new file mode 100644 index 0000000..7514614 --- /dev/null +++ b/style.css @@ -0,0 +1,38 @@ +#toc-np-container { + background: #f9f9f9; + border: 1px solid #aaa; + padding: 1em; + margin-bottom: 1em; + width: auto; + display: table; +} + +#toc-np-container ul, #toc-np-container li { + margin: 0; + padding: 0 +} + +#toc-np-container ul { + margin-top: 1em; +} + +#toc-np-container li a { + text-decoration: none; +} + +#toc-np-container li a:hover { + text-decoration: underline; +} + +#toc-np-container #toc-np-title { + font-weight: bold; + margin: 0; + padding: 0; + text-align: center; +} + +.no-bullets, .no-bullets ul, .no-bullets li { + background: none; + list-style-type: none; + list-style: none; +} \ No newline at end of file