├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .gitignore ├── LICENSE.md ├── README.md ├── bin ├── admin.php ├── client-core.php ├── compat-warnings.php ├── events-post-type.php ├── events │ ├── event.png │ ├── events-functions.css │ ├── jquery-ui-1.8.9.custom.css │ ├── jquery-ui-1.8.9.custom.min.js │ ├── jquery.ui.datepicker.js │ └── pubforce-admin.js ├── load-menu.php ├── permalinks.php └── profiles.php ├── contact ├── ContentHelpers.php ├── Html2Text.php ├── class-phpmailer.php ├── class-smtp.php └── contact-proc.php ├── footer.php ├── functions.php ├── header.php ├── index.php ├── jsonconfig.json ├── less ├── 600up.less ├── 720up.less ├── 992up.less ├── base.less ├── ie.less ├── login.less ├── mixins.less ├── normalize.less └── style.less ├── package.json ├── phpcs.xml ├── screenshot.png ├── sidebar.php ├── src ├── components │ ├── comments │ │ ├── form.js │ │ ├── index.js │ │ └── single.js │ ├── contact │ │ ├── form.js │ │ └── index.js │ ├── date │ │ └── index.js │ ├── event │ │ ├── form.js │ │ └── index.js │ ├── events │ │ ├── index.js │ │ ├── list.js │ │ └── single.js │ ├── home │ │ ├── index.js │ │ ├── slideshow.js │ │ └── widget.js │ ├── navigation │ │ ├── index.js │ │ └── sidebar.js │ ├── not-found │ │ └── index.js │ ├── pagination │ │ ├── archive.js │ │ └── comments.js │ ├── placeholder │ │ └── index.js │ ├── post │ │ ├── image.js │ │ ├── index.js │ │ ├── meta.js │ │ └── page.js │ ├── posts │ │ ├── index.js │ │ ├── list.js │ │ └── single.js │ ├── search │ │ ├── form.js │ │ └── index.js │ ├── socials │ │ └── index.js │ ├── term │ │ ├── index.js │ │ └── list.js │ ├── user │ │ └── index.js │ └── users │ │ ├── index.js │ │ ├── list.js │ │ └── single.js ├── i18n │ ├── actions.js │ ├── index.js │ ├── intl-redux-provider.js │ ├── messages │ │ ├── en.js │ │ └── it.js │ └── reducer.js ├── index.js ├── reducer.js ├── store.js ├── structure.js └── utils │ ├── a11y.js │ ├── content-mixin.js │ ├── is-item-selected.js │ ├── react-body-class.js │ └── validate.js ├── style.css └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | // JSX, Flow 4 | "react", 5 | "es2015", 6 | "es2016", 7 | "es2017" 8 | ], 9 | "plugins": [ 10 | "add-module-exports", 11 | "react-hot-loader/babel", 12 | // class { handleClick = () => { } } 13 | "transform-class-properties", 14 | // @decorate classes, helpful with redux 15 | "transform-decorators-legacy", 16 | "transform-export-extensions", 17 | // { ...todo, completed: true } 18 | "transform-object-rest-spread", 19 | ["transform-runtime", { 20 | "helpers": false, 21 | "polyfill": false, 22 | "regenerator": true 23 | }], 24 | "syntax-jsx", 25 | "transform-react-jsx", 26 | "lodash" 27 | ], 28 | "env": { 29 | "test": { 30 | "plugins": [ 31 | "transform-react-display-name", 32 | // Adds __self attribute to JSX which React will use for some warnings 33 | "transform-react-jsx-self", 34 | // Adds component stack to warning messages 35 | "transform-react-jsx-source" 36 | ] 37 | }, 38 | "development": { 39 | "plugins": [ 40 | "transform-react-display-name", 41 | // Adds __self attribute to JSX which React will use for some warnings 42 | "transform-react-jsx-self", 43 | // Adds component stack to warning messages 44 | "transform-react-jsx-source" 45 | ] 46 | }, 47 | "production": { 48 | 49 | }, 50 | "node": { 51 | "plugins": [ 52 | [ 53 | "babel-plugin-transform-require-ignore", 54 | { 55 | "extensions": [".less", ".scss"] 56 | } 57 | ] 58 | ] 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | experimentalDecorators = true -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | /build 4 | /bin 5 | /contact -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "babel-eslint", 3 | "extends": "airbnb", 4 | "plugins": [ 5 | "react" 6 | ], 7 | "env": { 8 | "browser": true, 9 | "node": true, 10 | "jasmine": true 11 | }, 12 | "rules": { 13 | "array-callback-return": 0, 14 | "arrow-parens": 0, 15 | "class-methods-use-this": 0, 16 | "import/extensions": 0, 17 | "import/first": 0, 18 | "import/imports-first": 0, 19 | "import/no-extraneous-dependencies": 0, 20 | "import/no-unresolved": 0, 21 | "jsx-a11y/href-no-hash": 0, 22 | "no-unused-vars": 0, 23 | "no-trailing-spaces": 0, 24 | "comma-dangle": 0, 25 | "radix": 0, 26 | "react/jsx-filename-extension": 0, 27 | "react/no-unused-prop-types": 0, 28 | "react/prop-types": 0, 29 | "max-len": 0, 30 | "semi": 0 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | 6 | # testing 7 | coverage 8 | 9 | # production 10 | build 11 | release 12 | 13 | # misc 14 | .DS_Store 15 | .env 16 | npm-debug.log* 17 | .vscode 18 | sass-cache -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Ryan Vannin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-theme 2 | Production ready Wordpress theme built with React, Redux, Redux-Thunk, Intl, React Router v4, etc... and packaged by Webpack 2. Enjoy! http://www.agire.ch 3 | 4 | Inspired by https://github.com/ryelle, although tweaks and (a lot of) changes had to be made :) -------------------------------------------------------------------------------- /bin/admin.php: -------------------------------------------------------------------------------- 1 | get_item_quantity(7); // specify number of items 38 | $items = $feed->get_items(0, $limit); // create an array of items 39 | } 40 | if ($limit == 0) echo '
The RSS Feed is either empty or unavailable.
'; // fallback message 41 | else foreach ($items as $item) : ?> 42 | 43 |

