In Pier pictures can be added to a page by creating a PRFile, or by using a webserver and the IMG html tag. In the past I have avoided PRFiles because:
Previously there were discussions on the Seaside/Pier newsgroup about saving pictures in PRFiles causing image bloat. In several tests I've ran, this didn't seem to be a problem - additional space taken by edits or space cleared by garbage collection well outpaced space changes from adding PRFiles. It may be that a test running over several weeks would indicate an issue.
Unfortunately using S3 or a separate image server requires a fair amount of technical skill for the wiki users. While I was on vacation I only had access to a phone and lacked the keys to add pictures to my usual S3 bucket, so using PRFiles were useful in this situation.
Why - what is the error if upload is used? Saving files in Pier does not appear to impact the image size significantly, it also puts more stress on the Pier system. Unfortunately the images served by Pier do not have alt-text, so using an external web server (like Amazon S3) allows this through HTML. Pictures also take up more space than text.
How:
{{{html: <div style="clear: both">}}} *Picture_Name.png|embedded=true* {{{html: </div>}}}
The HTML causes text below the picture to be on a separate line, otherwise it looks like:
Sample text before an image, followed by an empty line.
Sample text after the picture, with an empty line above and below. Note that the text is wrapped around the image, including:
- lists
- but not block-elements like lines
- for the picture at the top of this page, if the div surrounding the img is removed the it is no longer right aligned
Picture_Name.png
link and choose PRFile for the type Questions:
upload
button? It is from MAFileUploadComponent>>#renderUploadOn:
File: Input is conflicting with concurrent modification
error popping up for the Toshiba laptop, but not for the one on the VC. Is there code cached somewhere? Could be Input is Conflicting with Concurrent Modification issues.usingNaming: aNameBlock toExternalUsing: writePictureFilesAndReturnUrls reportOn: aPathString "The report may have links to the PRFiles, so consider its location (having aStartPage as a parent prevents the file from being overwritten). User is responsible to select a aStartPageName that does not have private pictures under it" | reportPage files | self guessTodoFromPath: aPathString. (reportPage := PRPathLookup start: self kernel root path: aPathString) ifNotNil: [ reportPage contents: (String streamContents: [ :outputStream | | batchesOfFiles batchesOfFilesToLinks linksToFile pictureUrls errorLinks | batchesOfFilesToLinks := Dictionary new. files := (PRPathLookup start: self kernel root path: aStartPageName) enumerator everything select: [ :e | e isFile and: [ e isImage ] ]. files isEmpty ifTrue: [ self printReportHeaderOn: outputStream fields: 'No files found' ] ifFalse: [ self printReportHeaderOn: outputStream fields: '|!File|!Comment'. files do: [ :file | ((file title reject: [ :c | '-_.:' includes: c ]) isAllAlphaNumerics and: [ file title includes: $. ]) ifFalse: [ outputStream nextPutAll: '|*'; nextPutAll: file absolutePath; nextPutAll: '*|needs a title to be used for the file name, edit it to change the title.'; cr ] ifTrue: [ file hasChildren ifTrue: [ outputStream nextPutAll: '|*'; nextPutAll: file absolutePath; nextPutAll: '*|Has children, these should be removed first.'; cr ] ifFalse: [ file isRoot ifTrue: [ outputStream nextPutAll: '|*'; nextPutAll: file absolutePath; nextPutAll: '*|Should not be the root, removing this would be very bad.'; cr ] ifFalse: [ ([ [ (aNameBlock value: file) asUrl retrieveContents isEmpty ] on: ZnHttpUnsuccessful do: [ true ] ] on: ConnectionTimedOut do: [ true ]) ifFalse: [ outputStream nextPutAll: '|*'; nextPutAll: file absolutePath; nextPutAll: '*|Should be replaced with: '; nextPutAll: (aNameBlock value: file) asString; cr ] ifTrue: [ errorLinks := (linksToFile := self kernel root incomingReferences to: file) reject: [ :link | link isEmbedded ]. linksToFile size = 0 ifTrue: [ outputStream nextPutAll: '|*'; nextPutAll: file absolutePath; nextPutAll: '*|Has no links to it, need to wait until there is an embedded link to this.'; cr ] ifFalse: [ errorLinks isNotEmpty ifTrue: [ outputStream nextPutAll: '|*'; nextPutAll: file absolutePath; nextPutAll: '*|Has a non-embedded link on *'; nextPutAll: errorLinks anyOne owner absolutePath; nextPutAll: '* - this should be embedded.'; cr; cr ] ifFalse: [ batchesOfFilesToLinks at: file put: linksToFile ] ] ] ] ] ] ]. writePictureFilesAndReturnUrls value: (batchesOfFiles := batchesOfFilesToLinks keys). pictureUrls := batchesOfFiles collect: aNameBlock. batchesOfFiles with: pictureUrls do: [ :prFile :urlString | urlString isEmpty ifTrue: [ outputStream nextPutAll: '|*'; nextPutAll: prFile absolutePath; nextPutAll: '*|The URL is empty, unable to create the picture file.'; cr ] ifFalse: [ ([ urlString asUrl retrieveContents isEmpty ] on: ZnHttpUnsuccessful do: [ true ]) ifTrue: [ outputStream nextPutAll: '|*'; nextPutAll: prFile absolutePath; nextPutAll: '*|The URL is *'; nextPutAll: urlString; nextPutAll: '* - but has an error retrieving the contents.'; cr ] ifFalse: [ (batchesOfFilesToLinks at: prFile) do: [ :link | outputStream nextPutAll: '|*'; nextPutAll: link owner absolutePath; nextPutAll: '*|Update to have *'; nextPutAll: urlString asString; nextPutAll: '* for =='; nextPutAll: prFile title; nextPutAll: '==.'; cr ] ] ] ] ] ]) ]