mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
ENHANCEMENT [file_link id=n] shortcode support for file links in HtmlEditorField
This commit is contained in:
parent
586ca7374f
commit
898c8f5497
@ -49,6 +49,8 @@ Object::useCustomClass('Datetime', 'SS_Datetime', true);
|
|||||||
*/
|
*/
|
||||||
define('MCE_ROOT', 'sapphire/thirdparty/tinymce/');
|
define('MCE_ROOT', 'sapphire/thirdparty/tinymce/');
|
||||||
|
|
||||||
|
ShortcodeParser::get('default')->register('file_link', array('File', 'link_shortcode_handler'));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The secret key that needs to be sent along with pings to /Email_BounceHandler
|
* The secret key that needs to be sent along with pings to /Email_BounceHandler
|
||||||
*
|
*
|
||||||
|
@ -138,6 +138,43 @@ class File extends DataObject {
|
|||||||
*/
|
*/
|
||||||
protected static $cache_file_fields = null;
|
protected static $cache_file_fields = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace "[file_link id=n]" shortcode with an anchor tag or link to the file.
|
||||||
|
* @param $arguments array Arguments to the shortcode
|
||||||
|
* @param $content string Content of the returned link (optional)
|
||||||
|
* @param $parser object Specify a parser to parse the content (see {@link ShortCodeParser})
|
||||||
|
* @return string anchor HTML tag if content argument given, otherwise file path link
|
||||||
|
*/
|
||||||
|
public static function link_shortcode_handler($arguments, $content = null, $parser = null) {
|
||||||
|
if(!isset($arguments['id']) || !is_numeric($arguments['id'])) return;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!($record = DataObject::get_by_id('File', $arguments['id'])) // Get the file by ID.
|
||||||
|
&& !($record = DataObject::get_one('ErrorPage', '"ErrorCode" = \'404\'')) // Link to 404 page directly.
|
||||||
|
) {
|
||||||
|
return; // There were no suitable matches at all.
|
||||||
|
}
|
||||||
|
|
||||||
|
// build the HTML tag
|
||||||
|
if($content) {
|
||||||
|
// build some useful meta-data (file type and size) as data attributes
|
||||||
|
$attrs = ' ';
|
||||||
|
if($record instanceof File) {
|
||||||
|
foreach(array(
|
||||||
|
'class' => 'file',
|
||||||
|
'data-type' => $record->getExtension(),
|
||||||
|
'data-size' => $record->getSize()
|
||||||
|
) as $name => $value) {
|
||||||
|
$attrs .= sprintf('%s="%s" ', $name, $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprintf('<a href="%s"%s>%s</a>', $record->Link(), rtrim($attrs), $parser->parse($content));
|
||||||
|
} else {
|
||||||
|
return $record->Link();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a File object by the given filename.
|
* Find a File object by the given filename.
|
||||||
*
|
*
|
||||||
@ -167,7 +204,7 @@ class File extends DataObject {
|
|||||||
return Director::baseURL() . $this->RelativeLink();
|
return Director::baseURL() . $this->RelativeLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
function RelativeLink(){
|
function RelativeLink() {
|
||||||
return $this->Filename;
|
return $this->Filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,7 +307,7 @@ class HtmlEditorField_Toolbar extends RequestHandler {
|
|||||||
$siteTree,
|
$siteTree,
|
||||||
new TextField('external', _t('HtmlEditorField.URL', 'URL'), 'http://'),
|
new TextField('external', _t('HtmlEditorField.URL', 'URL'), 'http://'),
|
||||||
new EmailField('email', _t('HtmlEditorField.EMAIL', 'Email address')),
|
new EmailField('email', _t('HtmlEditorField.EMAIL', 'Email address')),
|
||||||
new TreeDropdownField('file', _t('HtmlEditorField.FILE', 'File'), 'File', 'Filename', 'Title', true),
|
new TreeDropdownField('file', _t('HtmlEditorField.FILE', 'File'), 'File', 'ID', 'Title', true),
|
||||||
new TextField('Anchor', _t('HtmlEditorField.ANCHORVALUE', 'Anchor')),
|
new TextField('Anchor', _t('HtmlEditorField.ANCHORVALUE', 'Anchor')),
|
||||||
new TextField('Description', _t('HtmlEditorField.LINKDESCR', 'Link description')),
|
new TextField('Description', _t('HtmlEditorField.LINKDESCR', 'Link description')),
|
||||||
new CheckboxField('TargetBlank', _t('HtmlEditorField.LINKOPENNEWWIN', 'Open link in a new window?')),
|
new CheckboxField('TargetBlank', _t('HtmlEditorField.LINKOPENNEWWIN', 'Open link in a new window?')),
|
||||||
|
@ -379,7 +379,7 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'file':
|
case 'file':
|
||||||
href = this.find(':input[name=file]').val();
|
href = '[file_link id=' + this.find(':input[name=file]').val() + ']';
|
||||||
target = '_blank';
|
target = '_blank';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -532,7 +532,7 @@ ss.editorWrappers['default'] = ss.editorWrappers.tinyMCE;
|
|||||||
email: RegExp.$1,
|
email: RegExp.$1,
|
||||||
Description: title
|
Description: title
|
||||||
};
|
};
|
||||||
} else if(href.match(/^(assets\/.*)$/)) {
|
} else if(href.match(/^(assets\/.*)$/) || href.match(/^\[file_link\s*(?:%20)?id=([0-9]+)\]?(#.*)?$/)) {
|
||||||
return {
|
return {
|
||||||
LinkType: 'file',
|
LinkType: 'file',
|
||||||
file: RegExp.$1,
|
file: RegExp.$1,
|
||||||
|
@ -9,6 +9,38 @@ class FileTest extends SapphireTest {
|
|||||||
|
|
||||||
protected $extraDataObjects = array('FileTest_MyCustomFile');
|
protected $extraDataObjects = array('FileTest_MyCustomFile');
|
||||||
|
|
||||||
|
public function testLinkShortcodeHandler() {
|
||||||
|
$testFile = $this->objFromFixture('File', 'asdf');
|
||||||
|
$errorPage = $this->objFromFixture('ErrorPage', '404');
|
||||||
|
|
||||||
|
$parser = new ShortcodeParser();
|
||||||
|
$parser->register('file_link', array('File', 'link_shortcode_handler'));
|
||||||
|
|
||||||
|
$fileShortcode = sprintf('[file_link id=%d]', $testFile->ID);
|
||||||
|
$fileEnclosed = sprintf('[file_link id=%d]Example Content[/file_link]', $testFile->ID);
|
||||||
|
|
||||||
|
$fileShortcodeExpected = $testFile->Link();
|
||||||
|
$fileEnclosedExpected = sprintf('<a href="%s" class="file" data-type="txt" data-size="977 KB">Example Content</a>', $testFile->Link());
|
||||||
|
|
||||||
|
$this->assertEquals($fileShortcodeExpected, $parser->parse($fileShortcode), 'Test that simple linking works.');
|
||||||
|
$this->assertEquals($fileEnclosedExpected, $parser->parse($fileEnclosed), 'Test enclosed content is linked.');
|
||||||
|
|
||||||
|
$testFile->delete();
|
||||||
|
|
||||||
|
$fileShortcode = '[file_link id="-1"]';
|
||||||
|
$fileEnclosed = '[file_link id="-1"]Example Content[/file_link]';
|
||||||
|
|
||||||
|
$fileShortcodeExpected = $errorPage->Link();
|
||||||
|
$fileEnclosedExpected = sprintf('<a href="%s">Example Content</a>', $errorPage->Link());
|
||||||
|
|
||||||
|
$this->assertEquals($fileShortcodeExpected, $parser->parse($fileShortcode), 'Test link to 404 page if no suitable matches.');
|
||||||
|
$this->assertEquals($fileEnclosedExpected, $parser->parse($fileEnclosed));
|
||||||
|
|
||||||
|
$this->assertEquals('', $parser->parse('[file_link]'), 'Test that invalid ID attributes are not parsed.');
|
||||||
|
$this->assertEquals('', $parser->parse('[file_link id="text"]'));
|
||||||
|
$this->assertEquals('', $parser->parse('[file_link]Example Content[/file_link]'));
|
||||||
|
}
|
||||||
|
|
||||||
function testCreateWithFilenameWithSubfolder() {
|
function testCreateWithFilenameWithSubfolder() {
|
||||||
// Note: We can't use fixtures/setUp() for this, as we want to create the db record manually.
|
// Note: We can't use fixtures/setUp() for this, as we want to create the db record manually.
|
||||||
// Creating the folder is necessary to avoid having "Filename" overwritten by setName()/setRelativePath(),
|
// Creating the folder is necessary to avoid having "Filename" overwritten by setName()/setRelativePath(),
|
||||||
|
@ -28,3 +28,7 @@ File:
|
|||||||
Filename: assets/FileTest-folder1/File1.txt
|
Filename: assets/FileTest-folder1/File1.txt
|
||||||
Name: File1.txt
|
Name: File1.txt
|
||||||
ParentID: =>Folder.folder1
|
ParentID: =>Folder.folder1
|
||||||
|
ErrorPage:
|
||||||
|
404:
|
||||||
|
Title: Page not Found
|
||||||
|
ErrorCode: 404
|
||||||
|
Loading…
Reference in New Issue
Block a user