fancy's Introduction
fancy's People
Forkers
designashirtfancy's Issues
Create getting-started tutorial for v1 and v2
Without documentation, it's impossible/annoying to get started. A brief walkthrough would remedy this until complete docs can be built
In theme helper, it's not possible to get page by id or any or property
Can probably be considered related to #4
In the theme helper js, there is not a good way to retrieve another page by id or any other property. Attempting to use ctx.uses()
works in the ejs data, but fails from the theme and always complains about an invalid key.
The theme should have minimal dependence on content for portability sake, but this issue doesn't make sense when the ejs file has no problems retrieving pages.
The workaround is to do uses()
from the ejs and pass that result into your theme function.
No way to resolve a page by id?
The way to resolve a page by id is not obvious. This is a common use-case e.g. <a title="Go to home page" href="<%= findPageById('home').url() %>">
and it should be simplified.
Currently, the way to do this is:
<% uses('id', 'home').as('homePages') %>
<a href="<%= homePages[0].url() %>">
But that is not possible because of #3, which means there is currently no way to do this.
i18n needs to be revisited
Instead of rolling own, should use one of the many mature libraries that exist now.
Components need some improvement
Components for data work pretty well, but the signature they use isn't great.
I also find myself doing string concat for html, which isn't great. Replace with something like HyperScript?
uses() returns a Collection and it's really buggy; needs to be rewritten
The Collection object returned by uses()
doesn't really work right and is incomplete.
Calling .url()
on any of the items it contains leads to an undefined error but doing collection.forEach(function(page) { page.url() })
works. o.0
Collection should be rewritten because it contains numerous problems.
Config - mount constraints should support regex on the key but don't
config.data.mount[target][$key]
$key is supposed to support regex but it does not. Instead, it looks like I mistakingly implemented the regex matching one level up at the target level -- which is not suposed to support regex.
If a regex key constraint is used the mount will always fail because it is looking for a property name that literally matches they key value i.e. <meta key="(some|thing)" value="">
instead of <meta key="some" value="">
or <meta key="thing" value="">
theme context print(this) fails
Doing <%- print(this) %>
will fail with an error because of circular references. The default error page will include the contents of print(this) in the message, but it'd be nice to be able to do it without an error.
Theme js helper file should be watched/reloaded
When changes are made to the theme js helper file (during dev) it requires a server restart before the changes take effect. This can make dev tedious.
Content directories should not require .html extension
Requiring an .html extension on a content directory is unnecessary, confusing, and problematic in certain situations. Should instead give content directories a special extension like [directory].content or whatever.
Components not watched/reloaded and require server restart
The changes made to components js files (during dev) are not watched and a server restart is required before the changes take effect. These files should automatically trigger a reload like editing content data.
Components need to be user configurable
There needs to be a way to configure components globally in user land. Currently, the only way to pass settings into components is through usage. There should be some way to add it to the fancy.json file or something.
Usecase example: A grid component that could accept a framework setting globally (e.g. bootstrap) and whatever framework is used in the theme could be configured.
(This is another step toward completely isolating data from theme.)
Support for objects in html? Feature?
All content types except html support complex data i.e. body = { some: true, thing: { wee: 1 } }
.
Because html defines properties as <meta
key/value, there is no way to do the same; which is probably fine for <body>
but more annoying for other properties.
It might be nice to allow something like this:
<meta key="blog:title" value="This is the blog title">
<meta key="blog:byline" value="Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod">
<meta key="blog:category" value="Editorial">
<meta key="blog:category" value="Rants">
To automatically be expanded into this:
page.blog = {
title: 'This is the blog title',
byline: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod',
category: [ 'Editorial', 'Rants' ],
}
This would allow page data to be better organized instead of a flat dictionary of key/val.
If multiple route values exist page.url() returns a comma concat list
<meta key="route" value="/one">
<meta key="route" value="/two">
template
<a href="<%= page.url() %>">should be "/one" but is instead "/one,/two"</a>
Workaround is to specify a urlTemplate
which overrides route <meta key="urlTemplate" value="/one">
Or to use an array index page.url()[0]
Or to use a theme helper theme.url(page)
-> url(page) => { return page.url()[0]; }
Static assets with paths that collide with routes redirect
If a static asset path has a name that collides with a route (e.g. ..../assets/blog/ and route /blog), it will cause express to always redirect to a trailing slash.
The dependency on express' static asset handler should be dropped and a custom middleware should be built.
Templates with uses() require double rendering - This should be redesigned
In order to eval the uses()
calls, template need to be rendered. This means that templates with uses calls are rendered once to interpret those calls, and then re-rendered (with the resolved uses) in order to actually render the content.
This means that attempting to access property values of a uses-resolved object directly will result in undefined errors during this initial pre-render even though <%- print() %>
will display correct output.
The errors mentioned in #3 are actually because of this issue.
Instead of building uses into ejs, it might be better to create a new feature here that would eliminate the need to double-render.
Instead of this in the ejs template:
<% uses('id', 'home').as('homePage') %>
It might be better to invent new markup like:
<$ uses('id', 'home').as('homePage') $>
And then we can just grep for those values and resolve them ahead of the initial render.
This would also allow for a tweak in the signature a bit since I hate this as()
which is pretty much always required. This is way nicer and easier to immediately understand: <$ homePage = uses('id', 'home') $>
Symlinks
Fancy doesn't support symlinks, but they're highly desirable. Slowly adding support.
Components should be installable with npm
Fancy assumes components are written by the user and included alongside the rest of the site code.
This severely limits reusability.
Components should support being installed in node_modules and the normal components directory.
This would probably do the job: try { require('some-fancy-component'); catch (err) { require('./components/some-fancy-component/index.js') }
Config - Unmet mount option constraints lead to error
If a mount constraint is configured and not met, fancy serve
will die with error Error: E.bubble callback called twice
.
It should instead output a friendly message that some content does not match a configured constraint. (Ideally it'd include the exact config line).
Repro:
- Add to fancy.json
{
"data": {
"mount": {
"blog": {
"route": "^/blog/.*",
"(author|title)": "^(.{10,}|.{0})$",
"body": "!<a[^>]+?href=\"http:[^\"]+?\""
}
}
}
}
- Create some new content with a matching resource
// ./content/data/blog/whatever.html
<meta key="route" value="/some-blog-post">
- In the content, don't include
<meta key="author" value="something">
ejs partials should have simplified var sharing
there should be a way to pass vars to partials though in a way that's easy to use:
<%- partial('foo', { something: 'whatever' }) %>
foo.ejs
<p><= something || 'nothing' %></p>
that won't work if something is undefined, but it should.
Add error messages for various local serving states
Various things can lead to fancy serve
getting stuck at 99% loading of pages.
Usually it is one of two things:
- A page has invalid properties e.g. dupe route/url
- Downstream fancy dependency broken (node sqlite is almost always the cause)
When init'ing need to catch these errors and die with a friendly error message and resolution steps.
Use json schema internally
The model the the template page receives has all properties wrapped in arrays. The reason being that the properties all behave identically.
In practice, this has as many problems as it solves. The theme is "dev land" anyway, so they understand type
and can tell the diff between an array and string.
JSON schema would help the theme know what type of data they were dealing with.
ejs theme of undefined should not result in text "undefined" being written
When using an undefined variable in ejs <%= page.some_undefined_var %>
it writes "undefined".
Undefined should result in an empty string.
Build is tripped up by multiple routes
Multiple routes are used as comma concat strings e.g. "/one,/two" instead of "/one" AND "/two"
Related to #14
ejs context is not frozen and can cause confusion
it's possible to do:
<%
this.something = 'whatever';
%>
that will work and persist across all contexts. it won't be cleared until server restarts. either this
should be read-only or it should be recreated from scratch each view.
probably read-only since all the different partials using a defacto global will be hard to debug.
Non-regex mount point is not strict on matching
Because of #20 incorrectly adding regex to the mount point name, it causes the mount to be a broad match e.g. data.mount["blog"] will match:
- ./data/content/blog
- ./data/content/blog-authors
- ./data/content/blog-anything-because-it-just-prepends-^-to-value-and-treats-it-as-regex
When #20 is closed this can probably be closed too. In the meantime, the workaround is to invert names of secondary directories that shouldn't match e.g. blog-authors => authors-blog
Components need access to the main console logger (bunyan)
There is no way to log info from a component except for console.*
. The logger should be available to the component.
Subdirectories in symlinks not followed
Symlink is a handy way to include assets from dependencies but they're not followed e.g.
- assets
- some-symlink
- subdir
- another.png
not copied
- another.png
- file.png
copied
- subdir
- some-symlink
Production-worthy components
- There are some third-party libs that do server components. Research and replace homebrewed implementation with best option.
- Frame future support of GUI desktop editor for components (so components could implement their own ui in some future wysiwyg editor)
- Components should be able to inject values into model available to theme. (Maybe a create a new standard components object/namespace for theme?) usecase: clientside SPA/web component that needs a clientside js lib injected into the page to function. e.g. google maps
- npm-installable components #27
Globals are only global within template
The globals.json file can contain static information that is available globally from within the template only.
This is a bit confusing. The file/feature should be renamed or globals should be available truly everywhere -- including content.
Shipping fancy with a built-in component for reading globals would work and also serve as an example for how to write your own.
Remove include method of including partial views from theme
There are two ways to include a partial view:
- Standard ejs way:
<% include ... %>
- Fancy context way:
<%- partial(...) %>
When getting started with fancy, this is very confusing. And it also seems to have some quirks/problems as with #23
It might be better just to remove include
and always use partial
.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.