keys.php

<?php
return array (
  'TODO.Scanner' => '- allow configuration of the prefix regex 
- Class property to auto-merge with built-in prefixes 
    - As an alternative to overriding getApiPrefixes() 
- Document how to use prefixFor()',
  'TODO.RouteObject' => '- Document the route object',
  'TODO.View' => '- Config to set a namespace for all views of a given package
- perhaps $lia should be a required paramater, not hidden in an array
- Add an init + template approach like `view/Blog/template.php` and `view/Blog/init.php`
- Add automatic routing via the view system (which is more robust and neat than simple public-files), such as with a `public-view` dir 
    - a `<lia-route pattern="/"> might be a valid option, but that seems more like an extension feature than a core feature
- Document what paramaters are always available to views
- Document an example of a view file\'s code (such as the example blog.php view)
- For sibling resource files (view/blog.php, view/blog.css, view/blog.js), resources() returns \'.js\' and \'.css\' for the resource files. 
    - Maybe they should have real names? But the current setup prevents conflicts between view/blog.css and view/blog/blog.css
- Document resources() function & returned array',
  'Old.View.Base' => '## The View Object
- Each package can implement their own view object and method of handling data. The following docs regard \\Lia\\View, used in the base package.
- Generally, retrieve a view through liaison or the ViewHandler component.  
   - You may also do `new \\Lia\\View($viewPath,$data,$liaisonObject,$viewName=null)`, such as if you\'re creating your own package implementation.
- Data passed in (through lia OR the constructor) will be `extract()`ed
- The content is loaded in the constructor
- Resources are loaded into liaison during the constructor. So you just call $lia->view($viewName), if all you want is to use the associated css & javascript resources.
Display your view with `echo $view`

### View Structure
We have a view named "Form/Blog" at `view/Form/Blog/`. All your views go in the `view` directory and the path to the relative path to the view is it\'s name.
```
view/Form/Blog/
 - init.php: (optional) code to run before the template
 - template.php: (recommended) The PHP file to load, this is your html layout for the most part
     - template.php & init.php are in the scope of the \\Lia\\View object that loads the files. Therefore, `$this` refers to the view object
     - $lia, the Liaison object, is also available
     - Uninentionally, $viewPath, $data, $viewName, & $path are available, but you should not rely on them. They will likely be removed.
 - template.html: If a template.php file is not present, then template.html will be used.
 - css/ (optional)
     - BlogEditorStyle.css
 - js/ (optional)
     - BlogAutosaver.js
```
You don\'t actually have to have a template. css & js resources will still load

Every css file in the css dir will be found and added to liaison through the `Red_AddStyleFile` event, which passes the absolute file path along to the event.
Same for js, but `Res_AddScriptFile`.  ',
  'Utility.FancyClosure.TODO' => '@TODO add check to see if a callable is actually callable
@TODO setup read-only properties',
  'Utility.FancyClosure' => 'Fancy closures enable binding of paramaters to a callable and inspection of callables, whether as `[\'\\\\StaticClass\',\'functionName\']`, `[$object, \'methodName\']`, or `$anonymousFunction = function(){}`.
Example:  
```php
$cat = new \\Funny\\Cat();
$loudness = 7;
$closure = new \\Lia\\Utility\\FancyClosure([$cat, \'purr\'], [$loudness]);
$closure->funcName === \'purr\';
$closure->object === $cat;
$closure->class === \'Funny\\\\Cat\'; //it prints with a single slash, but backslashes are generally better off being escaped in my experience
$closure->isStatic === false; // would be true if using [\'Funny\\Cat\', \'purr\'] instead of [$cat, \'purr\']
$closure->isAnonymous === false; // would be true for function(){echo \'Kindness can be anonymous too.\';}
$closure->function === null; // would be the anonymous function, if you had passed a function instead of an `[$obj, \'funcName\']` callable

$closure->origCallable === [$cat, \'purr\']; //just the first arg you pass to the constructor
$closure->bound === [$loudness]; // and this is the 2nd arg
```',
  'TODO.Package' => '- Implement an \'api name\' for retrieving packages, prefixing view names, public files, etc
- Revisit lifecycles. There\'s a lifecycle component, but that doesn\'t really handle packages... Idunno. I\'m confused by it

OLD NOTES
- document the public dir
- document the file-to-pattern conversion
- document url normalization
- Document changing the view class
- Document general package usage
- Document creating a custom package',
  'Usage.Router.publicDir' => 'Files in the `public` dir of your package will be automatically routed to.
- `public/index.php` files will be delivered without the file name or extension
- `public/dir/file.php` files will be delivered at `/dir/file/`
- `public/resource.js` and other non `.php` files will be delivered at `/resource.ext`

There\'s much more to document and features to set up with routing, still. ',
  'Usage.Package.DefaultConfigs' => 'protected $config = [
    \'dir\'=>
        [
            \'component\' => \'core\',
            // \'public\' => \'public\',
            \'autoload\'=> \'class\',
            \'view\' => \'view\',
            \'cache\' => \'cache\',

            \'public\'=>[  // @TODO rethink config structure. public maybe shouldn\'t be nested under dir? Idk....
                \'dir\' => \'public\',
                \'baseUrl\'=> \'\',
            ]
        ],
    
    \'route\'=>
        [
            \'force_trail_slash\'=>true,
            \'index_names\'=>
            [
                \'index\'
            ],
            \'hidden_extensions\'=>
            [
                \'php\'
            ],
        ],
    \'class\'=>
        [
            \'view\' => \'\\\\Lia\\\\Obj\\\\View\'
        ],
    \'views\'=>
        [
            // \'conflict\' => \'throw\'
        ]
];',
  'TODO.Autoload' => '- Add classmap-autoloading method (currently only PSR4 is supported, I think)
- Cache autoloader classmap to disk',
  'TODO.Error' => '- Figure out how to do error handling...',
  'Usage.GlobalParams' => 'Call `$lia->addGlobalParam($argName, $value);`, then in your views and public files `$argName` will be available.',
  'TODO.Resources' => 'Maybe not so difficult
- Use config for default site title
- move SEO code into it\'s own component
- Auto-add charset=utf8 & viewport meta tags (with config to disable)
- Add url prefix for compiled files as a config option

Maybe not so simple
- Consider using custom routes instead of storing files in a cache-public dir
- jsFiles & cssFiles arrays have the full file path as their key & value. Add ability to name the paths. This will improve dev experience when sorting a list of scripts/stylesheets
- Improve sorting
    - add sort preference to `addResourceFile($file)`. A Liaison extension that adds a JS framework would use this to ensure it\'s framework file is always the first thing.
        - Without this, the sort burden is on the developer who is integrating the Liaison extension.
    - Add a simple function for setting sort preferences, like $lia->showFirst(\'*autowire.js\'); or something
- Consider other methods of routing that might improve performance...
- add all seo meta properties that are available...
- Separate large files from the block of compiled code. 
     - If i\'m using a, say, 50KB or larger JS file on 10 different pages, but each of those pages has a couple different small JS files for their individual components, it\'s probably better to cache the 50KB file on its own
- Minify js & css',
  'TODO.Router' => 'Documentation
- Document the paramaters that are passed to a public file
- document examples of routing
- improve \'Pattern Rules\' documentation

Essentials
- figure out sitemaps... Though that may not be part of router??
- add... something to help convert pattern-based routes to sitemap representations

Performance
- caching of urls & routes

Other
- auto-add `public` dir for each package
   - Right now, the package handles this. Should the Router be able to process a directory? (probably)
- add a function to convert a file path to a pattern (aka, remove extensions like \'.md\' and \'.php\', per a configuration)
- add a normalizeUrl function (add trailing slash, remove .php / .html / .md, all lowercase?)
- Option to return both perfect-match routes AND routes that match with the normalized url, aka: /some/url && /some/url/ would return the same route(s)
- add a mediator function to handle multiple global routers, possibly??',
  'Usage.Router.addRoute' => 'Call `$lia->addRoute($pattern, $callbackOrFile,$package=null)` to add a route to the built-in router

```
@param $pattern A pattern. See [the pattern matching rules](@link(Rules.Router.pattern))
@param $callbackOrFile a callback or a file path
@param $package (optional) A liaison package
```',
  'Usage.Router.getRoute' => '',
  'Rules.Router.pattern' => '```
rules:
    .php will generally be removed & replaced with a trailing slash, but that is NOT part of parsePattern()
    That will be a pattern-normalization step that happens prior to parsePattern() and is extensible/configurable

    Methods: @POST, @GET, @PUT, @DELETE, @OPTIONS, @TRACE, @HEAD, @CONNECT
        - We do not currently check the name of the method, just @ABCDEF for length 3-7
        - These must appear after a `/` or after another \'@METHOD.\' or they will be taken literally
        - lower case is not valid
        - Each method MUST be followed by a period (.)
        - example: /@POST.dir/sub/@GET.file/ is valid for both POST /dir/sub/file/ and GET /dir/sub/file 

  Paramaters:
      - {under_scoreCamel} specifies a named, dynamic paramater
      - {param} must be surrounded by path delimiters (/) OR periods (.) which will be literal characters in the url
      - {param} MAY be at the end of a pattern with no trailing delimiter
      - {paramName:regex} would specify a dynamic portion of a url that MUST match the given regex. 
          - Not currently implemented
      - {?param} would specify a paramater that is optional
          - Not currently implemented
    examples: 
        /blog/{category}/{post} is valid for url /blog/black-lives/matter
        /blog/{category}.{post}/ is valid for url /blog/environment.zero-waste/
        /blog/{category}{post}/ is valid for url /blog/{category}{post}/ and has NO dynamic paramaters
```',
  'TODO.Server' => '- Graceful fallback for when view() is not available
- Graceful fallback for when \'theme\' view is not available
- When route is a callable, should the callable output content or should it return content that is echo\'d by Server?',
  'TODO.ViewComponent' => '- document the use of a view that does NOT implement Lia\\IView
- implement & document adding a view by simple file path',
  'TODO.Cache' => '- Consider adding defaultExpiry as a config, rather than a default paramater in the cacheFile() function call
- Add a key=>value cache that returns values instead of file paths
- probably auto-delete if an expired file is requested
- Possibly add `lia.cacheDir.public` & `lia.cacheDir.public.baseUrl` to assist in routing
- Are these the same thing?
    - Consider function to return file content, not just file path. Consider additional decoding like parsing json or yaml.
    - Consider adding type-based processing (PHP, JSON, DOMDocument??)
    - Consider extensible features (such as auto en/decoding additional types not supported by Liaison)
- cache response of getCacheFile() so files don\'t have to be loaded more than once',
)
?>