Thank you for working on reforming our blighted patent system. Merely controlling litigation is not enough. You mentioned frivolous and speculative patent lawsuits, but you did not identify the deeper problem with software patents.Software is written. Software should be protected under copyright laws not patent laws. Copyrights protect exact wording, but do not prevent people from speaking, thinking or writing about those ideas. Just like literate people can read ideas in good books, literate software engineers can read ideas in software. Just as literate people should not copy a book word for word and take credit for writing it, software engineers should not copy a computer program word for word and take credit for writing it.Software should not be patentable. Think about these: A bookbinding, a new way to make paper, a new computer case, and a revolutionary computer screen. These can be patented, but the ideas on the pages of a book and the ideas in each line of software code are only thoughts and ideas. Patenting an idea is like trying to control how people think, it's like trying to control the newspapers saying that there can only be one republican newspaper and one democratic newspaper. Preventing the spread of thoughts and ideas is not constitutional.Allowing software patents is like saying we don't really believe in the right to believe, think, or speak. Allowing software patents is fundamentally wrong.Please champion legislation to protect software the right way: with copyrights, not with patents.
Tuesday, October 29, 2013
Software Patents = Crazy Talk
Rep. Goodlatte, my representative in congress, has been working on fixing the problems with US Patent Law. I just emailed him the following:
Tuesday, August 6, 2013
Figuring out TDD
I want to use TDD in my GSoC project. Tests are important, and the benefits of testing are worth it.
Now, my only problem with TDD is, I'm not quite sure how to do it. Oh, I've got the mechanics in place (Travis is set up and ready to eat my github repo, and I think I've got phpunit setup locally. Heck I even have Jenkins on my local machine if I could ever get it configured right.), but whenever I go to write unit tests, I feel like I'm staring at a blank page in an old fashioned typewriter.
I feel like I'm staring at a blank page in an old fashioned typewriter. (Image from starside on flickr) |
For a long time, I think my problem was an incomplete design. I knew I wanted to take stuff from a boilerplate, then "process it somehow", then put it in a derivative package. But I didn't know what that "somehow" looked like.
Well, I've figured out the main parts of that process now. I know what I want my API to look like (within PHP). So, I take my first example, and go line-by-line to make it work.
Well, I've figured out the main parts of that process now. I know what I want my API to look like (within PHP). So, I take my first example, and go line-by-line to make it work.
Loading Gist ....
So, let's take part of line 2:
How do I test this? Do unit tests test constructors? Is this a unit?
And so I'm back at that blank page again. I'm not quite sure what unit I'm testing. The constructor doesn't return anything, it just sets up the object. Should I add getters and setters for what should ultimately be protected properties just so that I can test that they are initialized correctly? That seems rather odd.
But TDD says don't write a line of code until you've written a failing test, so I feel stuck.
How do you approach TDD? Unit testing? What questions do you ask yourself to get past the stupid blank page?
new BlobQuery('Cognifire.SweetSitePackage');
How do I test this? Do unit tests test constructors? Is this a unit?
And so I'm back at that blank page again. I'm not quite sure what unit I'm testing. The constructor doesn't return anything, it just sets up the object. Should I add getters and setters for what should ultimately be protected properties just so that I can test that they are initialized correctly? That seems rather odd.
But TDD says don't write a line of code until you've written a failing test, so I feel stuck.
How do you approach TDD? Unit testing? What questions do you ask yourself to get past the stupid blank page?
Labels:
Boilerplates,
GSOC,
Neos,
TYPO3
Location:
Salt Lake City, UT, USA
Monday, July 15, 2013
BuilderFoundation BlobQuery
Blob: A file, or a snippet/section of a file, or syntax-tree like thing. Typically, a blob requires a special parser.
BlobType: A blob has a type so that it can be handled by the appropriate parser.
SubBlobs: A blob in another blob.
BlobType-SubType: BlobTypes are not restricted to just the main blob types, but may define subtypes as well to make working within the syntax tree easier. A SubType is separated by a dash (maybe I should use a dot as the separator like NodeTypes does in TYPO3CR. What do you think?)
Example BlobTypes include: FluidBlob, HtmlBlob, PhpBlob, YamlBlob, TypoScriptBlob. I believe the packageBuilder will need an additional DomainBlob that doesn't map to any particular media-type. A Blob is essentially a generalized syntax tree, and a DomainBlob would be used to create PhpBlobs, it's just a more specialized/focused view of the information.
Example SubTypes (if I match the syntax tree exactly):
OK, so here's a portion of the UML diagram I've been creating (in ArgoUML) to figure out what all needs to go in BuilderFoundation.
The OperationResolver expects simple values for priority, shortName, and Final, but I want to have one Operation class, BlobTypeSpecificOperations, that calls a variety of methods on the Blobs. To make this work, I add a BlobTypeSpecificOperationsAspect that calls a specialize initializeObject right after OperationResolver->initializeObject() gets called. This grabs the Cognifire.BuilderFoundation.BlobTypeOperations configuration and adds all of the registered blob operations to the list of operations. That means that if a blob has a special operation that only works for that BlobType, then add it as a method in the Blob itself (makes code organization feel better), and register that method as a BlobOperation in the Settings.yaml file. Whenever that operation gets called, it will go through BlobTypeSpecificOperations->evaluate() which will call the registered method on the blob for that operation.
The reason this is important, is you'll select a set of blobs with BlobQuery/FlowQuery, and then do some operation, and it will do that operation on all of the Blobs.
AOP is awesome!
BlobType: A blob has a type so that it can be handled by the appropriate parser.
SubBlobs: A blob in another blob.
BlobType-SubType: BlobTypes are not restricted to just the main blob types, but may define subtypes as well to make working within the syntax tree easier. A SubType is separated by a dash (maybe I should use a dot as the separator like NodeTypes does in TYPO3CR. What do you think?)
Example BlobTypes include: FluidBlob, HtmlBlob, PhpBlob, YamlBlob, TypoScriptBlob. I believe the packageBuilder will need an additional DomainBlob that doesn't map to any particular media-type. A Blob is essentially a generalized syntax tree, and a DomainBlob would be used to create PhpBlobs, it's just a more specialized/focused view of the information.
Example SubTypes (if I match the syntax tree exactly):
- FluidBlob
- FluidBlob-Array
- FluidBlob-Boolean
- FluidBlob-ObjectAccessor
- FluidBlob-Numeric
- FluidBlob-Text
- FluidBlob-ViewHelper.
- PhpBlob
- PhpBlob-Class
- PhpBlob-Function (PhpBlob-Method within Class)
- PhpBlob-Interface
- PhpBlob-Namespace
- PhpBlob-Property
OK, so here's a portion of the UML diagram I've been creating (in ArgoUML) to figure out what all needs to go in BuilderFoundation.
The OperationResolver expects simple values for priority, shortName, and Final, but I want to have one Operation class, BlobTypeSpecificOperations, that calls a variety of methods on the Blobs. To make this work, I add a BlobTypeSpecificOperationsAspect that calls a specialize initializeObject right after OperationResolver->initializeObject() gets called. This grabs the Cognifire.BuilderFoundation.BlobTypeOperations configuration and adds all of the registered blob operations to the list of operations. That means that if a blob has a special operation that only works for that BlobType, then add it as a method in the Blob itself (makes code organization feel better), and register that method as a BlobOperation in the Settings.yaml file. Whenever that operation gets called, it will go through BlobTypeSpecificOperations->evaluate() which will call the registered method on the blob for that operation.
The reason this is important, is you'll select a set of blobs with BlobQuery/FlowQuery, and then do some operation, and it will do that operation on all of the Blobs.
AOP is awesome!
Saturday, July 6, 2013
GSoC Notebook
I wanted to show that I'm still working on this, and a video seemed like the easiest way to show off my notes to the world. Enjoy. Let me know if you have any questions or want to know about something in my notebook.
Friday, June 14, 2013
Changing OpenRC colors to use Solarized
So, after switching my terminals to use the solarized color scheme, I was dismayed to discover that alot of apps don't like it when you change the ANSI colors.
OpenRC commands are no exception: rc-status, rc-config, and rc-service all tried to use the bold colors which have been reassigned, so the output is downright ugly.
I just went sifting through the OpenRC sources, and discovered a little gem: EINFO_COLOR is an environment variable that does more than turn color on or off. No, that little sucker allows you to redefine which ANSI colors it will use for output.
Here's what I do to make it use solarized. I put the following line in /etc/bash/bashrc (because everything is solarized, not just my user):
This sets my colors to:
Each of the colors is a pair of two numbers
OpenRC commands are no exception: rc-status, rc-config, and rc-service all tried to use the bold colors which have been reassigned, so the output is downright ugly.
I just went sifting through the OpenRC sources, and discovered a little gem: EINFO_COLOR is an environment variable that does more than turn color on or off. No, that little sucker allows you to redefine which ANSI colors it will use for output.
Here's what I do to make it use solarized. I put the following line in /etc/bash/bashrc (because everything is solarized, not just my user):
export EINFO_COLOR="good=2;0:bad=1;0:warn=1;1:hilite=7;1:"
This sets my colors to:
- good is green
- bad is red
- warn is orange
- hilite is base3
Each of the colors is a pair of two numbers
- The first number is the ANSI Color (0-7)
- followed by a semicolon (;)
- followed by whether or not it should use the "bold" ANSI Color (0 is normal, 1 is "bold")
- followed, by a colon (:) which serves to 'end' the number and separate the variables in the string
So that means that Solarized colors would be specified like this:
SOLARIZED HEX 16/8 TERMCOL EINFO_COLOR
--------- ------- ---- ------- -----------
base03 #002b36 8/4 brblack 0;1:
base02 #073642 0/4 black 0;0:
base01 #586e75 10/7 brgreen 2;1:
base00 #657b83 11/7 bryellow 3;1:
base0 #839496 12/6 brblue 4;1:
base1 #93a1a1 14/4 brcyan 6;1:
base2 #eee8d5 7/7 white 7;0:
base3 #fdf6e3 15/7 brwhite 7;1:
yellow #b58900 3/3 yellow 3;0:
orange #cb4b16 9/3 brred 1;1:
red #dc322f 1/1 red 1;0:
magenta #d33682 5/5 magenta 5;0:
violet #6c71c4 13/5 brmagenta 5;1:
blue #268bd2 4/4 blue 4;0:
cyan #2aa198 6/6 cyan 6;0:
green #859900 2/2 green 2;0:
Wednesday, June 12, 2013
Tech Buzzword Bonanza
I made this awhile ago while studying a bunch of different tech topics. I referred back to it today, and ended up recreating it in VUE so that I could update it. The original version was in a trial version of Lucid Chart. I've updated it with a few more terms from Domain Driven Design and TDD/BDD. Maybe someone else might find this helpful.
Tech Buzzword Bonanza |
Monday, June 10, 2013
Scattered design thoughts
So, I have notes scattered everywhere and I'm somewhat lost. I'm using this post to try and collect my notes, and get a better idea of where I am and where I'm going. Though you're welcome to browse through this, I don't expect these notes to make sense to anyone other than me.
BuilderFoundation provides a MetaModel for packages that other Builders will extend.
A Package can be built like FormDefinitions from TYPO3.Form
- FormDefinitions have:
- finishers <array>
- processingRules <array>
- elementsByIdentifier <array>
- eleementsDefaultValue <array>
- formFieldTypeManager <injected class>
- validatorPresets <array>
- finisherPresets <array>
- setOptions (stuff that works with info from a YAML)
- setRendererClassName
- setRenderingOption
- createFinisher
- The FormFactory builds FormDefinitions
- Use the name "presets" which would work as an options layer in general, or a "themes" layer in TemplateBuilder (a preset is a name + configuration; or iow it is a named set of configuration)
- Based on YAML files
- Using a yamlPersistenceManager
YAML files
- Use superTypes inheritance concept (like in Forms and TYPO3CR: NodeTypes.yaml) to allow for things like mixins
- Always get converted to arrays
- considered using TypoScript, but YAML seems to fit how I'll use this better. (YAML is for data serialization. TypoScript helps in processing things)
- YAML processors should always have at least one of dump() or load()
- Each package has a configuration file in YAML
- boilerplates and settings repositories should be added from the yaml (Cognifire\BuilderFoundation\boilerplateRepositories & derivativeRepositories)
- Current configuration files
- Settings.yaml
- Routes.yaml
- Objects.yaml
- Policy.yaml
- PackageStates.php
- Caches.yaml
- Views.yaml
- It would be nice to be able to breakup boilerplate configurations so that there's one preset per file (or somethin like that). <whatever base name>.<preset name>.yaml
- Will need a schema:
AbstractPackage: Boilerplates and Derivatives
- not packageKey identified, but w/ UUID because packageKey might change several times during package build process
- What gets stored in the package object is metadata about it's creation
- a declarative set of steps--if you will--to allow the builder to recreate the same derivative but with another package key
- Only part of this can be found out by parsing directory structures.
- Instead, you
- list Packages/<target repo>/*
- read each <package>/Configuration/<yaml file>
- Yaml file names (not satisfied with these names)
Themes.yaml(Builders might want to provide their own yaml file, like the templateBuilder where the word "themes" makes a lot of sense)- Possible names in Boilerplates:
Builder.Boilerplate.yaml- Boilerplate.yaml
- Declared components (all available)
Boilerplate.presets.yamlBoilerplate.presets.<something>.yaml- Possible names in Derivatives:
Builder.Derivative.yaml- Derivative.yaml
Boilerplate.Integrated.yaml- Declare which components were used and from where without introducing a dependency on the boilerplate
Builder.Template.yaml or Builder.Package.yaml- contains the presets or the final configuration, how all of declared components were put together
- Builder specific?
- Boilerplate.yaml and Derivative.yaml can be a collection of YAML files to keep the component definitions in the same folder as the component. Everything in that Boilerplate would apply only to that path. With one exception: Resources/Private/[Boilerplate || Derivative].yaml applies to the whole package. They should be restricted to the Resources folder, though, so that we don't have YAML files in the Classes/ or Tests/ folders. Boilerplate.yaml and Derivative.yaml should also not be in Settings/ as that is reserved for Presets.*.yaml for builder stuff as well as other configuration that is not builder-related.
- Basically, this means that Boilerplates will store the snippets they use to build files in the Resources folder.
- Boilerplate vs Derivative
- Package Repository (Boilerplate vs Application)
- Derivative
- Root files (composer.json...)
- Resources
- Configuration
- Documentation
- Classes
- Tests
- Scripts
- Migrations
- Meta
- Yaml files, rethought
- <package>/Resources/Private/Boilerplate.yaml
Declares which components/resources are available in boilerplate including: - Which builder is required to work with a particular set of files. Or maybe they would declare filetypes like x.html is fluid and y.html is handlebars so that the appropriate Builder can be used, and the Builder would say which filetypes it works with)
- A versioning "namespace" of sorts, so that a boilerplate can include multiple versions of layouts/templates/partials (thinking of TwitterBootstrap v2 and v3). This would assist the migration service
- Perhaps a list of presets that are available in the Boilerplate (though that should probably be based on what is in the Settings/)
- <package>/Resources/Private/Derivative.yaml
- Declares which components & presets have been used
- from which boilerplate
- and which boilerplate version (to assist with migrations)
- Perhaps a list of which manual changes have been detected
- This file would have the Eel selectors to say "insert [component] at [location] in [file]" including components from boilerplates and components that are added manually. This should be verbose enough that a Builder could regenerate the templates from the boilerplates (for the custom components [the 'changeset in Boilerplate math], maybe the builder could pull them out and store them in another Resources/Private/ folder so that it can keep track of manual changes.)
- Though this should be human readable, only Builders will edit it. I can imagine people tweaking an Eel statement. But most of the file is for Builder metadata persistence.
- <package>/Settings/
Presets.[BuilderSpecific].[PresetName].yaml
A preset configures a set of components to work together. This is the Builders' "options" layer. It does not define how the files are combined. That belongs in the Boilerplate.yaml (for what can be combined) or Deriative.yaml (for what has been combined) files.
Should the BuilderSpecific part be singular or plural? You can have multiple presets in a Presets.Builder.yaml file, or break them out into individual Presets.Builder.Preset1.yaml and Presets.Builder.Preset2.yaml files.
Someone could edit a Preset manually and use the Builder to make the change in their templates. These should be human-friendly. They would have to fire up the Builder to make the builder adjust whatever files are built with that preset (like changing a color in a LESS file).
Examples of possible uses per builder (just examples, most are not part of GSoC project): - PackageBuilder
- Presets.Package.CMS.yaml
- Presets.Package.Flow.yaml
- Presets.Package.Symfony.yaml (example extension of PackageBuilder)
- TemplateBuilder
- Presets.Theme.yaml
- Presets.Theme.FixedLayout.yaml
- Presets.Theme.AwesomeGreen.yaml
- Presets.Theme.MyThemeName.yaml
- Presets.Fluid.yaml (for stuff that doesn't quite fit the term "Theme"
- TypoScriptBuilder
- Presets.TypoScript.yaml
- EmberBuilder or JavaScriptBuilder (Works with JavaScript stuff like Ember and Handlebars)
- Presets.Ember.yaml
- Presets.Ember.Handlebars.yaml
- Presets.Handlebars.yaml
- Presets.JS.yaml (maybe everything could be Presets.JS.*.yaml like Presets.JS.Ember.yaml and Presets.JS.Handlebars.yaml)
- FormBuilder (if it switches to using BuilderFoundation at its core)
- Presets.Form.yaml
- Presets.Form.Cli.yaml
- Presets.Form.Bootstrap.yaml
- TranslationBuilder (works with .xlf files)
- Presets.Translation.yaml (not sure how a TranslationBuilder would need Presets, but it's possible)
- SchemaBuilder (a Resource that needs to be built. Different Builders might want to create a schema for what is allowed in their Presets.[Builder].*.yaml files, and they might not want to craft the schemas by hand)
- OntologyBuilder/TaxonomyBuilder (Not sure this one will work with packages or boilerplates, but, the Builder concept still applies)
Yaml file contents Boilerplate vs Derivative (extendable yaml schema)Boilerplaterelevant builder (like template builder)components that can be builtinclude[superType]Variations of each componentOptions that apply to each componentpresetscomponents 1,2,5variations such and sooptionsTemplateBuilder: (example specific builder)Declare what is avilableComponents:VariationsOptionsVariationsOptions (Theme in TemplateBuilder)color1:color2:width:Presets are pre-configured defaults / collections of components and optionsPresets / <presetname>components: 1, 2, 3variation: A, BoptionsDerivativeHas one preset that lists whichboilerplate components are in usehow they are configuredwhat options are setBoilerplate.Integrated.yamldeclares components used from each boierplatecopied from boilerplate w/ boilerplate version
Spl*Iterators [Directory, FileSystem, Glob]:
- Relationships
- GlobIterator extends FileSystemIterator extends DirectoryIterator
- RecursiveDirectoryIterator extends FileSystemIterator as well
- GlobIterator is one level w/ glob pattern search
- DirectoryIterator is one level
- FileSystemIterator is just like DirectoryIterator but with flags that give more control over what current and key return.
- RecursiveDirectoryIterator does many levels
- Interesting FileSystemIterator Flags
- ::CURRENT_AS_PATHNAME
- ::KEY_AS_PATHNAME
- ::KEY_AS_FILENAME
- ::FOLLOW_SYMLINKS
- ::NEW_CURRENT_AND_KEY (KEY_AS_FILENAME & CURRENT_AS_FILEINFO)
- ::SKIP_DOTS
- ::UNIX_PATHS (I'll want this one)
- Current could return Pathname, or Filename or Fileinfo (which is a SplFileInfo object)
- Key is just a numeric array key
- SplFileInfo interesting methods (also available on DirectoryIterator and FileSystemIterator)
- getBasename (can omit a suffix from path & filename)
- getFilename
- getPath (w/o filename)
- openFile (creates SplFileObject to iterate ovver a file w/ fwrite, fpassthru...)
- getRealPath (resolve links)
- getExtension
- getType (file, link, dir)
- Streams
- file:// -- for file access
- glob://*.png -- for listing dir contents that match the glob
- data: -- to encode stuff straight in files and treat it as a file/stream (RFC 2397)
- data:text/plan,$data
- data:text/plain;base64,$data
- data:image/jpeg;base64;$image
- resource:// -- flow specific only for stuff in resources of a particular package
- The purpose of this is not to hide that something is a file, but to hide where it is stored (so that Flow can do the linking magic with all the public stuff in the Web/_Resources folder
Persistence
- Flow injects the persistenceManagerInterface
- There's no way to say which one flow will use, instead it is specified in objects.yaml (doctrine by default)
- Mutliple concurrent Persistence backends won't be available until Flow 2.2 (or Flow 3 depending on how backwards compatible it is
- define on repository basis what kind of DB to persist it in
- This is not implemented yet due to lack of funding
- I would rather reuse the flow persistence stuff where it makes sense, but I have to decouple everything until this is implemented. I'll copy lots of stuff to make it work. The thing is, a DB doesn't make any sense in my packages, even though I'm persisting stuff, the code assumes that persistence is always to a DB.
- workaround is to put persistence stuff in the repository and not use @Flow\Entity and the like
- "Models do not know (a lot) about Persistence (internals)"
- Repository responsible for:
- Saving object
- persisting changes to object throughout lifetime (update DB as needed)
- provide QL
- handle DB retrieval
- ensures only one instance in memory
- provides the aggregate root
- Comparing Radmiraal.CouchDB (doctrine branch) with normal doctrine persistence
- @ODM\Document instead of @ORM\Entity or @Flow\Entity
- replaces persistence manager w/ document manager
- queries
- no query on arbitrary properties
- drops queries in favor of lucenQueries
- setQueryMatchValue
- both use persistenceManager
- ->getObjectByIdentifier in generic
- ->getIdentifierByObject in radmiraal
- persistenceManager vs documentManager method names
- add; persist
- update; merge
- remove; remove
- createQueryForType; [createLuceneQuery, createNativeQuery, createQuery]
- Doctrine's PersistenceManager uses the Annotations Driver
- Annotations
- Entity
- map the repository / set CustomRepositoryClass
- markReadOnly
- loadMetaDataForClass
- evaluatePropertyAnnotations
- maps to column names, OneToOne, OneToMany, ManyToOne, ManyToMany
- evaluateOverridesAnnotations
- evaluateLifeCycleAnnotations
- public methods
- PrePersist
- PostPersist
- PreUpdate
- PostUpdate
- PreRemove
- PostRemove
- PostLoad
- PreFlush
- isTransient (yes if not entity or value object)
- I want to use Flow/Validate
- PersistenceManager fires
- Yaml Configuration
- All combined/cached like views.yaml
How other things interact w/ files
- Parts of flow that work with files
- Reflection uses cache to interact w/ Files
- Fluid uses cache in compiler, and strings get passed to parser (it doesn't work w/ files)
- TypoScript also parses strings, not files
- Kickstarter
- uses $templatePathAndFilename = resource://TYPO3.Kickstart/Private/...
- shoves into renderTemplate()
- then generateFile()
- File::createDirectoryRecursviely
- uses reflection for php files
- hard codes important paths
- Classes
- Tests
- Resources
- Validate PackageKey ; PackageManager->isPackageAvailable
- TYPO3\Flow\Utility
- Environment
- $this->environment->getPathToTemporaryDirectory()
- Files
- ::getUnixStylePath($cacheDirectory)
- ::concatenatePaths($cacheDirectory)
- ::readDirectoryRecursively($cacheDirectory)
- ::createDirectoryRecursively($cacheDirectory)
- ::emptyDirectoryRecursively($cacheDirectory)
- php funcs
- file_exists($pathAndFillename)
- unlink($pathAndFilename)
- file_get_contents($pathAndFilename)
- file_put_contents($tempCacheEntryPathAndFilename, $data)
- rename($tempCacheEntryPathAndFilename, $newPathAndFilename)
- filesize($cacheEntryPathAndFilename)
- filemtime($file)
- new \DirectoryIterator ($this->cacheDirectory)
- ->valid()
- ->next()
- ->isDot()
- glob($pattern) find pathname matching the pattern
- $fileHandle=fopen($this->logFileUrl, 'ab')
- dirname($logFileUrl)
- is_dir($)
- is_link($)
- stream_get_meta_data($fileHandle)
- fclose($)
- chmod( , )
- touch()
- fputs()
Services
- RoundTrip
- Extension Builder's RoundTrip Service
- Extension Builder uses reflection instead of string magic
- Migration
- Doctrine Migrations
- TYPO3.PackageBuilder
- REST API
- https://twitter.com/bwaidelich/status/338967177292046336 (RESTful efforts in Flow)
- Specs that help with HATEOAS
- JSON API Spec
- JSON for Linked Data Spec
- HAL (Hypertext Application Language) Spec
- HATEOAS question on stackoverflow
- ember.js REST Adapter
- https://www.google.com/#output=search&q=hateoas+vs+uritemplate
Labels:
Boilerplates,
Flow,
FluidBuilder,
GSOC,
Neos,
TYPO3
Thursday, May 30, 2013
Boilerplates and Builders in TYPO3 Neos
I will edit this article to edit the In-Scope and Out-of-Scope sections as needed. I wanted to publish this sooner rather than later.
I produced these images in yED. I can provide the original .graphml files if requested.
GSoC Deliverables
In-Scope for this GSoC
I plan to deliver the following packages:
- TYPO3.BuilderAbstract
- TYPO3.TemplateBuilder
- TYPO3.ZurbBoilerplate
- TYPO3.BootstrapBoilerplate
Important features / components:
- RoundTripService (very basic)
- TemplateBuilder ties into the Fluid parser
- MigrationService (very basic)
- Backend Package Manipulation
- Copy boilerplate package contents into a Deriative package
- Boilerplate Configuration in YAML
- Options layer that allows for multiple "presets" (like in TYPO3.Form). In the context of the TemplateBuilder, those "presets" should be exposed in the UI as a "theme" layer of options.
- File manipulation indicators (a way to say that you inserted a fluid widget at a particular point in a template. These will be stored in the YAML files as Eel/FlowQuery because XPath only works for XML, and we will work with more than XML)
- Fluidify SourceTemplates in TemplateBuilder (the backend for something like TemplaVoila)
Note: These are the names I prefer right now, though they've gone through several iterations. If these are not clear, please let me know. TYPO3.BuilderAbstract used to be called TYPO3.Boilerplate. TYPO3.TemplateBuilder used to be called TYPO3.FluidBuilder. SourceTemplates used to be called RawTemplates, NakedTemplates, or NakedBoilerplates.
Out-of-Scope for this GSOC
I will not have time to work much, if at all, on these:
- Anything that works with TypoScript
- Much of the UI (may be partially working thanks to TYPO3.Ice - but that's not my focus)
- Including the TemplaVoila-like UI to select the various parts of a SourceTemplate file
Package Dependencies
Producing a Derivative Package
I produced these images in yED. I can provide the original .graphml files if requested.
Tuesday, May 28, 2013
Basic Designs for TYPO3.Boilerplate
I'm designing TYPO3.Boilerplate.
Though I could say that Boilerplates and Derivatives have a parent-child relationship, I thought that would suggest a much more dependent or a hierarchical relationship. Derivative Packages should have a copy of everything they need from the Boilerplate. These Derivatives should never depend on Boilerplates. Only Builders that use a particular Boilerplate package should depend on the Boilerplates.
Are there situations where something other than a Builder (or a Kickstarter) can depend on a Boilerplate? One possible situation would be an agency (or maybe even Neos) that has a collection of widgets that they store in a Boilerplate package, and reuse those widgets, without modification, in their site packages. In that case, I suppose they could introduce a dependency in their composer.json, but then they run the risk of upgrading one little thing in their boilerplate only to break things in the dependent site packages. It would be better to copy the widgets into the site packages, and then have a Boilerplate Migration that helps to update site packages from one Boilerplate version to the next. In any case, I don't think there should a technical limitation that prevents the dependency; It'd be one of those only-do-this-if-you-know-what-you're-doing kind of things.
I wonder if TYPO3.Neos.NodeTypes could be considered a Boilerplate package.
Please respond in the comments, or in the Neos forum, and let me know what you think of this design direction.
These HTML/CSS/JS templates that have not been broken into Fluid templates are Naked Boilerplates. For example, Twitter Bootstrap is a Naked Boilerplate. To create a Fluid Boilerplate Package, Twitter Bootstrap gets integrated into some Fluid templates with metadata that tells TYPO3.Boilerplate
The site package that is based on Twitter Bootstrap does not have information about all of the widgets available in the Boilerplate package; Instead, it contains metadata about which parts of the Boilerplates were integrated into it (e.g. which widgets were included in the site or application package). Ideally, the Derivative Package could have enough information to facilitate upgrades from one Boilerplate version to the next (deltas or diffs or steps taken to create the site package from the old boilerplate. These changes would be rebased--like git--on the new version to help with template upgrades).
Consider these basic calculus equations:
If I say that f'(x) is a Fluid Boilerplate package that gets integrated into f(x), a SitePackage, then:
Basics of TYPO3.Boilerplate
- Boilerplate Package[s] (Alternative name: Boilerplate[s]): A package that resides in FlowRoot/Packages/Boilerplates/ which has stuff that may be integrated into another package.
- Derivative Package[s] (Alternative name: Derivative[s] or Boilerplate Derivative[s]): A package that integrates one or more boilerplate packages.
- Naked Boilerplate[s]: The raw materials that makes a boilerplate without the metadata that TYPO3.Boilerplate needs to create Derivative Packages. These are often part of other packages or libraries. A site package might store the designer provided HTML/CSS files somewhere in the Resources.
TYPO3.Boilerplate is not very useful (from a user's perspective) on it's own, but is powerful within a Builder app such as FluidBuilder or PackageBuilder.
Boilerplates and Derivatives
TYPO3.Boilerplate is concerned with copying stuff from a Boilerplate package to a Derivative Package including interfaces to help Builders process or manipulate the files that get copied. Though the builders work with files, they should be able to treat them as objects via TYPO3.Boilerplate APIs.Though I could say that Boilerplates and Derivatives have a parent-child relationship, I thought that would suggest a much more dependent or a hierarchical relationship. Derivative Packages should have a copy of everything they need from the Boilerplate. These Derivatives should never depend on Boilerplates. Only Builders that use a particular Boilerplate package should depend on the Boilerplates.
Are there situations where something other than a Builder (or a Kickstarter) can depend on a Boilerplate? One possible situation would be an agency (or maybe even Neos) that has a collection of widgets that they store in a Boilerplate package, and reuse those widgets, without modification, in their site packages. In that case, I suppose they could introduce a dependency in their composer.json, but then they run the risk of upgrading one little thing in their boilerplate only to break things in the dependent site packages. It would be better to copy the widgets into the site packages, and then have a Boilerplate Migration that helps to update site packages from one Boilerplate version to the next. In any case, I don't think there should a technical limitation that prevents the dependency; It'd be one of those only-do-this-if-you-know-what-you're-doing kind of things.
I wonder if TYPO3.Neos.NodeTypes could be considered a Boilerplate package.
Please respond in the comments, or in the Neos forum, and let me know what you think of this design direction.
Naked Boilerplates and Boilerplate Metadata
In initial designs, I used the term Virtual Boilerplate, but I think Naked Boilerplate is a more appropriate term, because it has templates, but they are missing any boilerplate metadata. It is up to a Builder Package whether or not they support Naked Boilerplates. For some Builders, like PackageBuilder, it won't make much sense. For others, like FluidBuilder (TemplateBuilder?), it makes a lot of sense to support templates that have not been converted into Fluid templates already.These HTML/CSS/JS templates that have not been broken into Fluid templates are Naked Boilerplates. For example, Twitter Bootstrap is a Naked Boilerplate. To create a Fluid Boilerplate Package, Twitter Bootstrap gets integrated into some Fluid templates with metadata that tells TYPO3.Boilerplate
- which Builder to use (FluidBuilder) and
- what stuff is available in the Boilerplate (lists of layouts, widgets, options like changing colors, etc)
The Builder uses that metadata to present a list of stuff to the user. They can then integrate that stuff into their own Derivative Package. FluidBuilder could create fluid templates in an Application package or a Site package using the widgets/options (stuff) that the user chooses from the list of available stuff.
The site package that is based on Twitter Bootstrap does not have information about all of the widgets available in the Boilerplate package; Instead, it contains metadata about which parts of the Boilerplates were integrated into it (e.g. which widgets were included in the site or application package). Ideally, the Derivative Package could have enough information to facilitate upgrades from one Boilerplate version to the next (deltas or diffs or steps taken to create the site package from the old boilerplate. These changes would be rebased--like git--on the new version to help with template upgrades).
Derivative Metadata
Derivative Packages will need metadata about:
- Integrated Boilerplates
- Which Boilerplates have been integrated
- What stuff (layouts/widgets/components) came from a particular Boilerplate (I assume that if it didn't come from the Boilerplate, then it was added by the developer, so care should be taken not to overwrite those changes.)
- How things were integrated (like where widgets were inserted) could use Eel/FlowQuery (my preference) or XPath (which only works on XML-like files, but could be very useful in some cases.)
- Versioning Information to facilitate Migrations
- Kickstarters and Builders might not support migrating from one version of a Boilerplate to the next, but they should store something that says which version of a Boilerplate was used in generating the derivative package.
- Neos and other agencies might provide a Boilerplate package with a collection of widgets that can be added to templates. How/where these widgets are inserted should be carefully recorded, so that changes may be replayed/rebased on any manual template modifications or to facilitate migrating a package from one boilerplate version to the next.
- Builder-specific options
- For example, the FluidBuilder (maybe TemplateBuilder would be a better name) would have a theme layer that uses theming options. If a Boilerplate can be customized with custom colors (think SASS or LESS), then the Builder could expose those options in some kind of interface.
Initial Thoughts on Code
Note: I need to go through Flow's code again to decide which parts can be reused. Possibilities include:
- Configuration (Store all the metadata in yaml files)
- Monitor (File Monitor / Change Detection, Possibly implement ChangeDetectionStrategyInterface to look for specific changes in target files)
- Package (This has some cool stuff, but I can't depend on a package being "activated" before I interact with it, since Builders and Kickstarters will be creating packages. Packages might be broken until a Kickstarter/Builder is finished creating it.)
- Reflection (Possibly only useful in builders that work with PHP...)
- Resource (Could be very helpful, as long as it's not restricted to just the Resources Folder. This needs to be able to interact with any file in a package)
- Utilities (File manipulation stuff)
- Model
- Packages/ (Builders should extend these to provide the business-logic of how to manipulate relevant parts of a Derivative based on metadata from the Boilerplate)
- AbstractPackage implements PackageInterface
- BoilerplatePackage extends AbstractPackage
- DerivativePackage extends AbstractPackage (might be a Site or Applicaiton)
- (Others like library could be implemented at some point if someone needs it, but they might not extend the PackageInterface... I'm not sure on that, and I think it is outside the scope of this project.)
- NakedBoilerplateInterface
- Factories (extended in Builder packages to provide implementation details of how to work with different parts of a package)
- Copy between packages (Boilerplate to Site; Boilerplate to Application)
- Repository (Each package type has a separate repository that extends the basic repository)
- BoilerplateRepository is the collection of BoilerplatePackages
- SitePackagesRepository is a collection of DerivativePackages
- ApplicationRepository is a collection of DerivativePackages
- Service
- RoundTrip service (like PackageBuilder: Detecting changes in watched packages to trigger updates in registered Builders -- Uses FileMonitor)
- Migration service (assists in migrating a Derivative from one Boilerplate version to the next, assuming the boilerplate included migration scripts. For inspiration: Doctrine Migrations, TYPO3CR Migrations, Flow Code Migrations, git rebase and friends)
Boilerplate Math
Calculus is my inspiration for and explanation of how TYPO3.Boilerplate works. I call this, Boilerplate Math.
NOTE: I don't think people need to understand that I got the terms from Calculus to use the Boilerplate API. "Integrate" and "derive" are common enough words, that I think the meaning will be easy enough to understood for anyone who needs to use the Boilerplate API. But, for those that might want to modify Boilerplate, the history of them might come in handy.
Consider these basic calculus equations:
Integrate f'(x) to get f(x) plus some change |
Derive f'(x) from f(x) plus some change |
If I say that f'(x) is a Fluid Boilerplate package that gets integrated into f(x), a SitePackage, then:
Integrate Fluid (f) Boilerplate (B) into SitePackage (P) with Changeset (C) |
Derive Fluid (f) Boilerplate (B) Package (p) from SitePackage (P) with Chagneset (C) |
A SitePackage might use parts from more than one Fluid Boilerplate. For example, it could integrate some widgets from twitter bootstrap as well as widgets from an agency's custom boilerplate that they use for many of their websites.
Saturday, May 25, 2013
Designing TYPO3.Boilerplate
So, I've been thinking about boilerplates in TYPO3 Flow + Neos (it's my GSOC project). After filling up a couple of whiteboards, I started writing stuff in my notebook. I don't expect my notes to mean very much to anyone but me, but I love to see how other people work, so I'm posting all of my notes so that you can see how I work.
edit: I removed the iframe because it was demanding more attention than it deserved. Check the notes out here.
edit: I removed the iframe because it was demanding more attention than it deserved. Check the notes out here.
Labels:
Boilerplates,
Flow,
FluidBuilder,
GSOC,
Neos,
TYPO3
Friday, May 10, 2013
Flow Package Types + Boilerplate Thoughts
So, there are a bunch of different package types for TYPO3 Flow. If you look in the packages folder you'll see several major kinds:
- Distribution/ : The super-package that includes (via composer.json) all the other packages
- Packages/
- Applications: Flow-based apps
- Framework: Flow's packages
- Libraries: 3rd party libs and non-Flow packages
- Sites: Neos site packages
- Boilerplates: Meta-templates (part of my GSOC Proposal) that contain boilerplate files (php code, fluid templates, yaml, ...)
Then, there are some common naming conventions for Flow applications.
- FooKickstarter: for initial creation of packages of type "Foo".
- FooBuilder: to not only create, but edit "Foo" packages.
So, if my GSOC project is only going to be a one-time copy kind of a package, then I need to call it FluidKickstarter. If I give it the ability to edit and not just start templates, like I plan, then it should be called FluidBuilder.
I'm thinking of creating a Boilerplate framework. That way, there'd be a TYPO3.FluidBoilerplate that deals with Fluid specific template manipulation, but the TYPO3.Boilerplate package would contain the more abstract parts of dealing with any Boilerplate package. So that would mean there'd be something like this:
- FooBoilerplate:
- extends TYPO3.Boilerplate to assist builders in building "Foo" packages.
- Not to be confused with packages in the Boilerplates folder, which contain raw material for the Boilerplate system to use in creating various types of packages (by FluidBuilder, PackageBuilder, FormBuilder, etc)
That solution feels awkward. Perhaps, there's a TYPO3.Boilerplate package, like before, that provides the abstract ways of working with Boilerplate packages. Then, the Builder packages would include a server-side layer that interacts with TYPO3.Boilerplate to do the building of packages (Fluid, Package (Flow), Form, Ember). Plus, each Builder package would contain a Frontend app that does the same thing as the backend, but in the browser. Then they would communicate over some RESTful API with Ember Data.
To date, that has been the solution for the other builder projects, so I think that would be a good convention to follow, with one change, in that I'll be using Boilerplate package, and hopefully other Builders will follow suite.
One of the issues with current Builders is that they store all of the template like stuff in their Private Resources folder. That's not very extensible, and though it might work for a lot of the current Builders, it won't work for FluidBuilder because I want there to be a lot of ready-made boilerplates that people can use to create whatever site they want as fast as they want. They should be able to make their own, or use Twitter Bootstrap, or H5BP, or whatever other grid system they enjoy.
Why? Flow is already fun for developers, but it needs to attract designers. So, Neos should be fun for designers to use, and Boilerplate packages are a good way to get there.
Labels:
Boilerplates,
Flow,
FluidBuilder,
GSOC,
Neos,
TYPO3
Location:
Fairpark, Salt Lake City, UT, USA
Ice and PackageBuilder and Boilerplates, Oh my!
So, I was just browsing github, and stumbled on TYPO3.Ice (ICE=Interface Construction Environment). Looking around, there's also a project on forge, and a git.typo3.org repo. I wanted to make sure it wasn't a previous effort to build TYPO3.FluidBuilder (my GSOC proposal), so I asked Rens on IRC what Ice was all about.
Resources/Private/Generator could become Boilerplate packages in SiteKickstarter and Kickstart. Resources/Private/NewFormTemplates in FormBuilder could also be a Boilerplate, though one yaml file might not warrant it, so it could be treated like a virtual boilerplate. Potentially, other people could create Form boilerplates, though.
TYPO3.PackageBuilder
Apparently, it's part of the effort to create a TYPO3.PackageBuilder (see the github project, the forge project, and the git.typo3.org repo). PackageBuilder is like the next generation of the ExtensionBuilder that we know and love from TYPO3 CMS. It'll have a domain building UI, so that you can graphically create your domain objects and link them all together. I'm very excited to see someone working on the PackageBuilder.
TYPO3.Ice in TYPO3.PackageBuilder
PackageBuilder needs a UI similar to TYPO3.FormBuilder, so some of that interface was abstracted out, so that they could be reused in multiple packages. That common UI lives in TYPO3.Ice.
TYPO3.FluidBuilder
The best part of that? I'll probably be able to use TYPO3.Ice when I create TYPO3.FluidBuilder for a GSOC project. Maybe it'll be possible for me to create the UI portion in FluidBuilder after all, since it's mostly built for me already.
Boilerplates in TYPO3.PackageBuilder
Plus, looking through PackageBuilder's code, it looks like PackageBuilder could use the Boilerplate concept as well. Right now, there's Resources/Private/CodeTemplates. They've got both TYPO3 CMS and Flow templates, which could be put in separate boilerplate packages, so that you don't have to update the whole PackageBuilder package every time one of the boilerplates gets updated. Plus, then other organizations could create their own Flow Package Boilerplates, and use PackageBuilder to create packages with them.
Resources/Private/Generator could become Boilerplate packages in SiteKickstarter and Kickstart. Resources/Private/NewFormTemplates in FormBuilder could also be a Boilerplate, though one yaml file might not warrant it, so it could be treated like a virtual boilerplate. Potentially, other people could create Form boilerplates, though.
I'm very glad that I found out about Ice and PackageBuilder. It looks like my GSOC project will be very useful indeed (who wants their work to die and rot unused in the backroom?!). I hope that the Boilerplate concept, and the FluidBuilder will help more people to start using Flow and get involved with Neos.
Labels:
Boilerplates,
Flow,
FluidBuilder,
GSOC,
Neos,
TYPO3
Location:
Fairpark, Salt Lake City, UT, USA
Friday, May 3, 2013
Neos (dev-master) Hints
I'm using Neos from dev-master. Here are some things I've run up against with my group.
Workspaces
You can see and work in anyone's workspace, not just your own. If you want to work in the same workspace with someone, just edit the url.
@ in a Neos URL tells you what workspace you're looking at or using. For example, this shows that I'm in cognifloyd's workspace (hey, that's me!).
If I wanted to see the workspace for user john316 I would replace "@user-cognifloyd" with "@user-john316". Eventually, there will be some kind of access control to say which users can interact with which workspaces, but for now, once you're logged in, everything's fair game.
One way to use this is to share a workspace with a group of colleagues. Before I found this, we would each publish our changes (move them live) every time we wanted to share our work. This way, we can all work in the same workspace, and publish it live when everyone has finished their part.
Wireframe Mode
Resizing images in wireframe mode is currently broken.
Sections don't show up reliably until you've got content in them.
When you aren't in wireframe mode, you can just drag-n-drop elements to re-organize them. However, this feature isn't in wireframe mode. Instead, click "Inspect" in the lower left hand corner. You can rearrange the elements in there.
When you add a page, be sure to edit the nodepath in the right hand properties bar or you'll get some ugly urls. Neos doesn't seem to be automatically creating the nodepath based on the page name yet.
Subscribe to:
Posts (Atom)