44 | 45 | get_title(); ?> 46 | 47 |

48 |

49 | get_description(), 0, 200); ?> 50 |

51 | '; 77 | //echo ''; 78 | //echo ''; 79 | //echo ''; 80 | } 81 | add_action('login_head', 'plastical_custom_login'); 82 | } 83 | 84 | // calling your own login css so you can style it 85 | function plastical_login_css() { 86 | /* i couldn't get wp_enqueue_style to work :( */ 87 | //echo ''; 88 | } 89 | 90 | // changing the logo link from wordpress.org to your site 91 | function plastical_login_url() { echo bloginfo('url'); } 92 | 93 | // changing the alt text on the logo to show your site name 94 | function plastical_login_title() { echo get_option('blogname'); } 95 | 96 | // calling it only on the login page 97 | add_action('login_head', 'plastical_login_css'); 98 | add_filter('login_headerurl', 'plastical_login_url'); 99 | add_filter('login_headertitle', 'plastical_login_title'); 100 | 101 | 102 | /************* CUSTOMIZE ADMIN *******************/ 103 | 104 | /* 105 | I don't really reccomend editing the admin too much 106 | as things may get funky if Wordpress updates. Here 107 | are a few funtions which you can choose to use if 108 | you like. 109 | */ 110 | 111 | // Custom Backend Footer 112 | function plastical_custom_admin_footer() { 113 | echo 'Made by Plastical.'; 114 | } 115 | 116 | // adding it to the admin area 117 | add_filter('admin_footer_text', 'plastical_custom_admin_footer'); 118 | 119 | /* WP SEO */ 120 | # global 121 | global $wpseo_admin; 122 | # this removes when editing 'YOUR PROFILE' 123 | remove_action( 'show_user_profile', array( $wpseo_admin, 'user_profile' ) ); 124 | # this removes when editing 'EDIT PROFILE' 125 | remove_action( 'edit_user_profile', array( $wpseo_admin, 'user_profile' ) ); 126 | 127 | // Add the posts and pages columns filter. They can both use the same function. 128 | add_filter('manage_posts_columns', 'add_post_thumbnail_column', 5); 129 | add_filter('manage_pages_columns', 'add_post_thumbnail_column', 5); 130 | 131 | // Add the column 132 | function add_post_thumbnail_column($cols){ 133 | $cols['post_thumb'] = __('Feat. image'); 134 | return $cols; 135 | } 136 | 137 | // Hook into the posts an pages column managing. Sharing function callback again. 138 | add_action('manage_posts_custom_column', 'display_post_thumbnail_column', 5, 2); 139 | add_action('manage_pages_custom_column', 'display_post_thumbnail_column', 5, 2); 140 | 141 | // Grab featured-thumbnail size post thumbnail and display it. 142 | function display_post_thumbnail_column($col, $id){ 143 | switch($col){ 144 | case 'post_thumb': 145 | if( function_exists('the_post_thumbnail') ) 146 | echo the_post_thumbnail( 'plastical-thumb-160' ); 147 | else 148 | echo 'Not supported in theme'; 149 | break; 150 | } 151 | } 152 | 153 | /** Hide Administrator From User List **/ 154 | function isa_pre_user_query($user_search) { 155 | $user = wp_get_current_user(); 156 | if (!current_user_can('administrator')) { // Is Not Administrator - Remove Administrator 157 | global $wpdb; 158 | 159 | $user_search->query_where = 160 | str_replace('WHERE 1=1', 161 | "WHERE 1=1 AND {$wpdb->users}.ID IN ( 162 | SELECT {$wpdb->usermeta}.user_id FROM $wpdb->usermeta 163 | WHERE {$wpdb->usermeta}.meta_key = '{$wpdb->prefix}capabilities' 164 | AND {$wpdb->usermeta}.meta_value NOT LIKE '%administrator%')", 165 | $user_search->query_where 166 | ); 167 | } 168 | } 169 | add_action('pre_user_query','isa_pre_user_query'); 170 | 171 | // hide menus to user subscribers 172 | function hide_menus () { 173 | global $menu; 174 | 175 | if(current_user_can('subscriber')): 176 | $restricted = array(__('Posts'),__('Media'), __('Tools'), __('Comments')); 177 | end ($menu); 178 | while (prev($menu)){ 179 | $value = explode(' ',$menu[key($menu)][0]); 180 | if(in_array($value[0] != NULL?$value[0]:"" , $restricted)){unset($menu[key($menu)]);} 181 | } 182 | endif; 183 | } 184 | add_action('admin_menu', 'hide_menus'); 185 | 186 | function allow_subscriber_uploads() { 187 | $subscriber = get_role('subscriber'); 188 | $subscriber->add_cap('upload_files'); 189 | } 190 | 191 | if ( current_user_can('contributor') && !current_user_can('upload_files') ) 192 | add_action('admin_init', 'allow_contributor_uploads'); 193 | 194 | function allow_contributor_uploads() { 195 | $contributor = get_role('contributor'); 196 | $contributor->add_cap('upload_files'); 197 | } 198 | 199 | function remove_admin_bar_links() { 200 | if(current_user_can('subscriber')) { 201 | global $wp_admin_bar; 202 | $wp_admin_bar->remove_menu('wp-logo'); // Remove the WordPress logo 203 | $wp_admin_bar->remove_menu('about'); // Remove the about WordPress link 204 | $wp_admin_bar->remove_menu('wporg'); // Remove the WordPress.org link 205 | $wp_admin_bar->remove_menu('documentation'); // Remove the WordPress documentation link 206 | $wp_admin_bar->remove_menu('support-forums'); // Remove the support forums link 207 | $wp_admin_bar->remove_menu('feedback'); // Remove the feedback link 208 | //$wp_admin_bar->remove_menu('site-name'); // Remove the site name menu 209 | //$wp_admin_bar->remove_menu('view-site'); // Remove the view site link 210 | $wp_admin_bar->remove_menu('updates'); // Remove the updates link 211 | $wp_admin_bar->remove_menu('comments'); // Remove the comments link 212 | $wp_admin_bar->remove_menu('new-content'); // Remove the content link 213 | $wp_admin_bar->remove_menu('w3tc'); // If you use w3 total cache remove the performance link 214 | $wp_admin_bar->remove_menu('wpseo-dashboard'); // If you use w3 total cache remove the performance link 215 | //$wp_admin_bar->remove_menu('my-account'); // Remove the user details tab 216 | } 217 | } 218 | add_action( 'wp_before_admin_bar_render', 'remove_admin_bar_links' ); 219 | 220 | if (!current_user_can(‘manage_options’)) { add_filter(‘show_admin_bar’, ‘__return_false’); } 221 | 222 | function hide_yoastseo() { 223 | if ( !current_user_can( 'administrator' ) ) : 224 | remove_action('admin_bar_menu', 'wpseo_admin_bar_menu',95); 225 | remove_menu_page('wpseo_dashboard'); 226 | endif; 227 | } 228 | add_action( 'admin_init', 'hide_yoastseo'); 229 | 230 | if ( current_user_can('subscriber') && !current_user_can('upload_files') ) 231 | add_action('admin_init', 'allow_subscriber_uploads'); 232 | 233 | -------------------------------------------------------------------------------- /bin/client-core.php: -------------------------------------------------------------------------------- 1 | 'get_page_meta_welcome_txt', 61 | 'update_callback' => 'null', 62 | 'schema' => 'null', 63 | ]); 64 | } 65 | add_action('rest_api_init', 'register_pages_meta_rest'); 66 | 67 | /* custom excerpt */ 68 | function get_client_excerpt($length){ 69 | $excerpt = get_the_content(); 70 | $excerpt = preg_replace(" (\[.*?\])",'',$excerpt); 71 | $excerpt = strip_shortcodes($excerpt); 72 | $excerpt = strip_tags($excerpt); 73 | $excerpt = substr($excerpt, 0, $length); 74 | $excerpt = substr($excerpt, 0, strripos($excerpt, " ")); 75 | $excerpt = trim(preg_replace( '/\s+/', ' ', $excerpt)); 76 | $excerpt = $excerpt.'...'; 77 | return $excerpt; 78 | } 79 | 80 | // Fixing the Read More in the Excerpts 81 | // This removes the annoying […] to a Read More link & add excerpt more with language detection 82 | 83 | function client_excerpt_more($more) { 84 | global $post; 85 | if(ICL_LANGUAGE_CODE == 'en') 86 | $more = 'More'; 87 | else if(ICL_LANGUAGE_CODE == 'de') 88 | $more = 'Mehr'; 89 | else if(ICL_LANGUAGE_CODE == 'fr') 90 | $more = 'Continuez'; 91 | else if(ICL_LANGUAGE_CODE == 'it') 92 | $more = 'Continua'; 93 | else 94 | $more = 'More'; 95 | // if there's no active WPLM active: $more = 'more'; 96 | return '...  

'; 97 | } 98 | add_filter('excerpt_more', 'client_excerpt_more'); 99 | 100 | // Language set up 101 | 102 | function client_set_language() { 103 | $languages = icl_get_languages('skip_missing=0&orderby=code'); 104 | echo '
'; 115 | } 116 | 117 | // WPML 118 | define('ICL_DONT_LOAD_NAVIGATION_CSS', true); 119 | define('ICL_DONT_LOAD_LANGUAGE_SELECTOR_CSS', true); 120 | define('ICL_DONT_LOAD_LANGUAGES_JS', true); 121 | 122 | function is_page_tree($pid) { // $pid = The ID of the page we're looking for pages underneath 123 | global $post; // load details about this page 124 | 125 | if (is_page($pid)) 126 | return true; // we're at the page or at a sub page 127 | 128 | $anc = get_post_ancestors($post->ID); 129 | foreach ($anc as $ancestor) { 130 | if(is_page() && $ancestor == $pid) { 131 | return true; 132 | } 133 | } 134 | 135 | return false; // we arn't at the page, and the page is not an ancestor 136 | } 137 | 138 | function is_post_tree( $cid ) { 139 | if(in_category( (int) $cid )) 140 | return true; 141 | 142 | //$children = get_categories(array( 'child_of' => $pid, 'hide_empty' => 0 )); 143 | //if (count($children) > 1) 144 | //return true; 145 | //return false; 146 | $category = get_category($cid); 147 | if ($category->category_parent > 0) 148 | return true; 149 | return false; 150 | } 151 | 152 | /****************** PLUGINS & EXTRA FEATURES **************************/ 153 | 154 | // Related Posts Function (call using client_related_posts(); ) 155 | function client_related_posts() { 156 | echo '