├── .editorconfig ├── .gitignore ├── .travis.yml ├── Gruntfile.js ├── README.md ├── assets └── js │ └── image-shortcake-admin.js ├── bin └── install-wp-tests.sh ├── composer.json ├── image-shortcake.php ├── inc ├── class-img-shortcode-data-migration.php ├── class-img-shortcode.php └── class-wp-cli-img-shortcode-command.php ├── languages ├── image-shortcake-ru_RU.mo ├── image-shortcake-ru_RU.po └── image-shortcake.pot ├── package.json ├── phpcs.ruleset.xml ├── phpunit.xml ├── readme.txt ├── screenshot-1.png ├── screenshot-2.png └── tests ├── bootstrap.php ├── data ├── fusion_image_placeholder_16x9_h2000.png └── gin_joints.wav ├── test-img-shortcode-data-migration.php └── test-img-shortcode.php /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # editorconfig.org 3 | 4 | # WordPress Coding Standards 5 | # http://make.wordpress.org/core/handbook/coding-standards/ 6 | 7 | root = true 8 | 9 | [*] 10 | charset = utf-8 11 | end_of_line = lf 12 | insert_final_newline = true 13 | trim_trailing_whitespace = true 14 | indent_style = tab 15 | indent_size = 4 16 | 17 | [readme.txt,*.md,*.markdown] 18 | trim_trailing_whitespace = false 19 | 20 | [js-tests/**/*.js] 21 | indent_style = space 22 | indent_size = 2 23 | 24 | [*.json] 25 | indent_style = space 26 | indent_size = 2 27 | 28 | [*.txt,wp-config-sample.php] 29 | end_of_line = crlf 30 | 31 | [.scss-lint.yml] 32 | indent_style = space 33 | indent_size = 2 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .svn 2 | /node_modules 3 | /vendor 4 | .DS_Store 5 | .sass-cache 6 | composer.lock 7 | _SpecRunner.html 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | 3 | language: php 4 | 5 | matrix: 6 | include: 7 | - php: 5.6 8 | env: WP_VERSION=latest WP_MULTISITE=1 9 | - php: 7.1 10 | env: WP_VERSION=latest WP_MULTISITE=0 11 | 12 | cache: 13 | directories: 14 | - vendor 15 | - node_modules 16 | 17 | before_script: 18 | - composer install 19 | - npm install 20 | - bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION 21 | 22 | script: 23 | - grunt phpcs 24 | - phpunit 25 | 26 | branches: 27 | only: 28 | - master 29 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function( grunt ) { 2 | 3 | 'use strict'; 4 | var banner = '/**\n * <%= pkg.homepage %>\n * Copyright (c) <%= grunt.template.today("yyyy") %>\n * This file is generated automatically. Do not edit.\n */\n'; 5 | // Project configuration 6 | grunt.initConfig( { 7 | 8 | pkg: grunt.file.readJSON( 'package.json' ), 9 | 10 | addtextdomain: { 11 | options: { 12 | textdomain: 'image-shortcake', 13 | }, 14 | target: { 15 | files: { 16 | src: [ '*.php', '**/*.php', '!node_modules/**', '!php-tests/**', '!bin/**' ] 17 | } 18 | } 19 | }, 20 | 21 | wp_readme_to_markdown: { 22 | your_target: { 23 | files: { 24 | 'README.md': 'readme.txt' 25 | } 26 | }, 27 | }, 28 | 29 | phpcs: { 30 | plugin: { 31 | src: './' 32 | }, 33 | options: { 34 | bin: "vendor/bin/phpcs --extensions=php --ignore=\"*/vendor/*,*/node_modules/*\"", 35 | standard: "phpcs.ruleset.xml" 36 | } 37 | }, 38 | 39 | watch: { 40 | dev: { 41 | files: [ '**/*.php' ], 42 | tasks: [ 'phpcs' ] 43 | } 44 | }, 45 | 46 | makepot: { 47 | target: { 48 | options: { 49 | domainPath: '/languages', 50 | mainFile: 'image-shortcake.php', 51 | potFilename: 'image-shortcake.pot', 52 | potHeaders: { 53 | poedit: true, 54 | 'x-poedit-keywordslist': true 55 | }, 56 | type: 'wp-plugin', 57 | updateTimestamp: true 58 | } 59 | } 60 | }, 61 | } ); 62 | 63 | grunt.loadNpmTasks( 'grunt-wp-i18n' ); 64 | grunt.loadNpmTasks( 'grunt-wp-readme-to-markdown' ); 65 | grunt.loadNpmTasks( 'grunt-phpcs' ); 66 | grunt.loadNpmTasks( 'grunt-contrib-watch' ); 67 | grunt.registerTask( 'i18n', ['addtextdomain', 'makepot'] ); 68 | grunt.registerTask( 'readme', ['wp_readme_to_markdown']); 69 | 70 | 71 | grunt.util.linefeed = '\n'; 72 | 73 | }; 74 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Image Shortcake # 2 | **Contributors:** fusionengineering, goldenapples, danielbachhuber 3 | **Tags:** shortcodes, images 4 | **Requires at least:** 3.0.1 5 | **Tested up to:** 4.3 6 | **Stable tag:** 0.1.0 7 | **License:** GPLv2 or later 8 | **License URI:** http://www.gnu.org/licenses/gpl-2.0.html 9 | 10 | Image Shortcake adds a shortcode for images, so that themes can template and filter images displayed in posts. Although it can be used standalone, it is designed to work with the UI provided by the [Shortcake (Shortcode UI)](https://github.com/fusioneng/Shortcake) plugin. 11 | 12 | ## Description ## 13 | 14 | When images are inserted into posts from the media library or media uploader, only the html of the `` tag and the link around it (if any) are preserved. This means that themes which want to change the way images are marked up in content don't have an easy way of doing this. 15 | 16 | Image Shortcake is an attempt to solve this problem, by saving images in post content as _shortcodes_ rather than HTML. The output of shortcodes can be easily filtered in themes, plugins and templates, and since the original attachment data is preseved as attributes on the shortcode, it becomes much easier for modify the way images are marked up in themes. 17 | 18 | For best results, use this with the [Shortcake (Shortcode UI)](https://github.com/fusioneng/Shortcake) plugin. Shortcake offers an easy to use interface to manage shortcodes in post content. 19 | 20 | What could you use this for? Well, at [Fusion](http://fusion.net) we use this shortcode for: 21 | 22 | * **Responsive Images**. By filtering the output of the `[img]` shortcode image tag, we're able to insert the `srcset` attribute, so that all of the images on our site are served responsively to browsers that support that. 23 | 24 | * **Inline sharing buttons**. We've added share links to each of the images on our site. Because these are inserted through a filter on a shortcode and not in the post content, it's easy to modify them on the fly. And having this logic in template files rather in on-page javascript that runs after page load makes it quicker for users. 25 | 26 | * **Photo credits**. We've added "credit" as an image meta field, and we use a filter on 'img_shortcode_output_after_linkify' to display it on all images. 27 | 28 | See the [Installation](#Installation) section for more ideas and tips for custom image templates. [Get involved with the project](https://github.com/fusioneng/image-shortcake) on Github. 29 | 30 | ## Installation ## 31 | 32 | ### Customizing Output ### 33 | 34 | The whole point of using shortcodes rather than HTML tags for images is that you can customize the markup of images in your theme. This plugin offers three primary hooks to modify the output: 35 | 36 | * `img_shortcode_output_img_tag`: Filters the output of the tag before wrapping it in link or caption 37 | * `img_shortcode_output_after_linkify`: Filters the output of the tag after wrapping in link 38 | * `img_shortcode_output_after_captionify`: Filters the output of the tag after wrapping in link and attaching caption 39 | 40 | You can, of course, disregard the markup generated by this plugin altogether and use a template part for images if you want. This example adds EXIF data below all images containing those fields, in all post content: 41 | 42 | in the theme's `functions.php`: 43 | 44 | ``` 45 | add_filter( 'img_shortcode_output_img_tag', 'load_image_template', 10, 2 ); 46 | 47 | function load_image_template( $_, $attributes ) { 48 | ob_start(); 49 | get_template_part( 'inline-image' ); 50 | return ob_get_clean(); 51 | } 52 | ``` 53 | 54 | in a template file called `inline-image.php`: 55 | 56 | ``` 57 | "$class $align attachment-$size", 72 | 'alt' => $alt, 73 | ) 74 | ); 75 | 76 | if ( is_array( $exif_data ) ) { 77 | echo ''; 82 | } 83 | ``` 84 | 85 | 86 | ### Data Migration ### 87 | 88 | The plugin comes with two [WP-CLI](http://wp-cli.org) commands to migrate images in your existing content into the `[img]` shortcode format used by 89 | **this plugin. _Note:** if it isn't clear, this is an early release -- use at your own risk, and make sure you've backed up your posts before migrating!_ 90 | 91 | `wp image-shortcake migrate [--dry-run]` 92 | 93 | This command searches the post content of the posts specified in ``, and replaces any `` tags or `[caption]` shortcodes with `[img]` 94 | shortcodes. Currently it only catches images added through the media library; custom img tags will not be converted. 95 | 96 | If you add the `--dry-run` flag, no replacements will actually be performed, just a summary report of the changes which would have been made. 97 | 98 | `wp image-shortcake revert [--dry-run]` 99 | 100 | This command finds all `[img]` shortcodes in the content of any of the posts specified in ``, and replaces them with the markup that would be generated by those shortcodes. Note that this runs any filters in your theme, so that if you have filtered the output of the shortcodes at any output, those filters will be reflected in the coverted post content. 101 | 102 | ## Screenshots ## 103 | 104 | ### 1. This is the shortcode UI form as accessed from **Insert Media > Insert Post Element**. (Note that you can also insert images as usual, by inserting them in the Media Library - they will be transparently converted into shortcodes behind the scenes for you.) ### 105 | ![This is the shortcode UI form as accessed from **Insert Media > Insert Post Element**. (Note that you can also insert images as usual, by inserting them in the Media Library - they will be transparently converted into shortcodes behind the scenes for you.)](http://s.wordpress.org/extend/plugins/image-shortcake/screenshot-1.png) 106 | 107 | ### 2. Once inserted into a post, the image preview renders in the editor just as it normally would. The Shortcake plugin's edit/delete buttons are available to modify the shortcode through the provided UI. ### 108 | ![Once inserted into a post, the image preview renders in the editor just as it normally would. The Shortcake plugin's edit/delete buttons are available to modify the shortcode through the provided UI.](http://s.wordpress.org/extend/plugins/image-shortcake/screenshot-2.png) 109 | 110 | 111 | ## Changelog ## 112 | 113 | ### 0.1.0 (May 1, 2015) ### 114 | * Initial release 115 | -------------------------------------------------------------------------------- /assets/js/image-shortcake-admin.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Callback to manipulate the attachment details and two column template, onReady. 3 | */ 4 | function updateStringsForImageShortcake() { 5 | var attachmentDetailsTemplate = jQuery("#tmpl-attachment-details"); 6 | 7 | if ( 0 === attachmentDetailsTemplate.length ) { 8 | return; 9 | } 10 | 11 | var attachmentDetailsHtml = attachmentDetailsTemplate.html(), 12 | attachmentDetailsTwoColumnTemplate = jQuery("#tmpl-attachment-details-two-column"), 13 | attachmentDetailsTwoColumnHtml = attachmentDetailsTwoColumnTemplate.html(), 14 | 15 | customCaption = '<# if( "image" === data.type ) { #>' + 16 | '' + 17 | image_shortcake_strings.caption + 18 | '' + 19 | '<# } #>' + 20 | '' + 21 | '
' + 22 | image_shortcake_strings.warning + 23 | '.
' + 24 | ''; 25 | 26 | /** 27 | * Use string methods hack. 28 | */ 29 | var newHtml = attachmentDetailsHtml.replace(/(