Improving Windows support. #2

Merged
Offray merged 2 commits from Windows into master 2020-12-18 18:54:40 +00:00
14 changed files with 698 additions and 1674 deletions
Showing only changes of commit 1044fb4997 - Show all commits

View File

@ -1,118 +1,118 @@
" "
I model information of the items published on Internet Archive (https://archive.org/). I model information of the items published on Internet Archive (https://archive.org/).
" "
Class { Class {
#name : #ArchiveOrgItem, #name : #ArchiveOrgItem,
#superclass : #Object, #superclass : #Object,
#instVars : [ #instVars : [
'id', 'id',
'metadata' 'metadata'
], ],
#category : #Brea #category : #Brea
} }
{ #category : #utility } { #category : #utility }
ArchiveOrgItem >> archive [ ArchiveOrgItem >> archive [
^ 'https://archive.org' ^ 'https://archive.org'
] ]
{ #category : #utilities } { #category : #utilities }
ArchiveOrgItem >> createHtmlImageGalleryList [ ArchiveOrgItem >> createHtmlImageGalleryList [
"IMPORTANT: This is just a draft snipped. Should become a proper test o be deleted." "IMPORTANT: This is just a draft snipped. Should become a proper test o be deleted."
self metadata ifNil: [ self getMetadata ]. self metadata ifNil: [ self getMetadata ].
^ ' ^ '
<div id="nanogallery2" <div id="nanogallery2"
/* gallery settings */ /* gallery settings */
data-nanogallery2 = ''{ data-nanogallery2 = ''{
"thumbnailHeight": 150, "thumbnailHeight": 150,
"thumbnailWidth": 150, "thumbnailWidth": 150,
"itemsBaseURL": "', self galleryItemsBaseUrl ,'" "itemsBaseURL": "', self galleryItemsBaseUrl ,'"
}'' > }'' >
<!-- gallery content --> <!-- gallery content -->
<a href = "primera 3.jpg" data-ngThumb = "primera 3_thumb.jpg" > </a> <a href = "primera 3.jpg" data-ngThumb = "primera 3_thumb.jpg" > </a>
<a href = "segunda.jpg" data-ngThumb = "segunda_thumb.jpg" > </a> <a href = "segunda.jpg" data-ngThumb = "segunda_thumb.jpg" > </a>
</div>' </div>'
] ]
{ #category : #utilities } { #category : #utilities }
ArchiveOrgItem >> embeddedUrl [ ArchiveOrgItem >> embeddedUrl [
^ 'https://archive.org/embed/', self id. ^ 'https://archive.org/embed/', self id.
] ]
{ #category : #utilities } { #category : #utilities }
ArchiveOrgItem >> galleryItemsBaseUrl [ ArchiveOrgItem >> galleryItemsBaseUrl [
"I create the place where all image would be located for creating a custom image gallery, "I create the place where all image would be located for creating a custom image gallery,
according with the requirements for nanogallery2." according with the requirements for nanogallery2."
^ 'https://', (self metadata at: 'd2'), (self metadata at: 'dir'), '/'. ^ 'https://', (self metadata at: 'd2'), (self metadata at: 'dir'), '/'.
] ]
{ #category : #operation } { #category : #operation }
ArchiveOrgItem >> getMetadata [ ArchiveOrgItem >> getMetadata [
self id ifNil: [ ^ self ]. self id ifNil: [ ^ self ].
self metadata: (NeoJSONReader fromString: (self archive, '/metadata/', self id) asUrl retrieveContents) self metadata: (NeoJSONReader fromString: (self archive, '/metadata/', self id) asUrl retrieveContents)
] ]
{ #category : #accessing } { #category : #accessing }
ArchiveOrgItem >> id [ ArchiveOrgItem >> id [
^ id ^ id
] ]
{ #category : #accessing } { #category : #accessing }
ArchiveOrgItem >> id: anObject [ ArchiveOrgItem >> id: anObject [
id := anObject id := anObject
] ]
{ #category : #utilities } { #category : #utilities }
ArchiveOrgItem >> imagesGalleryList [ ArchiveOrgItem >> imagesGalleryList [
self metadata ifNil: [ self getMetadata ]. self metadata ifNil: [ self getMetadata ].
^ (self metadata at: 'files') select: [ :file | (file at: 'format') = 'JPEG Thumb' ] ^ (self metadata at: 'files') select: [ :file | (file at: 'format') = 'JPEG Thumb' ]
] ]
{ #category : #utilities } { #category : #utilities }
ArchiveOrgItem >> imagesGalleryListAsDictionary [ ArchiveOrgItem >> imagesGalleryListAsDictionary [
| galleryImages result | | galleryImages result |
self imagesGalleryList ifNil: [ ^ self ]. self imagesGalleryList ifNil: [ ^ self ].
galleryImages := OrderedCollection new. galleryImages := OrderedCollection new.
self imagesGalleryList do: [ :imgMetadata | self imagesGalleryList do: [ :imgMetadata |
galleryImages galleryImages
add: (Dictionary new add: (Dictionary new
at: 'imgOriginal' put: (imgMetadata at: 'original'); at: 'imgOriginal' put: (imgMetadata at: 'original');
at: 'imgThumb' put: (imgMetadata at: 'name'); at: 'imgThumb' put: (imgMetadata at: 'name');
yourself) ]. yourself) ].
result := { 'archiveItemImages' -> galleryImages } asDictionary. result := { 'archiveItemImages' -> galleryImages } asDictionary.
^ result ^ result
] ]
{ #category : #accessing } { #category : #accessing }
ArchiveOrgItem >> metadata [ ArchiveOrgItem >> metadata [
^ metadata ^ metadata
] ]
{ #category : #accessing } { #category : #accessing }
ArchiveOrgItem >> metadata: anObject [ ArchiveOrgItem >> metadata: anObject [
metadata := anObject metadata := anObject
] ]
{ #category : #utilities } { #category : #utilities }
ArchiveOrgItem >> subjectTags [ ArchiveOrgItem >> subjectTags [
self id ifNil: [ ^ self ]. self id ifNil: [ ^ self ].
self metadata ifNil: [ self getMetadata ]. self metadata ifNil: [ self getMetadata ].
^ (self metadata at: 'metadata') at: 'subject' ^ (self metadata at: 'metadata') at: 'subject'
] ]
{ #category : #utilities } { #category : #utilities }
ArchiveOrgItem >> subjectTagsAsDictionary [ ArchiveOrgItem >> subjectTagsAsDictionary [
| tagList result | | tagList result |
self imagesGalleryList ifNil: [ ^ self ]. self imagesGalleryList ifNil: [ ^ self ].
tagList := OrderedCollection new. tagList := OrderedCollection new.
self subjectTags do: [ :tag | self subjectTags do: [ :tag |
tagList tagList
add: (Dictionary new add: (Dictionary new
at: 'tag' put: tag; at: 'tag' put: tag;
yourself) ]. yourself) ].
result := { 'tagList' -> tagList } asDictionary. result := { 'tagList' -> tagList } asDictionary.
^ result ^ result
] ]

View File

@ -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
]

View File

@ -1,71 +1,78 @@
" "
I model the file where contents (data and/or metadata) for the Brea CSM pages are stored. I model the file where contents (data and/or metadata) for the Brea CSM pages are stored.
" "
Class { Class {
#name : #BreaFile, #name : #BreaFile,
#superclass : #Object, #superclass : #Object,
#instVars : [ #instVars : [
'folder', 'folder',
'name' 'name'
], ],
#category : #Brea #category : #Brea
} }
{ #category : #'instance creation' } { #category : #'instance creation' }
BreaFile class >> fromShortName: nameString andFolder: aFileLocation [ BreaFile class >> fromShortName: nameString andFolder: aFileLocation [
"I create a new BreaFile assigning priorities to the filename discovery according to "I create a new BreaFile assigning priorities to the filename discovery according to
their extension currently present in a particular folder." their extension currently present in a particular folder."
| extensions | | extensions |
extensions := #('md' 'json' 'yaml'). extensions := #('md' 'json' 'yaml').
extensions do: [ :ext | | markupFile filename | extensions do: [ :ext | | markupFile filename |
filename := nameString, '.', ext. filename := nameString, '.', ext.
markupFile := aFileLocation / filename. markupFile := aFileLocation / filename.
markupFile exists ifTrue: [ ^ self new name: filename; folder: aFileLocation ]. markupFile exists ifTrue: [ ^ self new name: filename; folder: aFileLocation ].
]. ].
^ nil. ^ nil.
] ]
{ #category : #accessing } { #category : #accessing }
BreaFile >> contentString [ BreaFile >> contentString [
self name ifNil: [ ^ nil ]. self name ifNil: [ ^ nil ].
(self name endsWith: '.md') ifTrue: [ ^ self contents contents ]. (self name endsWith: '.md') ifTrue: [ ^ self contents contents ].
(self name endsWith: '.json') ifTrue: [ ^ self contents asString ]. (self name endsWith: '.json') ifTrue: [ ^ self contents asString ].
] ]
{ #category : #accessing } { #category : #accessing }
BreaFile >> contents [ BreaFile >> contents [
| file | | file |
self name ifNil: [ ^ nil ]. self name ifNil: [ ^ nil ].
file := self folder / self name. file := self folder / self name.
(self name endsWith: '.md') ifTrue: [ ^ Markdown fromFile: file ]. (self name endsWith: '.md') ifTrue: [ ^ Markdown fromFile: file ].
(self name endsWith: '.json') ifTrue: [ ^ NeoJSONObject fromString: file contents ] (self name endsWith: '.json') ifTrue: [ ^ NeoJSONObject fromString: file contents ]
] ]
{ #category : #accessing } { #category : #accessing }
BreaFile >> folder [ BreaFile >> file [
^ folder self folder ifNil: [ ^ self ].
] self name ifNil: [ ^ self ].
^ self folder / self name.
{ #category : #accessing } ]
BreaFile >> folder: anObject [
folder := anObject { #category : #accessing }
] BreaFile >> folder [
^ folder
{ #category : #accessing } ]
BreaFile >> metadata [
self name ifNil: [ ^ nil ]. { #category : #accessing }
(self name endsWith: '.md') ifTrue: [ ^ self contents metadata ]. BreaFile >> folder: anObject [
(self name endsWith: '.json') ifTrue: [ ^ self contents ]. folder := anObject
] ]
{ #category : #accessing } { #category : #accessing }
BreaFile >> name [ BreaFile >> metadata [
^ name self name ifNil: [ ^ nil ].
] (self name endsWith: '.md') ifTrue: [ ^ self contents metadata ].
(self name endsWith: '.json') ifTrue: [ ^ self contents asDictionary ].
{ #category : #accessing } ]
BreaFile >> name: anObject [
name := anObject { #category : #accessing }
] BreaFile >> name [
^ name
]
{ #category : #accessing }
BreaFile >> name: anObject [
name := anObject
]

View File

@ -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&amp;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&amp;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
]

View File

@ -1,8 +0,0 @@
"
A BreaMemberTest is a test class for testing the behavior of BreaMember
"
Class {
#name : #BreaMemberTest,
#superclass : #TestCase,
#category : #'Brea-Tests'
}

View File

@ -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
]

View File

@ -1,250 +1,262 @@
" "
I model a wiki page of a Brea site. I model a wiki page of a Brea site.
I am modelled after common wiki pages, where a document in a light markup laguage 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 is converted in HTML and is expected to access document history (I am helped by
FossilRepo for that). FossilRepo for that).
I can be used for other types of publications, like blog post though. I can be used for other types of publications, like blog post though.
" "
Class { Class {
#name : #BreaPage, #name : #BreaPage,
#superclass : #Object, #superclass : #Object,
#instVars : [ #instVars : [
'shortName', 'shortName',
'template', 'template',
'templateData', 'templateData',
'bodyTag', 'bodyTag',
'splitters', 'splitters',
'subpages', 'subpages',
'metadata', 'metadata',
'folder', 'folder',
'file' 'file'
], ],
#category : #Brea #category : #Brea
} }
{ #category : #operation } { #category : #operation }
BreaPage >> bodyContentsAsHTML [ BreaPage >> bodyContentsAsHTML [
| sourcePage | | sourcePage |
self contentsFile ifNil: [ ^ self ]. self contentsFile ifNil: [ ^ self ].
sourcePage := FileLocator temp / 'wikiPage.md'. Smalltalk os isWindows ifTrue: [
MarkupFile exportAsFileOn: sourcePage containing: self contents. ^ Pandoc markdownToHtml: self file file
^ Pandoc markdownToHtml: sourcePage ].
] sourcePage := FileLocator temp / 'wikiPage.md'.
MarkupFile exportAsFileOn: sourcePage containing: self contents.
{ #category : #accessing } ^ Pandoc markdownToHtml: sourcePage
BreaPage >> bodyTag [ ]
^ bodyTag
] { #category : #accessing }
BreaPage >> bodyTag [
{ #category : #accessing } ^ bodyTag
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 { #category : #accessing }
they map where ever they are needed in a template, the Markdown file that will be converted BreaPage >> bodyTag: aString [
in HTML via a template doesn't know which part should occupy once the conversion is done. "I represent the Mustache Template tag used to denote the body part of a page.
I provide such knowledge. So if a page template puts the body content under the mustache tag While the metadata is self describing via YAML metadata blocks in Markddown, so
{{content}}, I should use bodyTag: 'content'. they map where ever they are needed in a template, the Markdown file that will be converted
bodyTag: is template dependant." in HTML via a template doesn't know which part should occupy once the conversion is done.
bodyTag := aString 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."
{ #category : #accessing } bodyTag := aString
BreaPage >> contents [ ]
| result |
self contentsFile ifNil: [ ^ nil ]. { #category : #accessing }
result := '' writeStream. BreaPage >> contents [
result nextPutAll: self contentsFile contentString. | result |
self subpages ifNotNil: [ self contentsFile ifNil: [ ^ nil ].
self subpages do: [ :sp | | markdownTempFile | result := '' writeStream.
markdownTempFile := self folder / (sp, '.md'). result nextPutAll: self contentsFile contentString.
result nextPutAll: (Markdown fromFile: markdownTempFile) contents. self subpages ifNotNil: [
] self subpages do: [ :sp | | markdownTempFile |
]. markdownTempFile := self folder / (sp, '.md').
^ result contents. result nextPutAll: (Markdown fromFile: markdownTempFile) contents.
] ]
].
{ #category : #operation } ^ result contents.
BreaPage >> contentsFile [ ]
self folder ifNil: [ ^ self ]. { #category : #operation }
self shortName ifNil: [ ^ self ]. BreaPage >> contentsFile [
^ BreaFile fromShortName: self shortName andFolder: self folder.
] self folder ifNil: [ ^ self ].
self shortName ifNil: [ ^ self ].
{ #category : #'as yet unclassified' } ^ BreaFile fromShortName: self shortName andFolder: self folder.
BreaPage >> exportAsHTML [ ]
| htmlContents allActions actionsArray semaphore result |
self shortName ifNil: [ ^ self ]. { #category : #'as yet unclassified' }
self template ifNil: [ ^ self ]. BreaPage >> exportAsHTML [
actionsArray := { [ self populateMetadata ] future. [ self split ] future. }. | htmlContents allActions actionsArray semaphore result |
self bodyTag ifNotNil: [ actionsArray := actionsArray copyWith: [ self populateBodyAs: self bodyTag ] future ]. self shortName ifNil: [ ^ self ].
allActions := TKTFuture all: actionsArray. self template ifNil: [ ^ self ].
semaphore := Semaphore new. actionsArray := { [ self populateMetadata ] future. }.
allActions onSuccessDo: [ :values | self splitters ifNotEmpty: [ actionsArray := actionsArray copyWith: [ self split ] future ].
result := values last. self bodyTag ifNotNil: [
semaphore signal. actionsArray := actionsArray copyWith: [ self populateBodyAs: self bodyTag ] future ].
]. allActions := TKTFuture all: actionsArray.
semaphore wait. semaphore := Semaphore new.
htmlContents := (MustacheTemplate on: result templateFile contents) value: result templateData. allActions onSuccessDo: [ :values |
^ MarkupFile exportAsFileOn: self folder / (self shortName, '.html' ) containing: htmlContents result := values last.
] semaphore signal.
].
{ #category : #accessing } semaphore wait.
BreaPage >> file [ htmlContents := (MustacheTemplate on: result templateFile contents) value: result templateData.
(self shortName isNil or: [ self folder isNil ]) ifTrue: [ ^ nil ]. ^ MarkupFile exportAsFileOn: self folder / (self shortName, '.html' ) containing: htmlContents
^ file ifNil: [ ^ BreaFile fromShortName: self shortName andFolder: self folder ] ]
]
{ #category : #accessing }
{ #category : #accessing } BreaPage >> file [
BreaPage >> file: anObject [ (self shortName isNil or: [ self folder isNil ]) ifTrue: [ ^ nil ].
file := anObject ^ file ifNil: [ ^ BreaFile fromShortName: self shortName andFolder: self folder ]
] ]
{ #category : #accessing } { #category : #accessing }
BreaPage >> folder [ BreaPage >> file: anObject [
^ folder file := anObject
] ]
{ #category : #accessing } { #category : #accessing }
BreaPage >> folder: folderFileReference [ BreaPage >> folder [
folder := folderFileReference ^ folder
] ]
{ #category : #'as yet unclassified' } { #category : #accessing }
BreaPage >> htmlContents [ BreaPage >> folder: folderFileReference [
self shortName ifNil: [ ^ self ]. folder := folderFileReference
self template ifNil: [ ^ self ]. ]
^ (MustacheTemplate on: self templateFile contents) value: self templateData.
] { #category : #'as yet unclassified' }
BreaPage >> htmlContents [
{ #category : #accessing } self shortName ifNil: [ ^ self ].
BreaPage >> metadata [ self template ifNil: [ ^ self ].
^ metadata ^ (MustacheTemplate on: self templateFile contents) value: self templateData.
] ]
{ #category : #accessing } { #category : #accessing }
BreaPage >> metadata: aDictionary [ BreaPage >> metadata [
"External place where page metadata is located (on Internet or the local file system) in JSON format. ^ metadata ifNil: [ self contentsFile metadata ]
If nil, is suposed that is placed in the Markdown file with the page contents." ]
metadata := aDictionary
] { #category : #accessing }
BreaPage >> metadata: aDictionary [
{ #category : #'as yet unclassified' } "External place where page metadata is located (on Internet or the local file system) in JSON format.
BreaPage >> populateBodyAs: key [ If nil, is suposed that is placed in the Markdown file with the page contents."
| allActions result semaphore | metadata := aDictionary
"(self file isMarkdown and: [ self bodyTag isNil ]) ifTrue: [ ^ self ]". ]
allActions := TKTFuture all: {
[ self bodyContentsAsHTML ] future. { #category : #'as yet unclassified' }
}. BreaPage >> populateBodyAs: key [
semaphore := Semaphore new. | allActions result semaphore |
allActions onSuccessDo: [ :values |
result := values last. allActions := TKTFuture all: {
semaphore signal ]. [ self bodyContentsAsHTML ] future.
semaphore wait. }.
self templateData at: key put: result contents. semaphore := Semaphore new.
^ self. allActions onSuccessDo: [ :values |
] result := values last.
semaphore signal ].
{ #category : #'as yet unclassified' } semaphore wait.
BreaPage >> populateExternalMetadata [ self templateData at: key put: result contents.
self metadata ifNil: [ ^ self ]. ^ self.
self ]
]
{ #category : #'as yet unclassified' }
{ #category : #operation } BreaPage >> populateExternalMetadata [
BreaPage >> populateMetadata [ self metadata ifNil: [ ^ self ].
| metadataTemp | self
self metadata ]
ifNotNil: [ metadataTemp := self metadata ]
ifNil: [ metadataTemp := self contentsFile metadata]. { #category : #operation }
metadataTemp keysAndValuesDo: [ :key :value | BreaPage >> populateMetadata [
self templateData at: key put: value ]. | metadataTemp |
^ templateData self metadata
] ifNotNil: [ metadataTemp := self metadata ]
ifNil: [ metadataTemp := self contentsFile metadata].
{ #category : #accessing } metadataTemp keysAndValuesDo: [ :key :value |
BreaPage >> shortName [ self templateData at: key put: value ].
^ shortName ^ templateData
] ]
{ #category : #accessing } { #category : #operation }
BreaPage >> shortName: aString [ BreaPage >> populateTaggedBody [
"The name of the file tha contains the light markup to produce the web page, without file extension. self bodyTag ifNil: [ ^ self ].
By default I work with Markdown files." ^ self populateBodyAs: self bodyTag.
shortName := aString ]
]
{ #category : #accessing }
{ #category : #'as yet unclassified' } BreaPage >> shortName [
BreaPage >> split [ ^ shortName
self splitters keysAndValuesDo: [ :key :value | self split: key with: value ]. ]
]
{ #category : #accessing }
{ #category : #'as yet unclassified' } BreaPage >> shortName: aString [
BreaPage >> split: key with: subkey [ "The name of the file tha contains the light markup to produce the web page, without file extension.
"I split a comma separated collection of subkeys stored in the 'key' field and name each one as 'subkey' By default I work with Markdown files."
to put it indiviudally in a Mustache template." shortName := aString
| allSubkeys cleaned data | ]
allSubkeys := (self populateMetadata at: key) splitOn: ','.
cleaned := allSubkeys collect: [ :item | item withBlanksCondensed ]. { #category : #'as yet unclassified' }
data := OrderedCollection new. BreaPage >> split [
cleaned do: [ :item | self splitters ifEmpty: [ ^ self ].
data add: { subkey -> item } asDictionary ]. self splitters keysAndValuesDo: [ :key :value | self split: key with: value ].
self populateMetadata at: key put: data; yourself. ]
]
{ #category : #'as yet unclassified' }
{ #category : #'as yet unclassified' } BreaPage >> split: key with: subkey [
BreaPage >> splitterAt: key with: subkey [ "I split a comma separated collection of subkeys stored in the 'key' field and name each one as 'subkey'
self splitters at: key put: subkey to put it indiviudally in a Mustache template."
] | allSubkeys cleaned data |
allSubkeys := (self populateMetadata at: key) splitOn: ','.
{ #category : #accessing } cleaned := allSubkeys collect: [ :item | item withBlanksCondensed ].
BreaPage >> splitters [ data := OrderedCollection new.
^ splitters ifNil: [ splitters := Dictionary new ] cleaned do: [ :item |
] data add: { subkey -> item } asDictionary ].
self populateMetadata at: key put: data; yourself.
{ #category : #accessing } ]
BreaPage >> splitters: aDictionary [
"I model the pattern where a Mustache template contains something like { #category : #'as yet unclassified' }
{{# key}} {{value}} {{/ key}} and has data that needs to be split before injecting it in the template." BreaPage >> splitterAt: key with: subkey [
splitters := aDictionary self splitters at: key put: subkey
] ]
{ #category : #accessing } { #category : #accessing }
BreaPage >> subpages [ BreaPage >> splitters [
^ subpages ^ splitters ifNil: [ splitters := Dictionary new ]
] ]
{ #category : #accessing } { #category : #accessing }
BreaPage >> subpages: shortNamesList [ BreaPage >> splitters: aDictionary [
"I am used when a page is composed of other subpages (for example with link aliases) that are shared "I model the pattern where a Mustache template contains something like
accross several pages." {{# key}} {{value}} {{/ key}} and has data that needs to be split before injecting it in the template."
subpages := shortNamesList splitters := aDictionary
] ]
{ #category : #accessing } { #category : #accessing }
BreaPage >> template [ BreaPage >> subpages [
^ template ^ subpages
] ]
{ #category : #accessing } { #category : #accessing }
BreaPage >> template: mustacheFileName [ BreaPage >> subpages: shortNamesList [
"Usually templates and their pages are located in the same folder." "I am used when a page is composed of other subpages (for example with link aliases) that are shared
template := mustacheFileName accross several pages."
] subpages := shortNamesList
]
{ #category : #accessing }
BreaPage >> templateData [ { #category : #accessing }
^ templateData ifNil: [ templateData := Dictionary new ] BreaPage >> template [
] ^ template
]
{ #category : #accessing }
BreaPage >> templateData: aDictionary [ { #category : #accessing }
templateData := aDictionary BreaPage >> template: mustacheFileName [
] "Usually templates and their pages are located in the same folder."
template := mustacheFileName
{ #category : #'as yet unclassified' } ]
BreaPage >> templateFile [
self folder ifNil: [ ^ self ]. { #category : #accessing }
self template ifNil: [ ^ self ]. BreaPage >> templateData [
^ self folder / self template ^ 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
]

View File

@ -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
]

View File

@ -1,204 +1,204 @@
" "
I model a web theme. I model a web theme.
For the Collaborators Part: State my main collaborators and one line about how I interact with them. For the Collaborators Part: State my main collaborators and one line about how I interact with them.
Public API and Key Messages Public API and Key Messages
- message one - message one
- message two - message two
- (for bonus points) how to create instances. - (for bonus points) how to create instances.
One simple example is simply gorgeous. One simple example is simply gorgeous.
Internal Representation and Key Implementation Points. Internal Representation and Key Implementation Points.
Instance Variables Instance Variables
name: <Object> name: <Object>
preview: <Object> preview: <Object>
provider: <Object> provider: <Object>
url: <Object> url: <Object>
Implementation Points Implementation Points
" "
Class { Class {
#name : #BreaTheme, #name : #BreaTheme,
#superclass : #Object, #superclass : #Object,
#instVars : [ #instVars : [
'name', 'name',
'provider', 'provider',
'url', 'url',
'preview', 'preview',
'license', 'license',
'folder', 'folder',
'customizations' 'customizations'
], ],
#category : #Brea #category : #Brea
} }
{ #category : #accessing } { #category : #accessing }
BreaTheme class >> availablePacks [ BreaTheme class >> availablePacks [
^ self downloadLinks keys ^ self downloadLinks keys
] ]
{ #category : #utilities } { #category : #utilities }
BreaTheme class >> downloadLinks [ BreaTheme class >> downloadLinks [
"Keys are the theme names and values are the url where it can be downloaded "Keys are the theme names and values are the url where it can be downloaded
as a zip file. as a zip file.
For the moment we work only with HTML5Up themes, but more could be added For the moment we work only with HTML5Up themes, but more could be added
and the code should be refactored accordingly." and the code should be refactored accordingly."
| result providerUrl | | result providerUrl |
result := Dictionary new. result := Dictionary new.
providerUrl := 'https://html5up.net'. providerUrl := 'https://html5up.net'.
result result
at: 'Paradigm Shift' put: providerUrl, '/paradigm-shift/download'; at: 'Paradigm Shift' put: providerUrl, '/paradigm-shift/download';
at: 'Massively' put: providerUrl, '/massively/download'; at: 'Massively' put: providerUrl, '/massively/download';
at: 'Ethereal' put: providerUrl, '/ethereal/download'; at: 'Ethereal' put: providerUrl, '/ethereal/download';
at: 'Story' put: providerUrl, '/story/download'; at: 'Story' put: providerUrl, '/story/download';
at: 'Dimension' put: providerUrl, '/dimension/download'; at: 'Dimension' put: providerUrl, '/dimension/download';
at: 'Editorial' put: providerUrl, '/editorial/download'; at: 'Editorial' put: providerUrl, '/editorial/download';
at: 'Forty' put: providerUrl, '/forty/download'; at: 'Forty' put: providerUrl, '/forty/download';
at: 'Stellar' put: providerUrl, '/stellar/download'; at: 'Stellar' put: providerUrl, '/stellar/download';
at: 'Multiverse' put: providerUrl, '/multiverse/download'; at: 'Multiverse' put: providerUrl, '/multiverse/download';
at: 'Phantom' put: providerUrl, '/phantom/download'; at: 'Phantom' put: providerUrl, '/phantom/download';
at: 'Hyperspace' put: providerUrl, '/hyperspace/download'; at: 'Hyperspace' put: providerUrl, '/hyperspace/download';
at: 'Future Imperfect' put: providerUrl, '/future-imperfect/download'; at: 'Future Imperfect' put: providerUrl, '/future-imperfect/download';
at: 'Solid State' put: providerUrl, '/solid-state/download'; at: 'Solid State' put: providerUrl, '/solid-state/download';
at: 'Identity' put: providerUrl, '/identity/download'; at: 'Identity' put: providerUrl, '/identity/download';
at: 'Lens' put: providerUrl, '/lens/download'; at: 'Lens' put: providerUrl, '/lens/download';
at: 'Fractal' put: providerUrl, '/fractal/download'; at: 'Fractal' put: providerUrl, '/fractal/download';
at: 'Eventually' put: providerUrl, '/eventually/download'; at: 'Eventually' put: providerUrl, '/eventually/download';
at: 'Spectral' put: providerUrl, '/spectral/download'; at: 'Spectral' put: providerUrl, '/spectral/download';
at: 'Phonon' put: providerUrl, '/photon/download'; at: 'Phonon' put: providerUrl, '/photon/download';
at: 'Highlights' put: providerUrl, '/highlights/download'; at: 'Highlights' put: providerUrl, '/highlights/download';
at: 'Landed' put: providerUrl, '/landed/download'; at: 'Landed' put: providerUrl, '/landed/download';
at: 'Strata' put: providerUrl, '/strata/download'; at: 'Strata' put: providerUrl, '/strata/download';
at: 'Read Only' put: providerUrl, '/read-only/download'; at: 'Read Only' put: providerUrl, '/read-only/download';
at: 'Alpha' put: providerUrl, '/alpha/download'; at: 'Alpha' put: providerUrl, '/alpha/download';
at: 'Directive' put: providerUrl, '/directive/download'; at: 'Directive' put: providerUrl, '/directive/download';
at: 'Aerial' put: providerUrl, '/aerial/download'; at: 'Aerial' put: providerUrl, '/aerial/download';
at: 'Twenty' put: providerUrl, '/twenty/download'; at: 'Twenty' put: providerUrl, '/twenty/download';
at: 'Big Picture' put: providerUrl, '/big-picture/download'; at: 'Big Picture' put: providerUrl, '/big-picture/download';
at: 'Tessellate' put: providerUrl, '/tessellate/download'; at: 'Tessellate' put: providerUrl, '/tessellate/download';
at: 'Overflow' put: providerUrl, 'overflow/download'; at: 'Overflow' put: providerUrl, 'overflow/download';
at: 'Prologue' put: providerUrl, '/prologue/download'; at: 'Prologue' put: providerUrl, '/prologue/download';
at: 'Helios' put: providerUrl, '/helios/download'; at: 'Helios' put: providerUrl, '/helios/download';
at: 'Telephasic' put: providerUrl, '/telephasic/download'; at: 'Telephasic' put: providerUrl, '/telephasic/download';
at: 'Strongly Typed' put: providerUrl, '/strongly-typed/download'; at: 'Strongly Typed' put: providerUrl, '/strongly-typed/download';
at: 'Parallelism' put: providerUrl, '/parallelism/download'; at: 'Parallelism' put: providerUrl, '/parallelism/download';
at: 'Escape Velocity' put: providerUrl, '/escape-velocity/download'; at: 'Escape Velocity' put: providerUrl, '/escape-velocity/download';
at: 'Astral' put: providerUrl, '/astral/download'; at: 'Astral' put: providerUrl, '/astral/download';
at: 'Striped' put: providerUrl, '/striped/download'; at: 'Striped' put: providerUrl, '/striped/download';
at: 'Dopetrope' put: providerUrl, '/dopetrope/download'; at: 'Dopetrope' put: providerUrl, '/dopetrope/download';
at: 'Miniport' put: providerUrl, '/miniport/download'; at: 'Miniport' put: providerUrl, '/miniport/download';
at: 'TXT' put: providerUrl, '/txt/download'; at: 'TXT' put: providerUrl, '/txt/download';
at: 'Verti' put: providerUrl, '/verti/download'; at: 'Verti' put: providerUrl, '/verti/download';
at: 'Zerofour' put: providerUrl, '/zerofour/download'; at: 'Zerofour' put: providerUrl, '/zerofour/download';
at: 'Arcana' put: providerUrl, '/arcana/download'; at: 'Arcana' put: providerUrl, '/arcana/download';
at: 'Halcyonic' put: providerUrl, '/halcyonic/download'; at: 'Halcyonic' put: providerUrl, '/halcyonic/download';
at: 'Minimaxing' put: providerUrl, '/minimaxing/download'. at: 'Minimaxing' put: providerUrl, '/minimaxing/download'.
^ result ^ result
] ]
{ #category : #utilities } { #category : #utilities }
BreaTheme >> dashedName [ BreaTheme >> dashedName [
^ self name asDashedLowercase ^ self name asDashedLowercase
] ]
{ #category : #operation } { #category : #operation }
BreaTheme >> downloadInto: aFolder [ BreaTheme >> downloadInto: aFolder [
| tempName zippedFile | | tempName zippedFile |
self url ifNil: [ ^ self ]. self url ifNil: [ ^ self ].
tempName := self name. tempName := self name.
zippedFile := aFolder / self dashedName , 'zip'. zippedFile := aFolder / self dashedName , 'zip'.
aFolder ensureCreateDirectory. aFolder ensureCreateDirectory.
GrafoscopioUtils GrafoscopioUtils
downloadingFrom: self url withMessage: 'Downloading ', tempName, '...' into: zippedFile. downloadingFrom: self url withMessage: 'Downloading ', tempName, '...' into: zippedFile.
self folder: aFolder. self folder: aFolder.
^ zippedFile ^ zippedFile
] ]
{ #category : #accessing } { #category : #accessing }
BreaTheme >> folder [ BreaTheme >> folder [
^ folder ^ folder
] ]
{ #category : #accessing } { #category : #accessing }
BreaTheme >> folder: anObject [ BreaTheme >> folder: anObject [
folder := anObject folder := anObject
] ]
{ #category : #installation } { #category : #installation }
BreaTheme >> installInto: aFolder [ BreaTheme >> installInto: aFolder [
| zippedFile | | zippedFile |
self url ifNil: [ ^ self ]. self url ifNil: [ ^ self ].
zippedFile := self downloadInto: aFolder. zippedFile := self downloadInto: FileLocator temp.
(ZipArchive new readFrom: zippedFile) extractAllTo: aFolder. (ZipArchive new readFrom: zippedFile) extractAllTo: aFolder.
^ aFolder ^ aFolder
] ]
{ #category : #accessing } { #category : #accessing }
BreaTheme >> license [ BreaTheme >> license [
^ license ^ license
] ]
{ #category : #accessing } { #category : #accessing }
BreaTheme >> license: anObject [ BreaTheme >> license: anObject [
license := anObject license := anObject
] ]
{ #category : #'as yet unclassified' } { #category : #'as yet unclassified' }
BreaTheme >> loadConfiguration [ BreaTheme >> loadConfiguration [
| config | | config |
config := self folder / 'brea.yaml'. config := self folder / 'brea.yaml'.
config exists config exists
ifTrue: [ ^ PPYAMLGrammar new parse: config contents ] ifTrue: [ ^ PPYAMLGrammar new parse: config contents ]
ifFalse: [ self inform: ifFalse: [ self inform:
'No configuration file found. A "brea.yaml" file should be located in the theme root folder. '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 please run "#updateCustomizations" after defining a theme name from the
"BreaTheme availablePacks". "BreaTheme availablePacks".
If no configuration is defined for such theme name you can create and empty configuration 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. file by running "#createBaseConfiguration" and filing out the "brea.yaml" fields.
For more information or help ask at https://t.me/grafoscopio .' ] For more information or help ask at https://t.me/grafoscopio .' ]
] ]
{ #category : #accessing } { #category : #accessing }
BreaTheme >> name [ BreaTheme >> name [
^ name ifNil: [ name = 'unamed' ] ^ name ifNil: [ name = 'unamed' ]
] ]
{ #category : #accessing } { #category : #accessing }
BreaTheme >> name: anObject [ BreaTheme >> name: anObject [
name := anObject name := anObject
] ]
{ #category : #accessing } { #category : #accessing }
BreaTheme >> preview [ BreaTheme >> preview [
^ preview ^ preview
] ]
{ #category : #accessing } { #category : #accessing }
BreaTheme >> preview: anObject [ BreaTheme >> preview: anObject [
preview := anObject preview := anObject
] ]
{ #category : #accessing } { #category : #accessing }
BreaTheme >> provider [ BreaTheme >> provider [
^ provider ^ provider
] ]
{ #category : #accessing } { #category : #accessing }
BreaTheme >> provider: anObject [ BreaTheme >> provider: anObject [
provider := anObject provider := anObject
] ]
{ #category : #accessing } { #category : #accessing }
BreaTheme >> url [ BreaTheme >> url [
^ url ifNil: [ url := self class downloadLinks at: self name. ] ^ url ifNil: [ url := self class downloadLinks at: self name. ]
] ]
{ #category : #accessing } { #category : #accessing }
BreaTheme >> url: anObject [ BreaTheme >> url: anObject [
url := anObject url := anObject
] ]

View File

@ -1,22 +1,22 @@
" "
I provide common utilities for the use with the Brea CMS. I provide common utilities for the use with the Brea CMS.
" "
Class { Class {
#name : #BreaUtils, #name : #BreaUtils,
#superclass : #Object, #superclass : #Object,
#category : #Brea #category : #Brea
} }
{ #category : #'as yet unclassified' } { #category : #'as yet unclassified' }
BreaUtils class >> installSkeleton [ BreaUtils class >> installSkeleton [
"I populate the folder and files structures for Brea documentation and customizations." "I populate the folder and files structures for Brea documentation and customizations."
| skeleton destination | | skeleton destination |
GrafoscopioUtils GrafoscopioUtils
downloadingFrom: 'https://mutabit.com/repos.fossil/brea/zip' downloadingFrom: 'https://mutabit.com/repos.fossil/brea/zip'
withMessage: 'Dowloading files skeleton' withMessage: 'Dowloading files skeleton'
into: FileLocator temp. into: FileLocator temp.
skeleton := ZipArchive new readFrom: FileLocator temp / 'zip'. skeleton := ZipArchive new readFrom: FileLocator temp / 'zip'.
destination := FileLocator home / '.local/share/Brea'. destination := FileLocator home / '.local/share/Brea'.
destination ensureCreateDirectory. destination ensureCreateDirectory.
skeleton extractAllTo: destination. skeleton extractAllTo: destination.
] ]

View File

@ -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
]

View File

@ -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
]

View File

@ -1,13 +1,13 @@
" "
I store metadata for this package. These meta data are used by other tools such as the SmalllintManifestChecker and the critics Browser I store metadata for this package. These meta data are used by other tools such as the SmalllintManifestChecker and the critics Browser
" "
Class { Class {
#name : #ManifestBrea, #name : #ManifestBrea,
#superclass : #PackageManifest, #superclass : #PackageManifest,
#category : #'Brea-Manifest' #category : #'Brea-Manifest'
} }
{ #category : #'code-critics' } { #category : #'code-critics' }
ManifestBrea class >> ruleRBStringConcatenationRuleV1FalsePositive [ 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') ) ^ #(#(#(#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') )
] ]

View File

@ -1 +1 @@
Package { #name : #Brea } Package { #name : #Brea }