Skip to content

Commit

Permalink
feature(assets): Move all core static assets to views
Browse files Browse the repository at this point in the history
Fixes #5105
  • Loading branch information
ewinslow committed Jun 16, 2015
1 parent 4e72de0 commit c44740d
Show file tree
Hide file tree
Showing 78 changed files with 269 additions and 176 deletions.
2 changes: 1 addition & 1 deletion docs/conf.py
Expand Up @@ -125,7 +125,7 @@ def setup(app):
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
html_favicon = '../_graphics/favicon.ico'
html_favicon = '../views/default/favicon.ico'

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
Expand Down
4 changes: 2 additions & 2 deletions docs/guides/javascript.rst
Expand Up @@ -160,7 +160,7 @@ In your PHP ``init, system`` event handler, you can use ``elgg_define_js()`` to
<?php
elgg_define_js('underscore', [
'src' => elgg_get_simplecache_url('js', 'underscore.js'),
'src' => elgg_get_simplecache_url('js/underscore.js'),
]);
.. note::
Expand All @@ -187,7 +187,7 @@ setting ``exports`` and optionally ``deps``:
// set the path, define its dependencies, and what value it returns
elgg_define_js('jquery.form', [
'src' => elgg_get_simplecache_url('js', 'jquery.form.js'),
'src' => elgg_get_simplecache_url('js/jquery.form.js'),
'deps' => array('jquery'),
'exports' => 'jQuery.fn.ajaxForm',
]);
Expand Down
2 changes: 1 addition & 1 deletion docs/guides/services.rst
Expand Up @@ -23,7 +23,7 @@ burden of supporting older Elgg versions, we encourage you to continue using the
Service: config
---------------

An instance of ``Elgg\Services\ConfigInterface``, this is for getting and setting various system
An instance of ``Elgg\Services\Config``, this is for getting and setting various system
configuration values.

.. note::
Expand Down
18 changes: 9 additions & 9 deletions docs/guides/views/simplecache.rst
Expand Up @@ -6,9 +6,11 @@ Simplecache
- :doc:`/admin/performance`
- :doc:`/guides/views`

The Simplecache is a mechanism designed to alleviate the need for certain views to be regenerated dynamically. Instead, they are generated once, saved as a static file, and served in a way that entirely bypasses the Elgg engine.
The Simplecache is a mechanism designed to alleviate the need for certain views to be regenerated dynamically.
Instead, they are generated once, saved as a static file, and served in a way that entirely bypasses the Elgg engine.

If Simplecache is turned off (which can be done from the administration panel), these views will be served as normal, with the exception of site CSS.
If Simplecache is turned off (which can be done from the administration panel),
these views will be served as normal, with the exception of site CSS.

The criteria for whether a view is suitable for the Simplecache is as follows:

Expand Down Expand Up @@ -38,13 +40,11 @@ You can register a view with the Simplecache with the following function at init
**Accessing the cached view**

If you registered a JavaScript or CSS file with Simplecache and put in in the view folder ``js/your_view`` or ``css/your_view`` you can very easily the the url to this cached view by calling
If you registered a JavaScript or CSS file with Simplecache and put in in the view folder
``js/your_view.js`` or ``css/your_view.css`` you can very easily get the url to this cached view by calling
``elgg_get_simplecache_url($view)``. For example:

.. code:: php
$url = elgg_get_simplecache_url($type, $view)
Where:

