Compare commits
43 Commits
Author | SHA1 | Date | |
---|---|---|---|
2875964efc | |||
7b86b2cfeb | |||
af81f92399 | |||
b500a65c00 | |||
83ea8d4310 | |||
2d811e9f38 | |||
a8d12ec46f | |||
c609595272 | |||
81298aefba | |||
72e0c775e5 | |||
f3a1927615 | |||
a96dd95359 | |||
8833341eee | |||
bbda57b908 | |||
f0dfea31b5 | |||
ef3218a343 | |||
f29ea2d014 | |||
b0498bfcc5 | |||
5b04df81b7 | |||
9f28bccc1e | |||
6055fd04f4 | |||
51ad9a8e12 | |||
1044fb4997 | |||
9f0f06d285 | |||
3cb08d4d2c | |||
72098ee5b9 | |||
ffeeff423b | |||
ba03def62c | |||
e839ee18c8 | |||
45f1ac84b1 | |||
cd938cf480 | |||
c11c00b7d1 | |||
471353880e | |||
321daf7165 | |||
bdd1813efb | |||
60c94d23e5 | |||
4bd52732ab | |||
c7fb5d8900 | |||
c2fafbbad4 | |||
8900a33b1b | |||
9a71c35602 | |||
e759f93afb | |||
e5303fa3e7 |
@ -16,12 +16,27 @@ BaselineOfBrea >> baseline: spec [
|
|||||||
for: #common
|
for: #common
|
||||||
do: [
|
do: [
|
||||||
"Dependencies"
|
"Dependencies"
|
||||||
|
self miniDocs: spec.
|
||||||
spec
|
spec
|
||||||
baseline: 'NeoJSON' with: [ spec repository: 'github://svenvc/NeoJSON/repository' ];
|
baseline: 'TaskIt' with: [ spec repository: 'github://pharo-contributions/taskit:v1.0' ]
|
||||||
baseline: 'Mustache' with: [ spec repository: 'github://noha/mustache/repository' ];
|
"[ spec repository: 'github://noha/taskit:add-all-future' ]"
|
||||||
baseline: 'TaskIt' with: [ spec repository: 'github://noha/taskit:add-all-future' ].
|
"Disabling Noha's Fork to make Brea installable.".
|
||||||
|
|
||||||
"Packages"
|
"Packages"
|
||||||
spec package: 'Brea' with: [ spec requires: #('NeoJSON' 'Mustache' 'TaskIt') ].
|
spec package: 'Brea' with: [ spec requires: #('MiniDocs' 'TaskIt') ].
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
{ #category : #baselines }
|
||||||
|
BaselineOfBrea >> miniDocs: spec [
|
||||||
|
| repo |
|
||||||
|
repo := ExoRepo new
|
||||||
|
repository: 'https://code.tupale.co/Offray/MiniDocs'.
|
||||||
|
repo
|
||||||
|
onConflict: [ :ex | ex useLoaded ];
|
||||||
|
onUpgrade: [ :ex | ex useLoaded ];
|
||||||
|
onDowngrade: [ :ex | ex useLoaded ];
|
||||||
|
onWarningLog;
|
||||||
|
load.
|
||||||
|
spec baseline: 'MiniDocs' with: [ spec repository: 'gitlocal://', repo local fullName ]
|
||||||
|
]
|
||||||
|
21
repository/Brea-Tests/BreaOperatorTest.class.st
Normal file
21
repository/Brea-Tests/BreaOperatorTest.class.st
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
"
|
||||||
|
A BreaQueryTest is a test class for testing the behavior of BreaQuery
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #BreaOperatorTest,
|
||||||
|
#superclass : #TestCase,
|
||||||
|
#category : #'Brea-Tests'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #tests }
|
||||||
|
BreaOperatorTest >> testSTONSerialization [
|
||||||
|
|
||||||
|
| original store deserialized |
|
||||||
|
original := BreaOperator new
|
||||||
|
name: 'plus';
|
||||||
|
inputs: {'a' -> 3. 'b' -> 4} asDictionary;
|
||||||
|
codeBlock: [ :x :y | x + y ].
|
||||||
|
store := STON toString: original.
|
||||||
|
deserialized := (STONReader on: store readStream) next.
|
||||||
|
self assert: original execute equals: deserialized execute
|
||||||
|
]
|
204
repository/Brea-Tests/BreaPageTest.class.st
Normal file
204
repository/Brea-Tests/BreaPageTest.class.st
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
"
|
||||||
|
A BreaPageTest is a test class for testing the behavior of BreaPage
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #BreaPageTest,
|
||||||
|
#superclass : #TestCase,
|
||||||
|
#category : #'Brea-Tests'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #initialization }
|
||||||
|
BreaPageTest >> createHTMLTemplateFile [
|
||||||
|
| testFile contents |
|
||||||
|
testFile := FileLocator temp / 'template.mus.html'.
|
||||||
|
testFile ensureCreateFile.
|
||||||
|
contents :=
|
||||||
|
'<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>{{title}}</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>{{title}}</h1>
|
||||||
|
<p>
|
||||||
|
{{#show}} You should see me. {{/show}}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{{#unhide}} You should not see me. {{/unhide}}
|
||||||
|
</p>
|
||||||
|
{{{ contents }}}
|
||||||
|
</body>
|
||||||
|
</html>'.
|
||||||
|
|
||||||
|
MarkupFile exportAsFileOn: testFile containing: contents.
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #initialization }
|
||||||
|
BreaPageTest >> createJSONFile [
|
||||||
|
| testFile contents |
|
||||||
|
testFile := self jsonTestFile.
|
||||||
|
testFile ensureCreateFile.
|
||||||
|
contents := '{ "title": "This is a test", "show": true, "unhide": false }'.
|
||||||
|
MarkupFile exportAsFileOn: testFile containing: contents.
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #initialization }
|
||||||
|
BreaPageTest >> createMarkdownFile [
|
||||||
|
| testFile contents |
|
||||||
|
testFile := self markdownTestFile.
|
||||||
|
testFile ensureCreateFile.
|
||||||
|
contents :=
|
||||||
|
'---
|
||||||
|
title: This is a test
|
||||||
|
show: true
|
||||||
|
unhide: false
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# Level one header
|
||||||
|
|
||||||
|
And paragraph contents with _emphasis_ and **strong emphasis**.'.
|
||||||
|
|
||||||
|
MarkupFile exportAsFileOn: testFile containing: contents.
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #'as yet unclassified' }
|
||||||
|
BreaPageTest >> htmlBodyContents [
|
||||||
|
^ '<h1 id="level-one-header">Level one header</h1>
|
||||||
|
<p>And paragraph contents with <em>emphasis</em> and <strong>strong emphasis</strong>.</p>
|
||||||
|
'
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #'as yet unclassified' }
|
||||||
|
BreaPageTest >> htmlOutput [
|
||||||
|
^ '<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>This is a test</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>This is a test</h1>
|
||||||
|
<p>
|
||||||
|
You should see me.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
', self htmlBodyContents,
|
||||||
|
'
|
||||||
|
</body>
|
||||||
|
</html>'
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #'as yet unclassified' }
|
||||||
|
BreaPageTest >> jsonTestFile [
|
||||||
|
^ FileLocator temp / 'test1.json'.
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #'as yet unclassified' }
|
||||||
|
BreaPageTest >> markdownTestFile [
|
||||||
|
^ FileLocator temp / 'test.md'.
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #'as yet unclassified' }
|
||||||
|
BreaPageTest >> setUp [
|
||||||
|
"I create disposable simple files for testing purposes."
|
||||||
|
super setUp.
|
||||||
|
self createMarkdownFile.
|
||||||
|
self createHTMLTemplateFile.
|
||||||
|
self createJSONFile
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #tests }
|
||||||
|
BreaPageTest >> testJSONMetadataExtraction [
|
||||||
|
|
||||||
|
| page testMetadata |
|
||||||
|
testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary.
|
||||||
|
page := BreaPage new.
|
||||||
|
page
|
||||||
|
shortName: 'test1';
|
||||||
|
folder: FileLocator temp.
|
||||||
|
self assert: page metadata equals: testMetadata
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #tests }
|
||||||
|
BreaPageTest >> testJSONPopulateMetadata [
|
||||||
|
|
||||||
|
| page testMetadata |
|
||||||
|
testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary.
|
||||||
|
page := BreaPage new.
|
||||||
|
page
|
||||||
|
shortName: 'test1';
|
||||||
|
folder: FileLocator temp.
|
||||||
|
page templateData at: 'extra' put: 'value'.
|
||||||
|
self assert: page populateMetadata equals: (testMetadata at: 'extra' put: 'value'; yourself)
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #tests }
|
||||||
|
BreaPageTest >> testMarkdownContentExtraction [
|
||||||
|
|
||||||
|
| page |
|
||||||
|
page := BreaPage new.
|
||||||
|
page
|
||||||
|
shortName: 'test';
|
||||||
|
folder: FileLocator temp.
|
||||||
|
self assert: page contents equals: self markdownTestFile contents.
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #tests }
|
||||||
|
BreaPageTest >> testMarkdownHTMLExport [
|
||||||
|
|
||||||
|
| page |
|
||||||
|
page := BreaPage new.
|
||||||
|
page
|
||||||
|
shortName: 'test';
|
||||||
|
folder: FileLocator temp;
|
||||||
|
template: 'template.mus.html';
|
||||||
|
bodyTag: 'contents'.
|
||||||
|
self assert: (page exportAsHTML contents) equals: self htmlOutput.
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #tests }
|
||||||
|
BreaPageTest >> testMarkdownMetadataExtraction [
|
||||||
|
|
||||||
|
| page testMetadata |
|
||||||
|
testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary.
|
||||||
|
page := BreaPage new.
|
||||||
|
page
|
||||||
|
shortName: 'test';
|
||||||
|
folder: FileLocator temp.
|
||||||
|
self assert: page metadata equals: testMetadata
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #tests }
|
||||||
|
BreaPageTest >> testMarkdownPopulateBody [
|
||||||
|
|
||||||
|
| page |
|
||||||
|
page := BreaPage new.
|
||||||
|
page
|
||||||
|
shortName: 'test';
|
||||||
|
folder: FileLocator temp;
|
||||||
|
bodyTag: 'contents'.
|
||||||
|
page populateTaggedBody.
|
||||||
|
self assert: (page templateData at: 'contents') equals: self htmlBodyContents.
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #tests }
|
||||||
|
BreaPageTest >> testMarkdownPopulateMetadata [
|
||||||
|
|
||||||
|
| page testMetadata |
|
||||||
|
testMetadata := {'title' -> 'This is a test' . 'show' -> true. 'unhide' -> false} asDictionary.
|
||||||
|
page := BreaPage new.
|
||||||
|
page
|
||||||
|
shortName: 'test';
|
||||||
|
folder: FileLocator temp.
|
||||||
|
page templateData at: 'extra' put: 'value'.
|
||||||
|
self assert: page populateMetadata equals: (testMetadata at: 'extra' put: 'value'; yourself)
|
||||||
|
]
|
1
repository/Brea-Tests/package.st
Normal file
1
repository/Brea-Tests/package.st
Normal file
@ -0,0 +1 @@
|
|||||||
|
Package { #name : #'Brea-Tests' }
|
20
repository/Brea/BlockClosure.extension.st
Normal file
20
repository/Brea/BlockClosure.extension.st
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
Extension { #name : #BlockClosure }
|
||||||
|
|
||||||
|
{ #category : #'*Brea' }
|
||||||
|
BlockClosure class >> fromSton: stonReader [
|
||||||
|
^ self compilerClass new
|
||||||
|
source: stonReader parseListSingleton;
|
||||||
|
evaluate
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #'*Brea' }
|
||||||
|
BlockClosure >> stonContainSubObjects [
|
||||||
|
^ false
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #'*Brea' }
|
||||||
|
BlockClosure >> stonOn: stonWriter [
|
||||||
|
self isClean
|
||||||
|
ifTrue: [ stonWriter writeObject: self listSingleton: self printString ]
|
||||||
|
ifFalse: [ stonWriter error: 'Only clean block can be serialized' ]
|
||||||
|
]
|
104
repository/Brea/BreaApp.class.st
Normal file
104
repository/Brea/BreaApp.class.st
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
Class {
|
||||||
|
#name : #BreaApp,
|
||||||
|
#superclass : #Object,
|
||||||
|
#instVars : [
|
||||||
|
'name',
|
||||||
|
'folder',
|
||||||
|
'host',
|
||||||
|
'componets'
|
||||||
|
],
|
||||||
|
#category : #Brea
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaApp >> add: anObject [
|
||||||
|
anObject class = String ifFalse: [ ].
|
||||||
|
self body
|
||||||
|
nextPutAll: (Pandoc htmlStringToMarkdown: anObject); cr.
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaApp >> appName [
|
||||||
|
^ self name asCamelCase
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaApp >> at: key put: anObject [
|
||||||
|
self components at: key put: anObject.
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaApp >> components [
|
||||||
|
^ componets ifNil: [ componets := OrderedDictionary new]
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaApp >> componentsWebView [
|
||||||
|
| response |
|
||||||
|
response := '' writeStream.
|
||||||
|
self components ifEmpty: [ ^ response contents ].
|
||||||
|
self components valuesDo: [ :component |
|
||||||
|
response
|
||||||
|
nextPutAll: component webView; cr
|
||||||
|
].
|
||||||
|
^ response contents
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaApp >> defaultView [
|
||||||
|
^ '<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="color-scheme" content="light dark" />
|
||||||
|
<link rel="stylesheet" href="css/pico.min.css">
|
||||||
|
<title>', self name, '</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main class="container">
|
||||||
|
', self componentsWebView,'
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>'
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaApp >> folder [
|
||||||
|
^ folder
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaApp >> folder: aFileDirectory [
|
||||||
|
folder := aFileDirectory
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaApp >> name [
|
||||||
|
^ name
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaApp >> name: aString [
|
||||||
|
name := aString
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaApp >> parentFolder: anObject [
|
||||||
|
self folder: anObject / self name asCamelCase
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaApp >> preview [
|
||||||
|
| defaultRoute |
|
||||||
|
defaultRoute := 'http://localhost:',self webHost server port asString, '/', self appName.
|
||||||
|
self webHost
|
||||||
|
GET: self appName -> [ self defaultView ].
|
||||||
|
GoogleChrome openWindowOn: defaultRoute
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaApp >> webHost [
|
||||||
|
^ host ifNil: [ host := Teapot allInstances detect: [ :each | each server isRunning ] ifNone: [ host := Teapot on. host server start ]]
|
||||||
|
]
|
@ -1,31 +0,0 @@
|
|||||||
Class {
|
|
||||||
#name : #BreaDataSource,
|
|
||||||
#superclass : #Object,
|
|
||||||
#instVars : [
|
|
||||||
'source',
|
|
||||||
'queries'
|
|
||||||
],
|
|
||||||
#category : #Brea
|
|
||||||
}
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaDataSource >> queries [
|
|
||||||
^ queries
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaDataSource >> queries: anObject [
|
|
||||||
queries := anObject
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaDataSource >> source [
|
|
||||||
^ source
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaDataSource >> source: aDictionary [
|
|
||||||
"Key, value pair in aDictionary contain a short name and a url pointing to a local or a remote
|
|
||||||
resource. If is local a FileLocator should be provided."
|
|
||||||
source := aDictionary
|
|
||||||
]
|
|
78
repository/Brea/BreaFile.class.st
Normal file
78
repository/Brea/BreaFile.class.st
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
"
|
||||||
|
I model the file where contents (data and/or metadata) for the Brea CSM pages are stored.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #BreaFile,
|
||||||
|
#superclass : #Object,
|
||||||
|
#instVars : [
|
||||||
|
'folder',
|
||||||
|
'name'
|
||||||
|
],
|
||||||
|
#category : #Brea
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #'instance creation' }
|
||||||
|
BreaFile class >> fromShortName: nameString andFolder: aFileLocation [
|
||||||
|
"I create a new BreaFile assigning priorities to the filename discovery according to
|
||||||
|
their extension currently present in a particular folder."
|
||||||
|
| extensions |
|
||||||
|
|
||||||
|
extensions := #('md' 'json' 'yaml').
|
||||||
|
extensions do: [ :ext | | markupFile filename |
|
||||||
|
filename := nameString, '.', ext.
|
||||||
|
markupFile := aFileLocation / filename.
|
||||||
|
markupFile exists ifTrue: [ ^ self new name: filename; folder: aFileLocation ].
|
||||||
|
].
|
||||||
|
^ nil.
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaFile >> contentString [
|
||||||
|
|
||||||
|
self name ifNil: [ ^ nil ].
|
||||||
|
(self name endsWith: '.md') ifTrue: [ ^ self contents contents ].
|
||||||
|
(self name endsWith: '.json') ifTrue: [ ^ self contents asString ].
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaFile >> contents [
|
||||||
|
| file |
|
||||||
|
self name ifNil: [ ^ nil ].
|
||||||
|
file := self folder / self name.
|
||||||
|
(self name endsWith: '.md') ifTrue: [ ^ Markdown fromFile: file ].
|
||||||
|
(self name endsWith: '.json') ifTrue: [ ^ NeoJSONObject fromString: file contents ]
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaFile >> file [
|
||||||
|
self folder ifNil: [ ^ self ].
|
||||||
|
self name ifNil: [ ^ self ].
|
||||||
|
^ self folder / self name.
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaFile >> folder [
|
||||||
|
^ folder
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaFile >> folder: anObject [
|
||||||
|
folder := anObject
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaFile >> metadata [
|
||||||
|
self name ifNil: [ ^ nil ].
|
||||||
|
(self name endsWith: '.md') ifTrue: [ ^ self contents metadata ].
|
||||||
|
(self name endsWith: '.json') ifTrue: [ ^ self contents asDictionary ].
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaFile >> name [
|
||||||
|
^ name
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaFile >> name: anObject [
|
||||||
|
name := anObject
|
||||||
|
]
|
@ -1,489 +0,0 @@
|
|||||||
"
|
|
||||||
I model a member of a Brea site, usually a human.
|
|
||||||
"
|
|
||||||
Class {
|
|
||||||
#name : #BreaMember,
|
|
||||||
#superclass : #Object,
|
|
||||||
#instVars : [
|
|
||||||
'givenName',
|
|
||||||
'familyName',
|
|
||||||
'picture',
|
|
||||||
'country',
|
|
||||||
'tags',
|
|
||||||
'email',
|
|
||||||
'password',
|
|
||||||
'webPresence',
|
|
||||||
'organizations'
|
|
||||||
],
|
|
||||||
#category : #Brea
|
|
||||||
}
|
|
||||||
|
|
||||||
{ #category : #converting }
|
|
||||||
BreaMember >> asStonModified [
|
|
||||||
"asSton is generated a core dumped now. This renaming is trying to solve that. Maybe
|
|
||||||
in the offical release it will be solved"
|
|
||||||
^ STON toStringPretty: self
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> country [
|
|
||||||
^ country
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> country: anObject [
|
|
||||||
country := anObject
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #public }
|
|
||||||
BreaMember >> countryTemplate [
|
|
||||||
^ '{{#country}}
|
|
||||||
<tr>
|
|
||||||
<td class="mdl-data-table__cell--non-numeric"><b>Country</b></td>
|
|
||||||
<td class="mdl-data-table__cell--non-numeric">{{.}}</td>
|
|
||||||
</tr>
|
|
||||||
{{/country}}' asMustacheTemplate value: self
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #helpers }
|
|
||||||
BreaMember >> createTestUser [
|
|
||||||
^ self class new
|
|
||||||
givenName: 'Test';
|
|
||||||
familyName: 'User';
|
|
||||||
country: 'Neverland';
|
|
||||||
memberOf: 'HackBo' withWebsite: 'http://hackbo.co/';
|
|
||||||
memberOf: 'mutabiT' withWebsite: 'http://mutabit.com/';
|
|
||||||
website: 'http://test.user';
|
|
||||||
twitter: '@offrayLC';
|
|
||||||
email: 'iam@test.user';
|
|
||||||
tags: 'just, a lot, of words, separated, by commas'.
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> email [
|
|
||||||
^ email
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> email: anEmailAddress [
|
|
||||||
email := (SHA1 new hashMessage: anEmailAddress) hex
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> facebook [
|
|
||||||
^ self webPresence facebook.
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> facebook: aProfileName [
|
|
||||||
aProfileName = ''
|
|
||||||
ifTrue: [ self webPresence facebook: nil ]
|
|
||||||
ifFalse: [ self webPresence facebook: aProfileName ]
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #public }
|
|
||||||
BreaMember >> facebookTemplate [
|
|
||||||
^ '{{#facebook}}
|
|
||||||
<tr>
|
|
||||||
<td class="mdl-data-table__cell--non-numeric">
|
|
||||||
<b>Facebook</b></td>
|
|
||||||
<td class="mdl-data-table__cell--non-numeric">
|
|
||||||
<a href="https://facebook.com/{{.}}">
|
|
||||||
{{.}}</a></td>
|
|
||||||
</tr>
|
|
||||||
{{/facebook}}' asMustacheTemplate value: self
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> familyName [
|
|
||||||
^ familyName
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> familyName: anObject [
|
|
||||||
familyName := anObject
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #helpers }
|
|
||||||
BreaMember >> fullName [
|
|
||||||
^ self givenName asLowercase, '-', self familyName asLowercase
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> getGenericProfilePicture [
|
|
||||||
"Other considered avatars where:
|
|
||||||
'https://upload.wikimedia.org/wikipedia/commons/1/1e/Default-avatar.jpg'"
|
|
||||||
self picture: 'https://www.jamf.com/jamf-nation/img/default-avatars/generic-user.png'.
|
|
||||||
^ picture
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> givenName [
|
|
||||||
^ givenName
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> givenName: anObject [
|
|
||||||
givenName := anObject
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #public }
|
|
||||||
BreaMember >> head [
|
|
||||||
^ '<head>', self headMeta, self headTitle, self headStyles,'</head>'
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #utility }
|
|
||||||
BreaMember >> headMeta [
|
|
||||||
^ '<meta charset="utf-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<meta name="description" content="A portfolio template that uses Material Design Lite.">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">'
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #utility }
|
|
||||||
BreaMember >> headStyles [
|
|
||||||
^ '
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&lang=en">
|
|
||||||
<link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.grey-pink.min.css" />
|
|
||||||
<link rel="stylesheet" href="http://mutabit.com/repos.fossil/gig/doc/tip/styles.css" />
|
|
||||||
<link rel="stylesheet" href="styles.css" />
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
|
||||||
'
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #utility }
|
|
||||||
BreaMember >> headTitle [
|
|
||||||
^ self headTitled: 'GIG: Network'
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #utility }
|
|
||||||
BreaMember >> headTitled: aString [
|
|
||||||
^ '<title>', aString ,'</title>'
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #public }
|
|
||||||
BreaMember >> html [
|
|
||||||
"I show the member profile as HTML"
|
|
||||||
^ self head, self htmlOutput
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #public }
|
|
||||||
BreaMember >> htmlInput [
|
|
||||||
"I capture data in a HTML Form and use it to create a new BreaMember"
|
|
||||||
^ '
|
|
||||||
<html lang="en">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<meta name="description" content="A portfolio template that uses Material Design Lite.">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
|
|
||||||
<title>Add Member | GIG Network</title>
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&lang=en">
|
|
||||||
<link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.grey-pink.min.css" />
|
|
||||||
<link rel="stylesheet" href="styles.css" />
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
|
|
||||||
<div class="mdl-layout__drawer mdl-layout--small-screen-only">
|
|
||||||
<nav class="mdl-navigation mdl-typography--body-1-force-preferred-font">
|
|
||||||
<a class="mdl-navigation__link is-active" href="index.html">Portfolio</a>
|
|
||||||
<a class="mdl-navigation__link" href="blog.html">Blog</a>
|
|
||||||
<a class="mdl-navigation__link" href="about.html">About</a>
|
|
||||||
<a class="mdl-navigation__link" href="contact.html">Contact</a>
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
<main class="mdl-layout__content">
|
|
||||||
<div class="mdl-grid portfolio-max-width portfolio-contact">
|
|
||||||
<div class="mdl-cell mdl-cell--12-col mdl-card mdl-shadow--4dp">
|
|
||||||
<div class="mdl-card__title">
|
|
||||||
<h2 class="mdl-card__title-text">Add new member</h2>
|
|
||||||
</div>
|
|
||||||
<div class="mdl-card__supporting-text">
|
|
||||||
<p>
|
|
||||||
Fill out the form.
|
|
||||||
The fields preceded by [*] are obligatory.
|
|
||||||
</p>
|
|
||||||
<form enctype="application/x-www-form-urlencoded" action="summit" method="POST" class="">
|
|
||||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
|
|
||||||
<input class="mdl-textfield__input" pattern="[A-Z,a-z, ]*" type="text" name="givenName">
|
|
||||||
<label class="mdl-textfield__label" for="givenName">[*]Given Name...</label>
|
|
||||||
<span class="mdl-textfield__error">Letters and spaces only</span>
|
|
||||||
</div>
|
|
||||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
|
|
||||||
<input class="mdl-textfield__input" pattern="[A-Z,a-z, ]*" type="text" name="familyName">
|
|
||||||
<label class="mdl-textfield__label" for="familyName">[*]Family Name...</label>
|
|
||||||
<span class="mdl-textfield__error">Letters and spaces only</span>
|
|
||||||
</div><br>
|
|
||||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
|
|
||||||
<input class="mdl-textfield__input" type="text" name="email">
|
|
||||||
<label class="mdl-textfield__label" for="email">[*]Email...</label>
|
|
||||||
</div>
|
|
||||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
|
|
||||||
<input class="mdl-textfield__input" pattern="[A-Z,a-z, ]*" type="text" name="country">
|
|
||||||
<label class="mdl-textfield__label" for="country">[*]Country...</label>
|
|
||||||
<span class="mdl-textfield__error">Letters and spaces only</span>
|
|
||||||
</div><br>
|
|
||||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
|
|
||||||
<input class="mdl-textfield__input" pattern="[A-Z,a-z, ]*" type="text" name="organizations">
|
|
||||||
<label class="mdl-textfield__label" for="organizations">
|
|
||||||
[*]Organization(s) (separated with commas)</label>
|
|
||||||
<span class="mdl-textfield__error">Letters and spaces only</span>
|
|
||||||
</div><br>
|
|
||||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
|
|
||||||
<input class="mdl-textfield__input" type="text" name="picture">
|
|
||||||
<label class="mdl-textfield__label" for="website">Profile picture url...</label>
|
|
||||||
</div>
|
|
||||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
|
|
||||||
<input class="mdl-textfield__input" type="text" name="website">
|
|
||||||
<label class="mdl-textfield__label" for="website">Personal website...</label>
|
|
||||||
</div><br>
|
|
||||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
|
|
||||||
<input class="mdl-textfield__input" type="text" name="twitter">
|
|
||||||
<label class="mdl-textfield__label" for="twitter">Twitter...</label>
|
|
||||||
</div>
|
|
||||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
|
|
||||||
<input class="mdl-textfield__input" type="text" name="facebook">
|
|
||||||
<label class="mdl-textfield__label" for="facebook">Facebook...</label>
|
|
||||||
</div><br>
|
|
||||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
|
|
||||||
<textarea class="mdl-textfield__input" type="text" rows="5" name="tags"></textarea>
|
|
||||||
<label class="mdl-textfield__label" for="tags">Tags (separated with commas)...</label>
|
|
||||||
</div>
|
|
||||||
<p>
|
|
||||||
<button class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect
|
|
||||||
mdl-button--accent" type="submit" value="Submit">
|
|
||||||
Submit
|
|
||||||
</button>
|
|
||||||
</p>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<footer class="mdl-mini-footer">
|
|
||||||
<div class="mdl-mini-footer__left-section">
|
|
||||||
<div class="mdl-logo">Simple portfolio website</div>
|
|
||||||
</div>
|
|
||||||
<div class="mdl-mini-footer__right-section">
|
|
||||||
<ul class="mdl-mini-footer__link-list">
|
|
||||||
<li><a href="#">Help</a></li>
|
|
||||||
<li><a href="#">Privacy & Terms</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
<script src="https://code.getmdl.io/1.3.0/material.min.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
'
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #public }
|
|
||||||
BreaMember >> htmlOutput [
|
|
||||||
|
|
||||||
^ self htmlOutputTemplate asMustacheTemplate value: self
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #public }
|
|
||||||
BreaMember >> htmlOutputTemplate [
|
|
||||||
"I show the member profile as HTML"
|
|
||||||
^ '<div class="mdl-grid portfolio-max-width">
|
|
||||||
<div class="mdl-cell mdl-card mdl-shadow--4dp portfolio-card">
|
|
||||||
<div class="mdl-card__title">
|
|
||||||
<h2 class="mdl-card__title-text">{{givenName}} {{familyName}}</h2>
|
|
||||||
</div>
|
|
||||||
<div class="mdl-card__media">
|
|
||||||
<img class="article-image"
|
|
||||||
src="{{picture}}"
|
|
||||||
border="0" alt="">
|
|
||||||
</div>
|
|
||||||
<div class="mdl-card__supporting-text">
|
|
||||||
<table class="mdl-data-table mdl-js-data-table">
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td class="mdl-data-table__cell--non-numeric"><b>Name</b></td>
|
|
||||||
<td class="mdl-data-table__cell--non-numeric">{{givenName}} {{familyName}}</td>
|
|
||||||
</tr>',
|
|
||||||
self countryTemplate,
|
|
||||||
self organizationsTemplate,
|
|
||||||
self websiteTemplate,
|
|
||||||
self twitterTemplate,
|
|
||||||
self facebookTemplate,
|
|
||||||
self tagsTemplate,
|
|
||||||
'
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<div class="mdl-card__actions mdl-card--border">
|
|
||||||
<a class="mdl-button mdl-button--colored mdl-js-button
|
|
||||||
mdl-js-ripple-effect mdl-button--accent"
|
|
||||||
href="portfolio-example01.html">Read more</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
'
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> instagram [
|
|
||||||
^ self webPresence instagram.
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> instagram: aProfileName [
|
|
||||||
self webPresence instagram: aProfileName
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> memberOf: anOrgName [
|
|
||||||
self organizations add:
|
|
||||||
(BreaOrganization new name: anOrgName)
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> memberOf: anOrgName withWebsite: aUrl [
|
|
||||||
self organizations add:
|
|
||||||
(BreaOrganization new
|
|
||||||
name: anOrgName;
|
|
||||||
website: aUrl)
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> organizations [
|
|
||||||
^ organizations ifNil: [ organizations := OrderedCollection new ]
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> organizations: anOrgListOrName [
|
|
||||||
anOrgListOrName splitOn: ',' do: [ :each | self memberOf: each ]
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #public }
|
|
||||||
BreaMember >> organizationsTemplate [
|
|
||||||
^ '
|
|
||||||
<tr>
|
|
||||||
<td class="mdl-data-table__cell--non-numeric"><b>Organization(s)</b></td>
|
|
||||||
<td class="mdl-data-table__cell--non-numeric">
|
|
||||||
{{#organizations}}
|
|
||||||
<a href="{{website}}">{{name}}</a>
|
|
||||||
{{/organizations}}
|
|
||||||
</td>
|
|
||||||
</tr>' asMustacheTemplate value: self
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> password [
|
|
||||||
^ password
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> password: anObject [
|
|
||||||
password := anObject
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> picture [
|
|
||||||
^ picture ifNil: [ ^ self getGenericProfilePicture ]
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> picture: anImageFilePath [
|
|
||||||
picture := anImageFilePath
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #helpers }
|
|
||||||
BreaMember >> renderTestUserAsHtml [
|
|
||||||
^ self class new createTestUser html
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #'server handling' }
|
|
||||||
BreaMember >> storeInto: aFileDirectory [
|
|
||||||
| folder file |
|
|
||||||
folder := (aFileDirectory asFileReference / self fullName) ensureCreateDirectory.
|
|
||||||
file := (folder / 'info.ston') ensureCreateFile.
|
|
||||||
file writeStreamDo: [:stream |
|
|
||||||
(STON writer on: stream)
|
|
||||||
newLine: String crlf;
|
|
||||||
prettyPrint: true;
|
|
||||||
nextPut: self]
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> tags [
|
|
||||||
^ tags
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> tags: anObject [
|
|
||||||
tags := anObject
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #public }
|
|
||||||
BreaMember >> tagsTemplate [
|
|
||||||
^ '{{#tags}}
|
|
||||||
<tr>
|
|
||||||
<td colspan="2"; style="text-align:left">
|
|
||||||
<b>Tags</b><br>
|
|
||||||
{{.}}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{{/tags}}' asMustacheTemplate value: self
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> twitter [
|
|
||||||
^ self webPresence twitter.
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> twitter: aProfileName [
|
|
||||||
aProfileName = ''
|
|
||||||
ifTrue: [ self webPresence twitter: nil ]
|
|
||||||
ifFalse: [ self webPresence twitter: aProfileName ]
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #public }
|
|
||||||
BreaMember >> twitterTemplate [
|
|
||||||
^ '{{#twitter}}
|
|
||||||
<tr>
|
|
||||||
<td class="mdl-data-table__cell--non-numeric">
|
|
||||||
<b>Twitter</b></td>
|
|
||||||
<td class="mdl-data-table__cell--non-numeric">
|
|
||||||
<a href="https://twitter.com/{{.}}">
|
|
||||||
{{.}}</a></td>
|
|
||||||
</tr>
|
|
||||||
{{/twitter}}' asMustacheTemplate value: self
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> webPresence [
|
|
||||||
^ webPresence ifNil: [ webPresence := BreaWebPresence new ]
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> webPresence: anObject [
|
|
||||||
webPresence := anObject
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> website [
|
|
||||||
^ self webPresence website.
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaMember >> website: anUrl [
|
|
||||||
self webPresence website: anUrl
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #public }
|
|
||||||
BreaMember >> websiteTemplate [
|
|
||||||
^ '{{#website}}
|
|
||||||
<tr>
|
|
||||||
<td class="mdl-data-table__cell--non-numeric"><b>Website</b></td>
|
|
||||||
<td class="mdl-data-table__cell--non-numeric">
|
|
||||||
<a href="{{.}}">{{.}}</a>
|
|
||||||
</td>
|
|
||||||
{{/website}}' asMustacheTemplate value: self
|
|
||||||
]
|
|
@ -1,8 +0,0 @@
|
|||||||
"
|
|
||||||
A BreaMemberTest is a test class for testing the behavior of BreaMember
|
|
||||||
"
|
|
||||||
Class {
|
|
||||||
#name : #BreaMemberTest,
|
|
||||||
#superclass : #TestCase,
|
|
||||||
#category : #'Brea-Tests'
|
|
||||||
}
|
|
95
repository/Brea/BreaOperator.class.st
Normal file
95
repository/Brea/BreaOperator.class.st
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
"
|
||||||
|
I represent a operation that can be done on data inputs to produce and output by executing
|
||||||
|
a code block.
|
||||||
|
|
||||||
|
I can be used by BreaThemes to produce outpus reflected in a particular set of theme pages.
|
||||||
|
|
||||||
|
|
||||||
|
- (for bonus points) how to create instances.
|
||||||
|
|
||||||
|
One simple example is simply gorgeous.
|
||||||
|
|
||||||
|
Internal Representation and Key Implementation Points.
|
||||||
|
|
||||||
|
Instance Variables
|
||||||
|
codeBlock: <Object>
|
||||||
|
inputs: <Object>
|
||||||
|
name: <Object>
|
||||||
|
|
||||||
|
|
||||||
|
Implementation Points
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #BreaOperator,
|
||||||
|
#superclass : #Object,
|
||||||
|
#instVars : [
|
||||||
|
'name',
|
||||||
|
'inputs',
|
||||||
|
'codeBlock',
|
||||||
|
'cleanedInputs'
|
||||||
|
],
|
||||||
|
#category : #Brea
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #converting }
|
||||||
|
BreaOperator >> asSton [
|
||||||
|
^ STON toStringPretty: self
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #converting }
|
||||||
|
BreaOperator >> cleanInputs [
|
||||||
|
self cleanedInputs ifNil: [ ^ self ].
|
||||||
|
self cleanedInputs ifTrue: [
|
||||||
|
self inputs keysAndValuesDo: [ :k :v | | currentValue |
|
||||||
|
currentValue := self inputs at: k.
|
||||||
|
self inputs at: k put: currentValue class new
|
||||||
|
]
|
||||||
|
].
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaOperator >> cleanedInputs [
|
||||||
|
^ cleanedInputs
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaOperator >> cleanedInputs: aBoolean [
|
||||||
|
"I tell if the inputs should be cleaned when the query is serialized as STON, for
|
||||||
|
example when they contain sensible information, like API keys or passwords"
|
||||||
|
cleanedInputs := aBoolean
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaOperator >> codeBlock [
|
||||||
|
^ codeBlock
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaOperator >> codeBlock: anObject [
|
||||||
|
codeBlock := anObject
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #execution }
|
||||||
|
BreaOperator >> execute [
|
||||||
|
^ self codeBlock valueWithArguments: self inputs values.
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaOperator >> inputs [
|
||||||
|
^ inputs
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaOperator >> inputs: anOrderedDictionary [
|
||||||
|
inputs := anOrderedDictionary
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaOperator >> name [
|
||||||
|
^ name
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaOperator >> name: anObject [
|
||||||
|
name := anObject
|
||||||
|
]
|
@ -1,32 +0,0 @@
|
|||||||
"
|
|
||||||
I store the places a BreaMember is affiliated to.
|
|
||||||
"
|
|
||||||
Class {
|
|
||||||
#name : #BreaOrganization,
|
|
||||||
#superclass : #Object,
|
|
||||||
#instVars : [
|
|
||||||
'name',
|
|
||||||
'website'
|
|
||||||
],
|
|
||||||
#category : #Brea
|
|
||||||
}
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaOrganization >> name [
|
|
||||||
^ name
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaOrganization >> name: anObject [
|
|
||||||
name := anObject
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaOrganization >> website [
|
|
||||||
^ website
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaOrganization >> website: anObject [
|
|
||||||
website := anObject
|
|
||||||
]
|
|
255
repository/Brea/BreaPage.class.st
Normal file
255
repository/Brea/BreaPage.class.st
Normal file
@ -0,0 +1,255 @@
|
|||||||
|
"
|
||||||
|
I model a wiki page of a Brea site.
|
||||||
|
I am modelled after common wiki pages, where a document in a light markup laguage
|
||||||
|
is converted in HTML and is expected to access document history (I am helped by
|
||||||
|
FossilRepo for that).
|
||||||
|
I can be used for other types of publications, like blog post though.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #BreaPage,
|
||||||
|
#superclass : #Object,
|
||||||
|
#instVars : [
|
||||||
|
'shortName',
|
||||||
|
'template',
|
||||||
|
'templateData',
|
||||||
|
'bodyTag',
|
||||||
|
'splitters',
|
||||||
|
'subpages',
|
||||||
|
'metadata',
|
||||||
|
'folder',
|
||||||
|
'file'
|
||||||
|
],
|
||||||
|
#category : #Brea
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #operation }
|
||||||
|
BreaPage >> bodyContentsAsHTML [
|
||||||
|
| sourcePage commandParameters |
|
||||||
|
self contentsFile ifNil: [ ^ self ].
|
||||||
|
sourcePage := self file file.
|
||||||
|
Smalltalk os isWindows ifTrue: [
|
||||||
|
^ Pandoc markdownToHtml: sourcePage
|
||||||
|
].
|
||||||
|
commandParameters := ' -f markdown+startnum+task_lists -t html '.
|
||||||
|
^ GtSubprocessWithInMemoryOutput new
|
||||||
|
shellCommand: 'pandoc', commandParameters, sourcePage fullName;
|
||||||
|
runAndWait;
|
||||||
|
stdout.
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaPage >> bodyTag [
|
||||||
|
^ bodyTag
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaPage >> bodyTag: aString [
|
||||||
|
"I represent the Mustache Template tag used to denote the body part of a page.
|
||||||
|
While the metadata is self describing via YAML metadata blocks in Markddown, so
|
||||||
|
they map where ever they are needed in a template, the Markdown file that will be converted
|
||||||
|
in HTML via a template doesn't know which part should occupy once the conversion is done.
|
||||||
|
I provide such knowledge. So if a page template puts the body content under the mustache tag
|
||||||
|
{{content}}, I should use bodyTag: 'content'.
|
||||||
|
bodyTag: is template dependant."
|
||||||
|
bodyTag := aString
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaPage >> contents [
|
||||||
|
| result |
|
||||||
|
self contentsFile ifNil: [ ^ nil ].
|
||||||
|
result := '' writeStream.
|
||||||
|
result nextPutAll: self contentsFile contentString.
|
||||||
|
self subpages ifNotNil: [
|
||||||
|
self subpages do: [ :sp | | markdownTempFile |
|
||||||
|
markdownTempFile := self folder / (sp, '.md').
|
||||||
|
result nextPutAll: (Markdown fromFile: markdownTempFile) contents.
|
||||||
|
]
|
||||||
|
].
|
||||||
|
^ result contents withInternetLineEndings.
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #operation }
|
||||||
|
BreaPage >> contentsFile [
|
||||||
|
|
||||||
|
self folder ifNil: [ ^ self ].
|
||||||
|
self shortName ifNil: [ ^ self ].
|
||||||
|
^ BreaFile fromShortName: self shortName andFolder: self folder.
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #'as yet unclassified' }
|
||||||
|
BreaPage >> exportAsHTML [
|
||||||
|
| htmlContents allActions actionsArray semaphore result |
|
||||||
|
self shortName ifNil: [ ^ self ].
|
||||||
|
self template ifNil: [ ^ self ].
|
||||||
|
actionsArray := { [ self populateMetadata ] future. }.
|
||||||
|
self splitters ifNotEmpty: [ actionsArray := actionsArray copyWith: [ self split ] future ].
|
||||||
|
self bodyTag ifNotNil: [
|
||||||
|
actionsArray := actionsArray copyWith: [ self populateBodyAs: self bodyTag ] future ].
|
||||||
|
allActions := TKTFuture fromCollectionOfFutures: actionsArray.
|
||||||
|
semaphore := Semaphore new.
|
||||||
|
allActions onSuccessDo: [ :values |
|
||||||
|
result := values last.
|
||||||
|
semaphore signal.
|
||||||
|
].
|
||||||
|
semaphore wait.
|
||||||
|
htmlContents := (MustacheTemplate on: result templateFile contents) value: result templateData.
|
||||||
|
^ MarkupFile exportAsFileOn: self folder / (self shortName, '.html' ) containing: htmlContents
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaPage >> file [
|
||||||
|
(self shortName isNil or: [ self folder isNil ]) ifTrue: [ ^ nil ].
|
||||||
|
^ file ifNil: [ ^ BreaFile fromShortName: self shortName andFolder: self folder ]
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaPage >> file: anObject [
|
||||||
|
file := anObject
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaPage >> folder [
|
||||||
|
^ folder
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaPage >> folder: folderFileReference [
|
||||||
|
folder := folderFileReference
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #'as yet unclassified' }
|
||||||
|
BreaPage >> htmlContents [
|
||||||
|
self shortName ifNil: [ ^ self ].
|
||||||
|
self template ifNil: [ ^ self ].
|
||||||
|
^ (MustacheTemplate on: self templateFile contents) value: self templateData.
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaPage >> metadata [
|
||||||
|
^ metadata ifNil: [ self contentsFile metadata ]
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaPage >> metadata: aDictionary [
|
||||||
|
"External place where page metadata is located (on Internet or the local file system) in JSON format.
|
||||||
|
If nil, is suposed that is placed in the Markdown file with the page contents."
|
||||||
|
metadata := aDictionary
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #'as yet unclassified' }
|
||||||
|
BreaPage >> populateBodyAs: key [
|
||||||
|
self templateData at: key put: self bodyContentsAsHTML.
|
||||||
|
^ self.
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #'as yet unclassified' }
|
||||||
|
BreaPage >> populateExternalMetadata [
|
||||||
|
self metadata ifNil: [ ^ self ].
|
||||||
|
self
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #operation }
|
||||||
|
BreaPage >> populateMetadata [
|
||||||
|
| metadataTemp |
|
||||||
|
self metadata
|
||||||
|
ifNotNil: [ metadataTemp := self metadata ]
|
||||||
|
ifNil: [ metadataTemp := self contentsFile metadata].
|
||||||
|
metadataTemp keysAndValuesDo: [ :key :value |
|
||||||
|
self templateData at: key put: value ].
|
||||||
|
^ self templateData
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #operation }
|
||||||
|
BreaPage >> populateTaggedBody [
|
||||||
|
self bodyTag ifNil: [ ^ self ].
|
||||||
|
^ self populateBodyAs: self bodyTag.
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaPage >> shortName [
|
||||||
|
^ shortName
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaPage >> shortName: aString [
|
||||||
|
"The name of the file tha contains the light markup to produce the web page, without file extension.
|
||||||
|
By default I work with Markdown files."
|
||||||
|
shortName := aString
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #'as yet unclassified' }
|
||||||
|
BreaPage >> split [
|
||||||
|
self splitters ifEmpty: [ ^ self ].
|
||||||
|
self splitters keysAndValuesDo: [ :key :value | self split: key with: value ].
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #'as yet unclassified' }
|
||||||
|
BreaPage >> split: key with: subkey [
|
||||||
|
"I split a comma separated collection of subkeys stored in the 'key' field and name each one as 'subkey'
|
||||||
|
to put it indiviudally in a Mustache template."
|
||||||
|
| allSubkeys cleaned data |
|
||||||
|
allSubkeys := (self populateMetadata at: key) splitOn: ','.
|
||||||
|
cleaned := allSubkeys collect: [ :item | item withBlanksCondensed ].
|
||||||
|
data := OrderedCollection new.
|
||||||
|
cleaned do: [ :item |
|
||||||
|
data add: { subkey -> item } asDictionary ].
|
||||||
|
self populateMetadata at: key put: data; yourself.
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #'as yet unclassified' }
|
||||||
|
BreaPage >> splitterAt: key with: subkey [
|
||||||
|
self splitters at: key put: subkey
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaPage >> splitters [
|
||||||
|
^ splitters ifNil: [ splitters := Dictionary new ]
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaPage >> splitters: aDictionary [
|
||||||
|
"I model the pattern where a Mustache template contains something like
|
||||||
|
{{# key}} {{value}} {{/ key}} and has data that needs to be split before injecting it in the template."
|
||||||
|
splitters := aDictionary
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaPage >> subpages [
|
||||||
|
^ subpages
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaPage >> subpages: shortNamesList [
|
||||||
|
"I am used when a page is composed of other subpages (for example with link aliases) that are shared
|
||||||
|
accross several pages."
|
||||||
|
subpages := shortNamesList
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaPage >> template [
|
||||||
|
^ template
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaPage >> template: mustacheFileName [
|
||||||
|
"Usually templates and their pages are located in the same folder."
|
||||||
|
template := mustacheFileName
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaPage >> templateData [
|
||||||
|
^ templateData ifNil: [ templateData := Dictionary new ]
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaPage >> templateData: aDictionary [
|
||||||
|
templateData := aDictionary
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #'as yet unclassified' }
|
||||||
|
BreaPage >> templateFile [
|
||||||
|
self folder ifNil: [ ^ self ].
|
||||||
|
self template ifNil: [ ^ self ].
|
||||||
|
^ self folder / self template
|
||||||
|
]
|
@ -1,89 +0,0 @@
|
|||||||
"
|
|
||||||
I define a [Mustache][1] template and how it is used to create
|
|
||||||
derivate output files combining it with particular data sources.
|
|
||||||
|
|
||||||
[1]: https://mustache.github.io/
|
|
||||||
"
|
|
||||||
Class {
|
|
||||||
#name : #BreaTemplate,
|
|
||||||
#superclass : #Object,
|
|
||||||
#instVars : [
|
|
||||||
'template',
|
|
||||||
'data',
|
|
||||||
'location',
|
|
||||||
'queries',
|
|
||||||
'outputs'
|
|
||||||
],
|
|
||||||
#category : #Brea
|
|
||||||
}
|
|
||||||
|
|
||||||
{ #category : #adding }
|
|
||||||
BreaTemplate >> addDataSourceNamed: name with: source [
|
|
||||||
self
|
|
||||||
data at: name put: source.
|
|
||||||
self data.
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaTemplate >> data [
|
|
||||||
^ data ifNil: [ data := Dictionary new ]
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaTemplate >> data: aDictionary [
|
|
||||||
"Each item in the dictionary is a unique alias (as key) and a data location (as value),
|
|
||||||
usually on the web.
|
|
||||||
Alias and locations are used later to define data queries to feed into templates."
|
|
||||||
data := aDictionary
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaTemplate >> location [
|
|
||||||
^ location
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaTemplate >> location: aFolderPath [
|
|
||||||
"This is the place where a template and its derivate files are located.
|
|
||||||
A shared location is an easy approach to start with and creates more explicit
|
|
||||||
relation between derived files and templates.
|
|
||||||
Eventually some re-mapping or re-routing could be used so templates and their outputs
|
|
||||||
could be further apart."
|
|
||||||
location := aFolderPath
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaTemplate >> outputs [
|
|
||||||
^ outputs
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaTemplate >> outputs: fileNamesList [
|
|
||||||
"fileNamesList contain the files which are derived from the template."
|
|
||||||
outputs := fileNamesList
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaTemplate >> queries [
|
|
||||||
^ queries ifNil: [ queries := Dictionary new ]
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaTemplate >> queries: aDictionary [
|
|
||||||
"aDictionary contains the alias for the query as key and a block that will be executed
|
|
||||||
on a particular data source, as value."
|
|
||||||
queries := aDictionary
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaTemplate >> template [
|
|
||||||
^ template
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaTemplate >> template: aFileName [
|
|
||||||
"I provide the name of the mustache base template.
|
|
||||||
The file can have any name, but by convention they end in '.mus.html' 'mus.md' and
|
|
||||||
so on."
|
|
||||||
template := aFileName
|
|
||||||
]
|
|
229
repository/Brea/BreaTheme.class.st
Normal file
229
repository/Brea/BreaTheme.class.st
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
"
|
||||||
|
I model a web theme.
|
||||||
|
|
||||||
|
For the Collaborators Part: State my main collaborators and one line about how I interact with them.
|
||||||
|
|
||||||
|
Public API and Key Messages
|
||||||
|
|
||||||
|
- message one
|
||||||
|
- message two
|
||||||
|
- (for bonus points) how to create instances.
|
||||||
|
|
||||||
|
One simple example is simply gorgeous.
|
||||||
|
|
||||||
|
Internal Representation and Key Implementation Points.
|
||||||
|
|
||||||
|
Instance Variables
|
||||||
|
name: <Object>
|
||||||
|
preview: <Object>
|
||||||
|
provider: <Object>
|
||||||
|
url: <Object>
|
||||||
|
|
||||||
|
|
||||||
|
Implementation Points
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #BreaTheme,
|
||||||
|
#superclass : #Object,
|
||||||
|
#instVars : [
|
||||||
|
'name',
|
||||||
|
'folder',
|
||||||
|
'provider',
|
||||||
|
'url',
|
||||||
|
'preview',
|
||||||
|
'license',
|
||||||
|
'operators'
|
||||||
|
],
|
||||||
|
#category : #Brea
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaTheme class >> availablePacks [
|
||||||
|
^ self downloadLinks keys
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #utilities }
|
||||||
|
BreaTheme class >> downloadLinks [
|
||||||
|
"Keys are the theme names and values are the url where it can be downloaded
|
||||||
|
as a zip file.
|
||||||
|
For the moment we work only with HTML5Up themes, but more could be added
|
||||||
|
and the code should be refactored accordingly."
|
||||||
|
| result providerUrl |
|
||||||
|
result := Dictionary new.
|
||||||
|
providerUrl := 'https://html5up.net'.
|
||||||
|
result
|
||||||
|
at: 'Paradigm Shift' put: providerUrl, '/paradigm-shift/download';
|
||||||
|
at: 'Massively' put: providerUrl, '/massively/download';
|
||||||
|
at: 'Ethereal' put: providerUrl, '/ethereal/download';
|
||||||
|
at: 'Story' put: providerUrl, '/story/download';
|
||||||
|
at: 'Dimension' put: providerUrl, '/dimension/download';
|
||||||
|
at: 'Editorial' put: providerUrl, '/editorial/download';
|
||||||
|
at: 'Forty' put: providerUrl, '/forty/download';
|
||||||
|
at: 'Stellar' put: providerUrl, '/stellar/download';
|
||||||
|
at: 'Multiverse' put: providerUrl, '/multiverse/download';
|
||||||
|
at: 'Phantom' put: providerUrl, '/phantom/download';
|
||||||
|
at: 'Hyperspace' put: providerUrl, '/hyperspace/download';
|
||||||
|
at: 'Future Imperfect' put: providerUrl, '/future-imperfect/download';
|
||||||
|
at: 'Solid State' put: providerUrl, '/solid-state/download';
|
||||||
|
at: 'Identity' put: providerUrl, '/identity/download';
|
||||||
|
at: 'Lens' put: providerUrl, '/lens/download';
|
||||||
|
at: 'Fractal' put: providerUrl, '/fractal/download';
|
||||||
|
at: 'Eventually' put: providerUrl, '/eventually/download';
|
||||||
|
at: 'Spectral' put: providerUrl, '/spectral/download';
|
||||||
|
at: 'Phonon' put: providerUrl, '/photon/download';
|
||||||
|
at: 'Highlights' put: providerUrl, '/highlights/download';
|
||||||
|
at: 'Landed' put: providerUrl, '/landed/download';
|
||||||
|
at: 'Strata' put: providerUrl, '/strata/download';
|
||||||
|
at: 'Read Only' put: providerUrl, '/read-only/download';
|
||||||
|
at: 'Alpha' put: providerUrl, '/alpha/download';
|
||||||
|
at: 'Directive' put: providerUrl, '/directive/download';
|
||||||
|
at: 'Aerial' put: providerUrl, '/aerial/download';
|
||||||
|
at: 'Twenty' put: providerUrl, '/twenty/download';
|
||||||
|
at: 'Big Picture' put: providerUrl, '/big-picture/download';
|
||||||
|
at: 'Tessellate' put: providerUrl, '/tessellate/download';
|
||||||
|
at: 'Overflow' put: providerUrl, 'overflow/download';
|
||||||
|
at: 'Prologue' put: providerUrl, '/prologue/download';
|
||||||
|
at: 'Helios' put: providerUrl, '/helios/download';
|
||||||
|
at: 'Telephasic' put: providerUrl, '/telephasic/download';
|
||||||
|
at: 'Strongly Typed' put: providerUrl, '/strongly-typed/download';
|
||||||
|
at: 'Parallelism' put: providerUrl, '/parallelism/download';
|
||||||
|
at: 'Escape Velocity' put: providerUrl, '/escape-velocity/download';
|
||||||
|
at: 'Astral' put: providerUrl, '/astral/download';
|
||||||
|
at: 'Striped' put: providerUrl, '/striped/download';
|
||||||
|
at: 'Dopetrope' put: providerUrl, '/dopetrope/download';
|
||||||
|
at: 'Miniport' put: providerUrl, '/miniport/download';
|
||||||
|
at: 'TXT' put: providerUrl, '/txt/download';
|
||||||
|
at: 'Verti' put: providerUrl, '/verti/download';
|
||||||
|
at: 'Zerofour' put: providerUrl, '/zerofour/download';
|
||||||
|
at: 'Arcana' put: providerUrl, '/arcana/download';
|
||||||
|
at: 'Halcyonic' put: providerUrl, '/halcyonic/download';
|
||||||
|
at: 'Minimaxing' put: providerUrl, '/minimaxing/download'.
|
||||||
|
^ result
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #operation }
|
||||||
|
BreaTheme >> addOperator: aBreaQuery [
|
||||||
|
self operators add: aBreaQuery cleanInputs
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #operation }
|
||||||
|
BreaTheme >> asSton [
|
||||||
|
^ STON toStringPretty: self
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #utilities }
|
||||||
|
BreaTheme >> dashedName [
|
||||||
|
^ self name asDashedLowercase
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #operation }
|
||||||
|
BreaTheme >> downloadInto: aFolder [
|
||||||
|
| tempName zippedFile |
|
||||||
|
self url ifNil: [ ^ self ].
|
||||||
|
tempName := self name.
|
||||||
|
zippedFile := aFolder / self dashedName , 'zip'.
|
||||||
|
aFolder ensureCreateDirectory.
|
||||||
|
GrafoscopioUtils
|
||||||
|
downloadingFrom: self url withMessage: 'Downloading ', tempName, '...' into: zippedFile.
|
||||||
|
self folder: aFolder.
|
||||||
|
^ zippedFile
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaTheme >> folder [
|
||||||
|
^ folder
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaTheme >> folder: anObject [
|
||||||
|
folder := anObject
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #installation }
|
||||||
|
BreaTheme >> installInto: aFolder [
|
||||||
|
| zippedFile |
|
||||||
|
self url ifNil: [ ^ self ].
|
||||||
|
zippedFile := FileLocator temp / 'download'.
|
||||||
|
zippedFile ensureDelete.
|
||||||
|
ZnClient new
|
||||||
|
url: self url;
|
||||||
|
downloadTo: FileLocator temp.
|
||||||
|
(ZipArchive new readFrom: zippedFile) extractAllTo: aFolder.
|
||||||
|
self folder: aFolder.
|
||||||
|
^ aFolder
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaTheme >> license [
|
||||||
|
^ license
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaTheme >> license: anObject [
|
||||||
|
license := anObject
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #operation }
|
||||||
|
BreaTheme >> loadConfiguration [
|
||||||
|
| config |
|
||||||
|
config := self folder / 'brea.yaml'.
|
||||||
|
config exists
|
||||||
|
ifTrue: [ ^ PPYAMLGrammar new parse: config contents ]
|
||||||
|
ifFalse: [ self inform:
|
||||||
|
'No configuration file found. A "brea.yaml" file should be located in the theme root folder.
|
||||||
|
please run "#updateCustomizations" after defining a theme name from the
|
||||||
|
"BreaTheme availablePacks".
|
||||||
|
If no configuration is defined for such theme name you can create and empty configuration
|
||||||
|
file by running "#createBaseConfiguration" and filing out the "brea.yaml" fields.
|
||||||
|
For more information or help ask at https://t.me/grafoscopio .' ]
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaTheme >> name [
|
||||||
|
^ name ifNil: [ name = 'unamed' ]
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaTheme >> name: anObject [
|
||||||
|
name := anObject
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaTheme >> operators [
|
||||||
|
^ operators ifNil: [ operators := OrderedCollection new ]
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaTheme >> operators: cleanedBreaQueriesCollection [
|
||||||
|
operators := cleanedBreaQueriesCollection
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaTheme >> preview [
|
||||||
|
^ preview
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaTheme >> preview: anObject [
|
||||||
|
preview := anObject
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaTheme >> provider [
|
||||||
|
^ provider
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaTheme >> provider: anObject [
|
||||||
|
provider := anObject
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaTheme >> url [
|
||||||
|
^ url ifNil: [ url := self class downloadLinks at: self name. ]
|
||||||
|
]
|
||||||
|
|
||||||
|
{ #category : #accessing }
|
||||||
|
BreaTheme >> url: anObject [
|
||||||
|
url := anObject
|
||||||
|
]
|
22
repository/Brea/BreaUtils.class.st
Normal file
22
repository/Brea/BreaUtils.class.st
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
"
|
||||||
|
I provide common utilities for the use with the Brea CMS.
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #BreaUtils,
|
||||||
|
#superclass : #Object,
|
||||||
|
#category : #Brea
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #'as yet unclassified' }
|
||||||
|
BreaUtils class >> installSkeleton [
|
||||||
|
"I populate the folder and files structures for Brea documentation and customizations."
|
||||||
|
| skeleton destination |
|
||||||
|
GrafoscopioUtils
|
||||||
|
downloadingFrom: 'https://mutabit.com/repos.fossil/brea/zip'
|
||||||
|
withMessage: 'Dowloading files skeleton'
|
||||||
|
into: FileLocator temp.
|
||||||
|
skeleton := ZipArchive new readFrom: FileLocator temp / 'zip'.
|
||||||
|
destination := FileLocator home / '.local/share/Brea'.
|
||||||
|
destination ensureCreateDirectory.
|
||||||
|
skeleton extractAllTo: destination.
|
||||||
|
]
|
@ -1,54 +0,0 @@
|
|||||||
"
|
|
||||||
I store the common forms of web presence a BreaMember can have online.
|
|
||||||
"
|
|
||||||
Class {
|
|
||||||
#name : #BreaWebPresence,
|
|
||||||
#superclass : #Object,
|
|
||||||
#instVars : [
|
|
||||||
'website',
|
|
||||||
'twitter',
|
|
||||||
'facebook',
|
|
||||||
'instagram'
|
|
||||||
],
|
|
||||||
#category : #Brea
|
|
||||||
}
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWebPresence >> facebook [
|
|
||||||
^ facebook
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWebPresence >> facebook: anObject [
|
|
||||||
facebook := anObject
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWebPresence >> instagram [
|
|
||||||
^ instagram
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWebPresence >> instagram: anObject [
|
|
||||||
instagram := anObject
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWebPresence >> twitter [
|
|
||||||
^ twitter
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWebPresence >> twitter: anObject [
|
|
||||||
twitter := anObject
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWebPresence >> website [
|
|
||||||
^ website
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWebPresence >> website: anObject [
|
|
||||||
website := anObject
|
|
||||||
]
|
|
@ -1,292 +0,0 @@
|
|||||||
"
|
|
||||||
I model the fossil repository where public data is stored for the
|
|
||||||
building of this web site.
|
|
||||||
"
|
|
||||||
Class {
|
|
||||||
#name : #BreaWebsite,
|
|
||||||
#superclass : #Object,
|
|
||||||
#instVars : [
|
|
||||||
'fossilRepo',
|
|
||||||
'server',
|
|
||||||
'template',
|
|
||||||
'title'
|
|
||||||
],
|
|
||||||
#category : #Brea
|
|
||||||
}
|
|
||||||
|
|
||||||
{ #category : #utility }
|
|
||||||
BreaWebsite class >> availableTemplates [
|
|
||||||
self templates keys.
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #utility }
|
|
||||||
BreaWebsite class >> demoFolder [
|
|
||||||
^ FileLocator temp asFileReference / 'BreaDemo'.
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #example }
|
|
||||||
BreaWebsite class >> example [
|
|
||||||
"I run an example mockup of a website using Brea.
|
|
||||||
After runing me, go to:
|
|
||||||
- http://localhost:8080/demo
|
|
||||||
- http://localhost:8080/members/test
|
|
||||||
- http://localhost:8080/members/add "
|
|
||||||
self new
|
|
||||||
local: FileLocator temp asFileReference / 'BreaDemo';
|
|
||||||
template: 'portafolio';
|
|
||||||
downloadTemplate;
|
|
||||||
modifyTemplate;
|
|
||||||
start
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #example }
|
|
||||||
BreaWebsite class >> exampleDashboard [
|
|
||||||
"I run an example mockup of a website using Brea.
|
|
||||||
After runing me, go to: http://localhost:8080/demo "
|
|
||||||
self new
|
|
||||||
local: FileLocator temp asFileReference / 'BreaDemo';
|
|
||||||
template: 'dashboard';
|
|
||||||
downloadTemplate;
|
|
||||||
modifyTemplate;
|
|
||||||
start
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #'server handling' }
|
|
||||||
BreaWebsite class >> stopAll [
|
|
||||||
"I stop the server"
|
|
||||||
Teapot stopAll
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #utility }
|
|
||||||
BreaWebsite class >> templates [
|
|
||||||
"I provide the supported MDL templates taken from: https://getmdl.io/templates/"
|
|
||||||
^ Dictionary new
|
|
||||||
at: 'portafolio' put: 'https://code.getmdl.io/1.3.0/mdl-template-portfolio.zip';
|
|
||||||
at: 'dashboard' put: 'https://code.getmdl.io/1.3.0/mdl-template-dashboard.zip';
|
|
||||||
yourself.
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #utility }
|
|
||||||
BreaWebsite >> defaultTemplate [
|
|
||||||
self template
|
|
||||||
ifNil: [
|
|
||||||
self template: 'portafolio' ].
|
|
||||||
^ self template.
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #utility }
|
|
||||||
BreaWebsite >> downloadDefaultTemplate [
|
|
||||||
self downloadTemplateNamed: self defaultTemplate Into: self local.
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #utility }
|
|
||||||
BreaWebsite >> downloadDefaultTemplateInto: aDirectory [
|
|
||||||
| remoteUrl templatesFile |
|
|
||||||
aDirectory ensureDeleteAll.
|
|
||||||
aDirectory ensureCreateDirectory.
|
|
||||||
remoteUrl := self class templates at: self template.
|
|
||||||
GrafoscopioUtils
|
|
||||||
downloadingFrom: remoteUrl
|
|
||||||
withMessage: 'Downloading templates'
|
|
||||||
into: FileLocator temp asFileReference.
|
|
||||||
templatesFile := FileLocator temp asFileReference / (remoteUrl splitOn: '/') last.
|
|
||||||
ZipArchive new
|
|
||||||
readFrom: templatesFile;
|
|
||||||
extractAllTo: aDirectory
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #utility }
|
|
||||||
BreaWebsite >> downloadTemplate [
|
|
||||||
self downloadTemplateNamed: self template Into: self local.
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #utility }
|
|
||||||
BreaWebsite >> downloadTemplateNamed: aName Into: aDirectory [
|
|
||||||
"aName: String aDirectory: aFileLocation"
|
|
||||||
| remoteUrl templatesFile localDirectory |
|
|
||||||
localDirectory := aDirectory asFileReference.
|
|
||||||
localDirectory ensureDeleteAll.
|
|
||||||
localDirectory ensureCreateDirectory.
|
|
||||||
remoteUrl := self class templates at: aName.
|
|
||||||
GrafoscopioUtils
|
|
||||||
downloadingFrom: remoteUrl
|
|
||||||
withMessage: 'Downloading templates'
|
|
||||||
into: FileLocator temp asFileReference.
|
|
||||||
templatesFile := FileLocator temp asFileReference / (remoteUrl splitOn: '/') last.
|
|
||||||
ZipArchive new
|
|
||||||
readFrom: templatesFile;
|
|
||||||
extractAllTo: localDirectory
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWebsite >> fossilRepo [
|
|
||||||
^ fossilRepo ifNil: [ fossilRepo := FossilRepo new ]
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWebsite >> fossilRepo: aFossilRepo [
|
|
||||||
fossilRepo := aFossilRepo
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #utility }
|
|
||||||
BreaWebsite >> local [
|
|
||||||
^ self fossilRepo local
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #'server handling' }
|
|
||||||
BreaWebsite >> local: aFilePath [
|
|
||||||
"I define the local storage of the Fossil repository.
|
|
||||||
For the moment aFilePath must be an absolute "
|
|
||||||
| localSite |
|
|
||||||
aFilePath asFileReference exists
|
|
||||||
ifFalse: [
|
|
||||||
localSite := (FileLocator temp / 'breaSite') ensureCreateDirectory.
|
|
||||||
self fossilRepo local: localSite fullName ]
|
|
||||||
ifTrue: [ self fossilRepo local: aFilePath ].
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #'server handling' }
|
|
||||||
BreaWebsite >> local: aFilePath remote: anUrl [
|
|
||||||
"I define the local and remote storages of the Fossil repository"
|
|
||||||
self remote: anUrl.
|
|
||||||
self local: aFilePath
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #utility }
|
|
||||||
BreaWebsite >> modifyDashboardTemplate [
|
|
||||||
"I replace default templates with versioned files, that contains Mustache tags used
|
|
||||||
for examples."
|
|
||||||
"This part should be factorized and integrated into a single method tha modifies any
|
|
||||||
template, instead of repeated the code of modifyPortafolioTemplate."
|
|
||||||
| remoteRepoUrl files |
|
|
||||||
remoteRepoUrl := 'http://mutabit.com/repos.fossil/brea/templates/portaforlio'.
|
|
||||||
files := #('index.html' 'styles.css').
|
|
||||||
"files do: [ :file |
|
|
||||||
GrafoscopioUtils
|
|
||||||
downloadingFrom: remoteRepoUrl, 'doc/tip/', file
|
|
||||||
withMessage: 'Replacing ', file
|
|
||||||
into: self local ]"
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #utility }
|
|
||||||
BreaWebsite >> modifyPortafolioTemplate [
|
|
||||||
"I replace default templates with versioned files, that contains Mustache tags used
|
|
||||||
for examples."
|
|
||||||
| remoteRepoUrl files |
|
|
||||||
remoteRepoUrl := 'http://mutabit.com/repos.fossil/gig/'.
|
|
||||||
files := #('index.html' 'styles.css').
|
|
||||||
files do: [ :file |
|
|
||||||
GrafoscopioUtils
|
|
||||||
downloadingFrom: remoteRepoUrl, 'doc/tip/', file
|
|
||||||
withMessage: 'Replacing ', file
|
|
||||||
into: self local ]
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #utility }
|
|
||||||
BreaWebsite >> modifyTemplate [
|
|
||||||
"I replace default templates with versioned files, that contains Mustache tags used
|
|
||||||
for examples."
|
|
||||||
self template = 'portafolio' ifTrue: [ self modifyPortafolioTemplate ].
|
|
||||||
self template = 'dashboard' ifTrue: [ self modifyDashboardTemplate ]
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #'input processing' }
|
|
||||||
BreaWebsite >> processNewMember: request [
|
|
||||||
| member badRequest |
|
|
||||||
badRequest := [ ^ ZnResponse badRequest: request ].
|
|
||||||
(request hasEntity
|
|
||||||
and: [ request contentType matches: ZnMimeType applicationFormUrlEncoded ])
|
|
||||||
ifFalse: [ badRequest ].
|
|
||||||
member := BreaMember new
|
|
||||||
givenName: (request at: #givenName);
|
|
||||||
familyName: (request at: #familyName);
|
|
||||||
email: (request at: #email);
|
|
||||||
country: (request at: #country);
|
|
||||||
organizations: (request at: #organizations);
|
|
||||||
picture: (request at: #picture);
|
|
||||||
website: (request at: #website);
|
|
||||||
twitter: (request at: #twitter);
|
|
||||||
facebook: (request at: #facebook);
|
|
||||||
tags: (request at: #tags).
|
|
||||||
self store: member.
|
|
||||||
^ 'New member stored!'
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #'server handling' }
|
|
||||||
BreaWebsite >> remote: anUrl [
|
|
||||||
"I define the remote storage of the Fossil repository"
|
|
||||||
self remote: anUrl.
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #'server handling' }
|
|
||||||
BreaWebsite >> routes [
|
|
||||||
"I define how the website behaves accordingly to particular routes."
|
|
||||||
self server
|
|
||||||
serveStatic: 'demo' from: (self local);
|
|
||||||
GET: 'members/test' -> [ :req | BreaMember new renderTestUserAsHtml ];
|
|
||||||
GET: 'members/add' -> [ :req | BreaMember new htmlInput ];
|
|
||||||
POST: 'members/summit' -> [ :req | self processNewMember: req ]
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWebsite >> server [
|
|
||||||
^ server ifNil: [ self setup ]
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWebsite >> server: anObject [
|
|
||||||
server := anObject
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWebsite >> setup [
|
|
||||||
^ server := Teapot
|
|
||||||
configure:
|
|
||||||
{(#port -> 8080).
|
|
||||||
(#debugMode -> true)}
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #'server handling' }
|
|
||||||
BreaWebsite >> start [
|
|
||||||
"I define the config and start the server"
|
|
||||||
self routes.
|
|
||||||
self server start
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #'server handling' }
|
|
||||||
BreaWebsite >> storageFor: anObject [
|
|
||||||
"I define the places where local storage is done for several types of objects"
|
|
||||||
anObject class = BreaMember
|
|
||||||
ifTrue: [ ^ self local asFileReference / 'members' ].
|
|
||||||
^ self
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #'server handling' }
|
|
||||||
BreaWebsite >> store: anObject [
|
|
||||||
"I store different kind of objects in the website repository.
|
|
||||||
For the moment I will only store BreaMembers, but as long as new
|
|
||||||
objects will emerge, I will specialize other ways of storage."
|
|
||||||
anObject storeInto: (self storageFor: anObject)
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWebsite >> template [
|
|
||||||
^ template
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWebsite >> template: aTemplateName [
|
|
||||||
"I define the default template to be used for the Brea website.
|
|
||||||
Available options are at self class templates."
|
|
||||||
template := aTemplateName
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWebsite >> title [
|
|
||||||
^ title
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWebsite >> title: anObject [
|
|
||||||
title := anObject
|
|
||||||
]
|
|
@ -1,149 +0,0 @@
|
|||||||
"
|
|
||||||
I model a wiki page of a Brea site.
|
|
||||||
"
|
|
||||||
Class {
|
|
||||||
#name : #BreaWikiPage,
|
|
||||||
#superclass : #Object,
|
|
||||||
#instVars : [
|
|
||||||
'shortName',
|
|
||||||
'template',
|
|
||||||
'templateData',
|
|
||||||
'namespace',
|
|
||||||
'bodyTag'
|
|
||||||
],
|
|
||||||
#category : #Brea
|
|
||||||
}
|
|
||||||
|
|
||||||
{ #category : #operation }
|
|
||||||
BreaWikiPage >> bodyContentsAsHTML [
|
|
||||||
| sourcePage |
|
|
||||||
self markdownFile ifNil: [ ^ self ].
|
|
||||||
sourcePage := FileLocator temp / 'wikiPage.md'.
|
|
||||||
MarkupFile exportAsFileOn: sourcePage containing: self markdownFile contents.
|
|
||||||
^ Pandoc markdownToHtml: sourcePage
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWikiPage >> bodyTag [
|
|
||||||
^ bodyTag
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWikiPage >> bodyTag: aString [
|
|
||||||
"I represent the Mustache Template tag used to denote the body part of a page.
|
|
||||||
While the metadata is self describing via YAML metadata blocks in Markddown, so
|
|
||||||
they map where ever they are needed in a template, the Markdown file that will be converted
|
|
||||||
in HTML via a template doesn't know which part should occupy once the conversion is done.
|
|
||||||
I provide such knowledge. So if a page template puts the body content under the mustache tag
|
|
||||||
{{content}}, I should use bodyTag: 'content'.
|
|
||||||
bodyTag: is template dependant."
|
|
||||||
bodyTag := aString
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #'as yet unclassified' }
|
|
||||||
BreaWikiPage >> exportAsHTML [
|
|
||||||
| htmlContents allActions semaphore result |
|
|
||||||
self shortName ifNil: [ ^ self ].
|
|
||||||
self template ifNil: [ ^ self ].
|
|
||||||
self bodyTag ifNil: [ ^ self ].
|
|
||||||
allActions := TKTFuture all: {
|
|
||||||
[ self populateMetadata ] future.
|
|
||||||
[ self populateBodyAs: self bodyTag ] future.
|
|
||||||
}.
|
|
||||||
semaphore := Semaphore new.
|
|
||||||
allActions onSuccessDo: [ :values |
|
|
||||||
result := values last.
|
|
||||||
semaphore signal.
|
|
||||||
].
|
|
||||||
semaphore wait.
|
|
||||||
htmlContents := (MustacheTemplate on: result templateFile contents) value: result templateData.
|
|
||||||
^ MarkupFile exportAsFileOn: self namespace / (self shortName, '.html' ) containing: htmlContents
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #'as yet unclassified' }
|
|
||||||
BreaWikiPage >> htmlContents [
|
|
||||||
self shortName ifNil: [ ^ self ].
|
|
||||||
self template ifNil: [ ^ self ].
|
|
||||||
^ (MustacheTemplate on: self templateFile contents) value: self templateData.
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #operation }
|
|
||||||
BreaWikiPage >> markdownFile [
|
|
||||||
| localFile |
|
|
||||||
self namespace ifNil: [ ^ self ].
|
|
||||||
self shortName ifNil: [ ^ self ].
|
|
||||||
localFile := self namespace / (self shortName, '.md').
|
|
||||||
localFile exists ifFalse: [ ^ self ].
|
|
||||||
^ Markdown fromFile: localFile
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWikiPage >> namespace [
|
|
||||||
^ namespace
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWikiPage >> namespace: folderFileReference [
|
|
||||||
namespace := folderFileReference
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #'as yet unclassified' }
|
|
||||||
BreaWikiPage >> populateBodyAs: key [
|
|
||||||
| allActions result semaphore |
|
|
||||||
allActions := TKTFuture all: {
|
|
||||||
[ self bodyContentsAsHTML ] future.
|
|
||||||
}.
|
|
||||||
semaphore := Semaphore new.
|
|
||||||
allActions onSuccessDo: [ :values |
|
|
||||||
result := values last.
|
|
||||||
semaphore signal ].
|
|
||||||
semaphore wait.
|
|
||||||
self templateData at: key put: result contents.
|
|
||||||
^ self.
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #operation }
|
|
||||||
BreaWikiPage >> populateMetadata [
|
|
||||||
self markdownFile metadata keysAndValuesDo: [ :key :value |
|
|
||||||
self templateData at: key put: value
|
|
||||||
].
|
|
||||||
^ templateData
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWikiPage >> shortName [
|
|
||||||
^ shortName
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWikiPage >> shortName: aString [
|
|
||||||
shortName := aString
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWikiPage >> template [
|
|
||||||
^ template
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWikiPage >> template: mustacheFileName [
|
|
||||||
"Usually templates and their pages are located in the same folder."
|
|
||||||
template := mustacheFileName
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWikiPage >> templateData [
|
|
||||||
^ templateData ifNil: [ templateData := Dictionary new ]
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #accessing }
|
|
||||||
BreaWikiPage >> templateData: aDictionary [
|
|
||||||
templateData := aDictionary
|
|
||||||
]
|
|
||||||
|
|
||||||
{ #category : #'as yet unclassified' }
|
|
||||||
BreaWikiPage >> templateFile [
|
|
||||||
self namespace ifNil: [ ^ self ].
|
|
||||||
self template ifNil: [ ^ self ].
|
|
||||||
^ self namespace / self template
|
|
||||||
]
|
|
13
repository/Brea/ManifestBrea.class.st
Normal file
13
repository/Brea/ManifestBrea.class.st
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
"
|
||||||
|
I store metadata for this package. These meta data are used by other tools such as the SmalllintManifestChecker and the critics Browser
|
||||||
|
"
|
||||||
|
Class {
|
||||||
|
#name : #ManifestBrea,
|
||||||
|
#superclass : #PackageManifest,
|
||||||
|
#category : #'Brea-Manifest'
|
||||||
|
}
|
||||||
|
|
||||||
|
{ #category : #'code-critics' }
|
||||||
|
ManifestBrea class >> ruleRBStringConcatenationRuleV1FalsePositive [
|
||||||
|
^ #(#(#(#RGMethodDefinition #(#BreaPage #contents #false)) #'2020-08-28T20:08:20.291489-05:00') #(#(#RGMethodDefinition #(#BreaFile #fromShortName:andFolder: #false)) #'2020-11-06T20:59:12.94748-05:00') #(#(#RGMethodDefinition #(#'BreaFile class' #fromShortName:andFolder: #true)) #'2020-11-06T21:02:25.564981-05:00') )
|
||||||
|
]
|
6
repository/Brea/String.extension.st
Normal file
6
repository/Brea/String.extension.st
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
Extension { #name : #String }
|
||||||
|
|
||||||
|
{ #category : #'*Brea' }
|
||||||
|
String >> webView [
|
||||||
|
^ (Pandoc htmlStringToMarkdown: self) accentedCharactersCorrection
|
||||||
|
]
|
6
repository/Brea/Teapot.extension.st
Normal file
6
repository/Brea/Teapot.extension.st
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
Extension { #name : #Teapot }
|
||||||
|
|
||||||
|
{ #category : #'*Brea' }
|
||||||
|
Teapot >> dynamicRoutes [
|
||||||
|
^ dynamicRouter routes
|
||||||
|
]
|
Loading…
Reference in New Issue
Block a user