Hallo David,
> Demnach wäre Category und Thread dann eine Subclass von Folder,
> und Entry eine von Page.
das ist eigentlich genau die Vorgehensweise, welche ich mir vorgestellt
habe. Ich denke so ist es am Einfachsten, weil du am Meisten
weiterverwenden kannst. Sonst musst du ja irgendwie selber einen
Dispatcher schreiben, der die richtigen Komponenten aufruft.
> Meinst du, das lässt genug Möglichkeiten zur Erweiterung, z.B. wenn es
> auch noch Subkategorien geben wird?
Das sollte kein Problem sein, Subkategorien sind dann einfach
Kategorien welche sich in einer anderen Kategorie befinden. Dazu
braucht es wohl keine einzige Zeile Code und man kann sie verschachteln
wie auch die Ordner. Oder haben Subkategorien andere Eigenschaften als
Top-Level Kategorien?
> Bist du auf keinerlei Probleme gestossen, wenn die URL immer länger
> wird?
So lange sind diese URLs ja dann auch wieder nicht. Das RFC meint:
The HTTP protocol does not place any a priori limit on the
length of a URI. Servers MUST be able to handle the URI of
any resource they serve, and SHOULD be able to handle URIs
of unbounded length if they provide GET-based forms that
could generate such URIs. A server SHOULD return 414
(Request-URI Too Long) status if a URI is longer than
the server can handle (see section 10.4.15).
Note: Servers ought to be cautious about depending on URI
lengths above 255 bytes, because some older client or proxy
implementations might not properly support these lengths.
http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.2
In anderen Quellen lese ich das bis zu 64k URL problemlos
funktionieren, aber ich kenne mich da weniger aus, habe das noch nicht
bis an die Limiten getestet.
> Und können so zwei Threads den gleichen Titel haben? Im Moment wohl
> nicht,
> aber könnte man wohl einbauen?
Dass der Titel direkt auf die URL abgebildet wird habe ich aus Gründen
der Benutzerfreundlichkeit bei der Navigation gemacht. Ich denke, dass
dies in einem Forum weniger nötig ist: du könntest die Methoden #title,
#id, ... überschreiben und die Threads einfach durchnummerieren.
Grüsse,
Lukas
PS: Bitte poste deine Fragen zukünftig in Englisch in die Mailing-Liste.
--
Lukas Renggli
http://renggli.freezope.org
Hi David,
> @Lukas: I have encountered a problem with one of your SmallWiki's
> test. Last
> week when I first run the tests, everything was okay, but now
> SmallWiki.parserTests>>#testRenderHTML fails. I havent managed to find
> out
> why.
I need some more information to be able to tell you what actually
happens:
1. What version of SmallWiki are you running in your image? You can see
this in the status-bar when selecting the SmallWiki bundle, e.g.
(0.9.47,lukas).
2. Did you modify or load code? If yes, what did you do since last
week? You can see the differences between your code and the version you
loaded from StORE by clicking on Versions | Compare with Parent in the
context-menu of the SmallWiki bundle.
3. What exactly is failing within the test? Please run the test again,
but hit the Debug- instead of the Run-Button this time. A debugger
should open and you can copy the stack (e.g. see below for an example)
and send it to the mailing-list or investigate further (e.g. click on
debug to open the full debugger) by yourself.
Cheers,
Lukas
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-
Unhandled exception: A Test Exception Raised In A Test
SmallWiki.ParserTests(Object)>>error:
optimized [] in SmallWiki.ParserTests>>testRenderHtml
optimized [] in SequenceableCollection>>with:do:
Array(SequenceableCollection)>>do:
Array(SequenceableCollection)>>with:do:
SmallWiki.ParserTests>>testRenderHtml
SmallWiki.ParserTests(TestCase)>>performTest
optimized [] in TestCase>>runCase
BlockClosure>>ensure:
BlockClosure>>sunitEnsure:
SmallWiki.ParserTests(TestCase)>>runCase
optimized [] in TestCase>>debug
BlockClosure>>ensure:
BlockClosure>>sunitEnsure:
SmallWiki.ParserTests(TestCase)>>debug
optimized [] in [] in [] in Refactory.Browser.SUnitCodeTool>>debugTests
OrderedCollection>>do:
optimized [] in [] in Refactory.Browser.SUnitCodeTool>>debugTests
BlockClosure>>on:do:
optimized [] in Refactory.Browser.SUnitCodeTool>>debugTests
BlockClosure>>ifCurtailed:
Refactory.Browser.SUnitCodeTool>>debugTests
optimized [] in ApplicationModel>>actionFor:
optimized [] in ActionButtonSpec>>typeConvert:
PluggableAdaptor>>setValue:
PluggableAdaptor(ValueModel)>>value:
TriggerButtonController>>pressAction
TriggerButtonTracker(BasicButtonTracker)>>finishSelectionFor:
TriggerButtonTracker>>finishSelectionFor:
TriggerButtonTracker(SelectionTracker)>>redButtonReleasedEvent:
RedButtonReleasedEvent>>dispatchTo:
TriggerButtonTracker(SelectionTracker)>>handleEvent:
EventDispatcher>>dispatch:to:
EventDispatcher>>dispatchEvent:
RedButtonReleasedEvent(Event)>>dispatch
RedButtonReleasedEvent(Event)>>dispatchForWindowManager:
optimized [] in WindowManager>>safelyDispatchForWindowManager:
BlockClosure>>on:do:
WindowManager>>safelyDispatchForWindowManager:
WindowManager>>processNextEvent
optimized [] in [] in WindowManager>>newProcess
BlockClosure>>on:do:
optimized [] in WindowManager>>newProcess
BlockClosure>>on:do:
optimized [] in Process class>>forBlock:priority:
----------------------------------------------------------------------
SmallWiki.ParserTests(Object)>>error:
Receiver:
a SmallWiki.ParserTests
Instance Variables:
testSelector = #testRenderHtml
root = a SmallWiki.Folder title: 'Root'
page = a SmallWiki.Page title: 'Page'
request = a SmallWiki.Request
action = a SmallWiki.PageView
prettyPrint = false
Arguments:
aStringOrMessage = 'asfdfasd'
Temporaries:
lastNonSpace = 8
aString = 'asfdfasd'
Context PC = 18
----------------------------------------------------------------------
optimized [] in SmallWiki.ParserTests>>testRenderHtml
Receiver:
an UndefinedObject
Arguments:
document = a SmallWiki.Document
html = '<p>3628800</p><p></p>'
Temporaries:
.self = SmallWiki.ParserTests>>#testRenderHtml
Context PC = 7
----------------------------------------------------------------------
optimized [] in SequenceableCollection>>with:do:
Receiver:
an UndefinedObject
Arguments:
each = a SmallWiki.Document
Temporaries:
.aBlock = BlockClosure [] in SmallWiki.ParserTests>>testRenderHtml
.otherCollection = a ReadStream
Context PC = 10
----------------------------------------------------------------------
Array(SequenceableCollection)>>do:
Receiver:
an Array
Arguments:
aBlock = BlockClosure [] in SequenceableCollection>>with:do:
Temporaries:
i = 1
Context PC = 19
----------------------------------------------------------------------
Array(SequenceableCollection)>>with:do:
Receiver:
an Array
Arguments:
aSequenceableCollection = an Array[11]
aBlock = BlockClosure [] in SmallWiki.ParserTests>>testRenderHtml
Temporaries:
otherCollection = a ReadStream
Context PC = 25
----------------------------------------------------------------------
SmallWiki.ParserTests>>testRenderHtml
Receiver:
a SmallWiki.ParserTests
Instance Variables:
testSelector = #testRenderHtml
root = a SmallWiki.Folder title: 'Root'
page = a SmallWiki.Page title: 'Page'
request = a SmallWiki.Request
action = a SmallWiki.PageView
prettyPrint = false
Context PC = 12
----------------------------------------------------------------------
SmallWiki.ParserTests(TestCase)>>performTest
Receiver:
a SmallWiki.ParserTests
Instance Variables:
testSelector = #testRenderHtml
root = a SmallWiki.Folder title: 'Root'
page = a SmallWiki.Page title: 'Page'
request = a SmallWiki.Request
action = a SmallWiki.PageView
prettyPrint = false
Context PC = 6
----------------------------------------------------------------------
optimized [] in TestCase>>runCase
Receiver:
an UndefinedObject
Temporaries:
.self = SmallWiki.ParserTests>>#testRenderHtml
Context PC = 9
----------------------------------------------------------------------
BlockClosure>>ensure:
Receiver:
a BlockClosure
Instance Variables:
method = CompiledBlock [] in TestCase>>runCase
outerContext = nil
copiedValues = SmallWiki.ParserTests>>#testRenderHtml
Arguments:
aBlock = BlockClosure [] in TestCase>>runCase
Temporaries:
result = nil
Context PC = 4
----------------------------------------------------------------------
BlockClosure>>sunitEnsure:
Receiver:
a BlockClosure
Instance Variables:
method = CompiledBlock [] in TestCase>>runCase
outerContext = nil
copiedValues = SmallWiki.ParserTests>>#testRenderHtml
Arguments:
aBlock = BlockClosure [] in TestCase>>runCase
Context PC = 5
----------------------------------------------------------------------
SmallWiki.ParserTests(TestCase)>>runCase
Receiver:
a SmallWiki.ParserTests
Instance Variables:
testSelector = #testRenderHtml
root = a SmallWiki.Folder title: 'Root'
page = a SmallWiki.Page title: 'Page'
request = a SmallWiki.Request
action = a SmallWiki.PageView
prettyPrint = false
Context PC = 11
----------------------------------------------------------------------
optimized [] in TestCase>>debug
Receiver:
an UndefinedObject
Temporaries:
.self = SmallWiki.ParserTests>>#testRenderHtml
Context PC = 10
----------------------------------------------------------------------
BlockClosure>>ensure:
Receiver:
a BlockClosure
Instance Variables:
method = CompiledBlock [] in TestCase>>debug
outerContext = nil
copiedValues = SmallWiki.ParserTests>>#testRenderHtml
Arguments:
aBlock = BlockClosure [] in TestCase>>debug
Temporaries:
result = nil
Context PC = 4
----------------------------------------------------------------------
BlockClosure>>sunitEnsure:
Receiver:
a BlockClosure
Instance Variables:
method = CompiledBlock [] in TestCase>>debug
outerContext = nil
copiedValues = SmallWiki.ParserTests>>#testRenderHtml
Arguments:
aBlock = BlockClosure [] in TestCase>>debug
Context PC = 5
----------------------------------------------------------------------
SmallWiki.ParserTests(TestCase)>>debug
Receiver:
a SmallWiki.ParserTests
Instance Variables:
testSelector = #testRenderHtml
root = nil
page = nil
request = nil
action = nil
prettyPrint = nil
Context PC = 18
----------------------------------------------------------------------
optimized [] in [] in [] in Refactory.Browser.SUnitCodeTool>>debugTests
Receiver:
an UndefinedObject
Arguments:
each = SmallWiki.ParserTests>>#testRenderHtml
Temporaries:
.self = a Refactory.Browser.SUnitCodeTool
Context PC = 5
----------------------------------------------------------------------
OrderedCollection>>do:
Receiver:
an OrderedCollection
Instance Variables:
firstIndex = 1
lastIndex = 1
Arguments:
aBlock = BlockClosure [] in [] in [] in
Refactory.Browser.SUnitCodeTool>>debugTests
Temporaries:
index = 1
Context PC = 17
----------------------------------------------------------------------
optimized [] in [] in Refactory.Browser.SUnitCodeTool>>debugTests
Receiver:
an UndefinedObject
Temporaries:
.self = a Refactory.Browser.SUnitCodeTool
Context PC = 12
----------------------------------------------------------------------
BlockClosure>>on:do:
Receiver:
a BlockClosure
Instance Variables:
method = CompiledBlock [] in [] in
Refactory.Browser.SUnitCodeTool>>debugTests
outerContext = nil
copiedValues = a Refactory.Browser.SUnitCodeTool
Arguments:
anExceptionSelector = an ExceptionSet[2]
handlerBlock = BlockClosure [] in [] in
Refactory.Browser.SUnitCodeTool>>debugTests
Context PC = 18
----------------------------------------------------------------------
optimized [] in Refactory.Browser.SUnitCodeTool>>debugTests
Receiver:
an UndefinedObject
Temporaries:
.self = a Refactory.Browser.SUnitCodeTool
failed = true
Context PC = 18
----------------------------------------------------------------------
BlockClosure>>ifCurtailed:
Receiver:
a BlockClosure
Instance Variables:
method = CompiledBlock [] in
Refactory.Browser.SUnitCodeTool>>debugTests
outerContext = nil
copiedValues = an Array[2]
Arguments:
terminationBlock = BlockClosure [] in
Refactory.Browser.SUnitCodeTool>>debugTests
Context PC = 4
----------------------------------------------------------------------
Refactory.Browser.SUnitCodeTool>>debugTests
Receiver:
a Refactory.Browser.SUnitCodeTool
Instance Variables:
dependents = nil
builder = an UIBuilder
uiSession = nil
eventHandlers = nil
codeModel = ParserTests>>testRenderHtml
menu = a Menu
codeTool = a Refactory.Browser.BrowserCodeTool
selectionPolicy = a Refactory.Browser.SourceSelectionPolicy
testCount = 1
defects = an OrderedCollection[1]
Temporaries:
failed = true
Context PC = 42
----------------------------------------------------------------------
optimized [] in ApplicationModel>>actionFor:
Receiver:
an UndefinedObject
Temporaries:
.self = a Refactory.Browser.SUnitCodeTool
.aKey = #debugTests
Context PC = 7
----------------------------------------------------------------------
optimized [] in ActionButtonSpec>>typeConvert:
Receiver:
an UndefinedObject
Arguments:
b = a ValueHolder on: nil
v = true
Temporaries:
.aValue = BlockClosure [] in ApplicationModel>>actionFor:
Context PC = 5
----------------------------------------------------------------------
PluggableAdaptor>>setValue:
Receiver:
a PluggableAdaptor
Instance Variables:
dependents = a Win95ActionButtonView
model = a ValueHolder on: nil
getBlock = BlockClosure [] in ActionButtonSpec>>typeConvert:
putBlock = BlockClosure [] in ActionButtonSpec>>typeConvert:
updateBlock = BlockClosure [] in ActionButtonSpec>>typeConvert:
Arguments:
newValue = true
Context PC = 6
----------------------------------------------------------------------
PluggableAdaptor(ValueModel)>>value:
Receiver:
a PluggableAdaptor
Instance Variables:
dependents = a Win95ActionButtonView
model = a ValueHolder on: nil
getBlock = BlockClosure [] in ActionButtonSpec>>typeConvert:
putBlock = BlockClosure [] in ActionButtonSpec>>typeConvert:
updateBlock = BlockClosure [] in ActionButtonSpec>>typeConvert:
Arguments:
newValue = true
Context PC = 5
----------------------------------------------------------------------
TriggerButtonController>>pressAction
Receiver:
a TriggerButtonController
Instance Variables:
model = a PluggableAdaptor
view = a Win95ActionButtonView
sensor = a TranslatingSensor
keyboardProcessor = a KeyboardProcessor
keyboardHook = nil
dispatcher = nil
Context PC = 17
----------------------------------------------------------------------
TriggerButtonTracker(BasicButtonTracker)>>finishSelectionFor:
Receiver:
a TriggerButtonTracker
Instance Variables:
controller = a TriggerButtonController
inside = true
Arguments:
aPoint = 21@5
Context PC = 8
----------------------------------------------------------------------
TriggerButtonTracker>>finishSelectionFor:
Receiver:
a TriggerButtonTracker
Instance Variables:
controller = a TriggerButtonController
inside = true
Arguments:
aPoint = 21@5
Context PC = 11
----------------------------------------------------------------------
TriggerButtonTracker(SelectionTracker)>>redButtonReleasedEvent:
Receiver:
a TriggerButtonTracker
Instance Variables:
controller = a TriggerButtonController
inside = true
Arguments:
aMouseButtonEvent = a RedButtonReleasedEvent
Context PC = 13
----------------------------------------------------------------------
RedButtonReleasedEvent>>dispatchTo:
Receiver:
a RedButtonReleasedEvent
Instance Variables:
time = 275953709
initiator = an EventDispatcher
window = an ApplicationWindow 192
state = 0
x = 700
y = 592
gx = 757
gy = 906
buttonNumber = 1
Arguments:
anObject = a TriggerButtonTracker
Context PC = 4
----------------------------------------------------------------------
TriggerButtonTracker(SelectionTracker)>>handleEvent:
Receiver:
a TriggerButtonTracker
Instance Variables:
controller = a TriggerButtonController
inside = true
Arguments:
anEvent = a RedButtonReleasedEvent
Context PC = 4
----------------------------------------------------------------------
EventDispatcher>>dispatch:to:
Receiver:
an EventDispatcher
Instance Variables:
windowController = an ApplicationStandardSystemController
currentMouseConsumer = nil
grabbingMouse = false
keyboardProcessor = a KeyboardProcessor
lastControlObject = nil
trapList = nil
state = #debugging
repairDamageWhenDebugging = true
flushQueueAfterError = true
distributeEventsWhenDebugging = true
dragDropInProgress = false
dragDropTracker = nil
dispatchUnknownEvents = false
Arguments:
event = a RedButtonReleasedEvent
object = a TriggerButtonTracker
Temporaries:
tmp = nil
Context PC = 10
----------------------------------------------------------------------
EventDispatcher>>dispatchEvent:
Receiver:
an EventDispatcher
Instance Variables:
windowController = an ApplicationStandardSystemController
currentMouseConsumer = nil
grabbingMouse = false
keyboardProcessor = a KeyboardProcessor
lastControlObject = nil
trapList = nil
state = #debugging
repairDamageWhenDebugging = true
flushQueueAfterError = true
distributeEventsWhenDebugging = true
dragDropInProgress = false
dragDropTracker = nil
dispatchUnknownEvents = false
Arguments:
event = a RedButtonReleasedEvent
Temporaries:
objectWantingControl = nil
targetKeyboardProcessor = nil
Context PC = 60
----------------------------------------------------------------------
RedButtonReleasedEvent(Event)>>dispatch
Receiver:
a RedButtonReleasedEvent
Instance Variables:
time = 275953709
initiator = an EventDispatcher
window = an ApplicationWindow 192
state = 0
x = 700
y = 592
gx = 757
gy = 906
buttonNumber = 1
Context PC = 16
----------------------------------------------------------------------
RedButtonReleasedEvent(Event)>>dispatchForWindowManager:
Receiver:
a RedButtonReleasedEvent
Instance Variables:
time = 275953709
initiator = an EventDispatcher
window = an ApplicationWindow 192
state = 0
x = 700
y = 592
gx = 757
gy = 906
buttonNumber = 1
Arguments:
aWinMgr = a WindowManager
Context PC = 4
----------------------------------------------------------------------
optimized [] in WindowManager>>safelyDispatchForWindowManager:
Receiver:
an UndefinedObject
Temporaries:
.event = a RedButtonReleasedEvent
.self = a WindowManager
Context PC = 6
----------------------------------------------------------------------
BlockClosure>>on:do:
Receiver:
a BlockClosure
Instance Variables:
method = CompiledBlock [] in
WindowManager>>safelyDispatchForWindowManager:
outerContext = nil
copiedValues = an Array[2]
Arguments:
anExceptionSelector = BadControllerError
handlerBlock = BlockClosure [] in
WindowManager>>safelyDispatchForWindowManager:
Context PC = 18
----------------------------------------------------------------------
WindowManager>>safelyDispatchForWindowManager:
Receiver:
a WindowManager
Instance Variables:
windows = an OrderedCollection[1]
activeController = an ApplicationStandardSystemController
interruptLock = false
outstandingMetaOrDamage = false
modalWindowChain = nil
openInProgress = false
eventQueue = an EventQueue
baseProcess = a Process in Semaphore>>wait
dontFilterEvents = false
Arguments:
event = a RedButtonReleasedEvent
Context PC = 13
----------------------------------------------------------------------
WindowManager>>processNextEvent
Receiver:
a WindowManager
Instance Variables:
windows = an OrderedCollection[1]
activeController = an ApplicationStandardSystemController
interruptLock = false
outstandingMetaOrDamage = false
modalWindowChain = nil
openInProgress = false
eventQueue = an EventQueue
baseProcess = a Process in Semaphore>>wait
dontFilterEvents = false
Temporaries:
event = a RedButtonReleasedEvent
Context PC = 12
----------------------------------------------------------------------
optimized [] in [] in WindowManager>>newProcess
Receiver:
an UndefinedObject
Temporaries:
.self = a WindowManager
Context PC = 13
----------------------------------------------------------------------
BlockClosure>>on:do:
Receiver:
a BlockClosure
Instance Variables:
method = CompiledBlock [] in [] in WindowManager>>newProcess
outerContext = nil
copiedValues = a WindowManager
Arguments:
anExceptionSelector = TerminateException
handlerBlock = BlockClosure [] in [] in WindowManager>>newProcess
Context PC = 18
----------------------------------------------------------------------
optimized [] in WindowManager>>newProcess
Receiver:
an UndefinedObject
Temporaries:
.self = a WindowManager
Context PC = 15
----------------------------------------------------------------------
BlockClosure>>on:do:
Receiver:
a BlockClosure
Instance Variables:
method = CompiledBlock [] in WindowManager>>newProcess
outerContext = nil
copiedValues = a WindowManager
Arguments:
anExceptionSelector = TerminateException
handlerBlock = BlockClosure [] in [] in Process
class>>forBlock:priority:
Context PC = 18
----------------------------------------------------------------------
optimized [] in Process class>>forBlock:priority:
Receiver:
an UndefinedObject
Temporaries:
.aBlock = BlockClosure [] in WindowManager>>newProcess
Context PC = 9
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=-=-
--
Lukas Renggli
http://renggli.freezope.org