- ``$type`` is js or css
- ``$view`` the view name after css/ or js/
$js = elgg_get_simplecache_url('js/your_view.js');
$css = elgg_get_simplecache_url('css/your_view.css');
74 changes: 63 additions & 11 deletions engine/classes/Elgg/Application/CacheHandler.php
Expand Up @@ -46,11 +46,15 @@ public function handleRequest($path) {
if (!$request) {
$this->send403();
}

$ts = $request['ts'];
$view = $request['view'];
$viewtype = $request['viewtype'];

$this->sendContentType($view);
$contentType = $this->getContentType($view);
if (!empty($contentType)) {
header("Content-Type: $contentType", true);
}

// this may/may not have to connect to the DB
$this->setupSimplecache();
Expand Down Expand Up @@ -200,22 +204,70 @@ protected function sendCacheHeaders($etag) {
}

/**
* Send content type
* Get the content type
*
* @param string $view The view name
* @return void
*
* @return string?
*/
protected function sendContentType($view) {
$segments = explode('/', $view, 2);
switch ($segments[0]) {
case 'css':
header("Content-Type: text/css", true);
break;
protected function getContentType($view) {

$extension = $this->getViewFileType($view);

switch ($extension) {
case 'gif':
case 'png':
case 'webp':
case 'bmp':
case 'tiff':
case 'jpeg':
return "image/$extension";

case 'jpg':
return "image/jpeg";

case 'ico':
return 'image/x-icon';

case 'svg':
return 'image/svg+xml';

case 'js':
header('Content-Type: text/javascript', true);
return 'application/javascript';

case 'css':
case 'html':
case 'xml':
return "text/$extension";

default:
break;
}
}

/**
* Returns the type of output expected from the view.
*
* - view/name.extension returns "extension"
* - css/view views return "css"
* - js/view views return "js"
* - Otherwise, returns "unknown"
*
* @param string $view The view name
* @return string
*/
private function getViewFileType($view) {
$extension = (new \SplFileInfo($view))->getExtension();
if ($extension) {
return $extension;
}

if (preg_match('~(?:^|/)(css|js)(?:$|/)~', $view, $m)) {
return $m[1];
} else {
return 'unknown';
}
}

/**
* Get the contents of a view for caching
Expand All @@ -228,7 +280,7 @@ protected function sendContentType($view) {
protected function getProcessedView($view, $viewtype) {
$content = $this->renderView($view, $viewtype);

$hook_type = _elgg_get_view_filetype($view);
$hook_type = $this->getViewFileType($view);
$hook_params = array(
'view' => $view,
'viewtype' => $viewtype,
Expand Down
50 changes: 35 additions & 15 deletions engine/classes/Elgg/Cache/SimpleCache.php
Expand Up @@ -49,30 +49,50 @@ function registerView($view_name) {
}

/**
* Get the URL for the cached file
* Get the URL for the cached view.
*
* This automatically registers the view with Elgg's simplecache.
* Recommended usage is to just pass the entire view name as the first and only arg:
*
* ```
* $blog_js = $simpleCache->getUrl('js/blog/save_draft.js');
* $favicon = $simpleCache->getUrl('favicon.ico');
* ```
*
* @example
* $blog_js = elgg_get_simplecache_url('js', 'blog/save_draft');
* elgg_register_js('elgg.blog', $blog_js);
* elgg_load_js('elgg.blog');
* For backwards compatibility with older versions of Elgg, you can also pass
* "js" or "css" as the first arg, with the rest of the view name as the second arg:
*
* @param string $type The file type: css or js
* @param string $view The view name after css/ or js/
* ```
* $blog_js = $simpleCache->getUrl('js', 'blog/save_draft.js');
* ```
*
* Note that with this older approach, there is no way to access cached views
* outside of the js/ or css/ folders.
*
* This automatically registers the view with Elgg's simplecache.
*
* @param string $view The full view name
* @param string $subview If the first arg is "css" or "js", the rest of the view name
*
* @return string
*/
function getUrl($type, $view) {
// handle file type passed with view name
if (($type === 'js' || $type === 'css') && 0 === strpos($view, $type . '/')) {
$view = substr($view, strlen($type) + 1);
function getUrl($view, $subview = '') {
// handle `getUrl('js', 'js/blog/save_draft.js')`
if (($view === 'js' || $view === 'css') && 0 === strpos($subview, $view . '/')) {
$view = $subview;
$subview = '';
}

// handle `getUrl('js', 'blog/save_draft.js')`
if (!empty($subview)) {
$view = "$view/$subview";
$subview = '';
}

elgg_register_simplecache_view("$type/$view");
return _elgg_get_simplecache_root() . "$type/$view";
// should be normalized to canonical form by now: `getUrl('js/blog/save_draft.js')`
elgg_register_simplecache_view($view);
return $this->getRoot() . $view;
}


/**
* Get the base url for simple cache requests
*
Expand Down
2 changes: 0 additions & 2 deletions engine/classes/Elgg/ViewsService.php
Expand Up @@ -432,8 +432,6 @@ public function registerCacheableView($view) {
* @access private
*/
public function isCacheableView($view) {


if (!isset($this->CONFIG->views)) {
$this->CONFIG->views = new \stdClass;
}
Expand Down
2 changes: 1 addition & 1 deletion engine/classes/ElggEntity.php
Expand Up @@ -1453,7 +1453,7 @@ public function getIconURL($params = array()) {

$url = _elgg_services()->hooks->trigger('entity:icon:url', $type, $params, null);
if ($url == null) {
$url = "_graphics/icons/default/$size.png";
$url = elgg_get_simplecache_url("icons/default/$size.png");
}

return elgg_normalize_url($url);
Expand Down
8 changes: 4 additions & 4 deletions engine/lib/admin.php
Expand Up @@ -204,7 +204,7 @@ function _elgg_admin_init() {
if (elgg_get_config('elgg_maintenance_mode', null)) {
elgg_register_plugin_hook_handler('route', 'all', '_elgg_admin_maintenance_handler', 600);
elgg_register_plugin_hook_handler('action', 'all', '_elgg_admin_maintenance_action_check', 600);
elgg_register_css('maintenance', elgg_get_simplecache_url('css', 'maintenance'));
elgg_register_css('maintenance', elgg_get_simplecache_url('css/maintenance'));

elgg_register_menu_item('topbar', array(
'name' => 'maintenance_mode',
Expand Down Expand Up @@ -245,10 +245,10 @@ function _elgg_admin_init() {
elgg_register_action('profile/fields/reorder', '', 'admin');

elgg_register_simplecache_view('css/admin');
$url = elgg_get_simplecache_url('js', 'admin');
$url = elgg_get_simplecache_url('js/admin');
elgg_register_js('elgg.admin', $url);
elgg_register_js('elgg.upgrades', 'js/lib/upgrades.js');
elgg_register_js('jquery.jeditable', elgg_get_simplecache_url('js', 'jquery.jeditable.js'));
elgg_register_js('jquery.jeditable', elgg_get_simplecache_url('js/jquery.jeditable.js'));

// administer
// dashboard
Expand Down Expand Up @@ -358,7 +358,7 @@ function _elgg_admin_init() {
*/
function _elgg_admin_pagesetup() {
if (elgg_in_context('admin')) {
$url = elgg_get_simplecache_url('css', 'admin');
$url = elgg_get_simplecache_url('css/admin');
elgg_register_css('elgg.admin', $url);
elgg_load_css('elgg.admin');
elgg_unregister_css('elgg');
Expand Down
63 changes: 20 additions & 43 deletions engine/lib/cache.php
Expand Up @@ -100,57 +100,34 @@ function elgg_register_simplecache_view($view_name) {
}

/**
* Get the URL for the cached file
* Get the URL for the cached view.
*
* This automatically registers the view with Elgg's simplecache.
*
* @example
* $blog_js = elgg_get_simplecache_url('js', 'blog/save_draft');
* elgg_register_js('elgg.blog', $blog_js);
* elgg_load_js('elgg.blog');
* Recommended usage is to just pass the entire view name as the first and only arg:
*
* @param string $type The file type: css or js
* @param string $view The view name after css/ or js/
* @return string
* @since 1.8.0
*/
function elgg_get_simplecache_url($type, $view) {
return _elgg_services()->simpleCache->getUrl($type, $view);
}


/**
* Get the base url for simple cache requests
* ```
* $blog_js = elgg_get_simplecache_url('js/blog/save_draft.js');
* $favicon = elgg_get_simplecache_url('favicon.ico');
* ```
*
* @return string The simplecache root url for the current viewtype.
* @access private
*/
function _elgg_get_simplecache_root() {
return _elgg_services()->simpleCache->getRoot();
}

/**
* Returns the type of output expected from the view.
*
* css/* views always return "css"
* js/* views always return "js"
* For backwards compatibility with older versions of Elgg, this function supports
* "js" or "css" as the first arg, with the rest of the view name as the second arg:
*
* @todo why isn't this in the CacheHandler class? It is not used anywhere else.
*
* @todo view/name.suffix returns "suffix"
* ```
* $blog_js = elgg_get_simplecache_url('js', 'blog/save_draft.js');
* ```
*
* Otherwise, returns "unknown"
* Note that with this older approach, there is no way to access cached views
* outside of the js/ or css/ folders.
*
* @param string $view The view name
* This automatically registers the view with Elgg's simplecache.
*
* @param string $view The full view name
* @param string $subview If the first arg is "css" or "js", the rest of the view name
* @return string
* @access private
* @since 1.8.0
*/
function _elgg_get_view_filetype($view) {
if (preg_match('~(?:^|/)(css|js)(?:$|/)~', $view, $m)) {
return $m[1];
} else {
return 'unknown';
}
function elgg_get_simplecache_url($view, $subview = '') {
return _elgg_services()->simpleCache->getUrl($view, $subview);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion engine/lib/deprecated-1.8.php
Expand Up @@ -3016,7 +3016,7 @@ function get_entity_icon_url(\ElggEntity $entity, $size = 'medium') {
return $overrideurl;
}

$url = "_graphics/icons/default/$size.png";
$url = elgg_get_simplecache_url("icons/default/$size.png");
}

return elgg_normalize_url($url);
Expand Down

0 comments on commit c44740d

Please sign in to comment.