├── README.md
├── app
├── code
│ └── community
│ │ └── SomethingDigital
│ │ └── RecentlyViewed
│ │ ├── Block
│ │ └── Viewed.php
│ │ ├── Model
│ │ └── Adminhtml
│ │ │ └── System
│ │ │ └── Config
│ │ │ └── SdRecentlyViewedPosition.php
│ │ └── etc
│ │ ├── config.xml
│ │ └── system.xml
├── design
│ └── frontend
│ │ └── base
│ │ └── default
│ │ ├── layout
│ │ └── sd_recentlyviewed
│ │ │ └── recent.xml
│ │ └── template
│ │ └── sd_recentlyviewed
│ │ ├── items.phtml
│ │ ├── product.phtml
│ │ └── productid.phtml
└── etc
│ └── modules
│ └── SomethingDigital_RecentlyViewed.xml
├── composer.json
├── modman
└── skin
└── frontend
└── base
└── default
└── js
└── sd_recentlyviewed
└── recent.js
/README.md:
--------------------------------------------------------------------------------
1 | # SomethingDigital_RecentlyViewed
2 |
3 | Localstorage-based recently viewed products
4 |
5 | Overview
6 | --
7 |
8 | Inspired by Ivan Chepurnyi's [talk about improving Magento write performance](de.slideshare.net/ivanchepurnyi/making-magento-flying-like-a-rocket-a-set-of-valuable-tips-for-developers?related=1). This replaces the in-built Recently Viewed product block with a localstorage implementation.
9 |
10 | Features
11 | --
12 |
13 | - Target the location of the block in admin via CSS selector
14 | - Control the number of items displayed (uses default Magento value)
15 | - Disable writes to report tables (recommended to use in conjunction with [Quafzi_PerformanceTweaks](https://github.com/quafzi/magento-performance-tweaks)
16 |
17 |
18 | Screenshots
19 | --
20 |
21 |
22 |
23 |
24 | License
25 | --
26 |
27 | The MIT License
28 |
29 | Copyright (c) 2015 Something Digital http://www.somethingdigital.com
30 |
31 | Permission is hereby granted, free of charge, to any person obtaining a copy
32 | of this software and associated documentation files (the "Software"), to deal
33 | in the Software without restriction, including without limitation the rights
34 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
35 | copies of the Software, and to permit persons to whom the Software is
36 | furnished to do so, subject to the following conditions:
37 |
38 | The above copyright notice and this permission notice shall be included in
39 | all copies or substantial portions of the Software.
40 |
41 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
44 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
45 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
46 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
47 | THE SOFTWARE.
48 |
--------------------------------------------------------------------------------
/app/code/community/SomethingDigital/RecentlyViewed/Block/Viewed.php:
--------------------------------------------------------------------------------
1 | 'top', 'label' => 'Top' ),
8 | array( 'value' => 'bottom', 'label' => 'Bottom' ),
9 | array( 'value' => 'above', 'label' => 'Above' ),
10 | array( 'value' => 'below', 'label' => 'Below' ),
11 | );
12 |
13 | return $position;
14 | }
15 | }
--------------------------------------------------------------------------------
/app/code/community/SomethingDigital/RecentlyViewed/etc/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 0.1.0
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | SomethingDigital_RecentlyViewed_Block
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | sd_recentlyviewed/recent.xml
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | .col-right.sidebar
36 | top
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/app/code/community/SomethingDigital/RecentlyViewed/etc/system.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | text
11 | 100
12 | 1
13 | 1
14 | 1
15 |
16 |
17 |
18 |
19 | select
20 | SomethingDigital_RecentlyViewed_Model_Adminhtml_System_Config_sdRecentlyViewedPosition
21 | 200
22 | 1
23 | 1
24 | 1
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/design/frontend/base/default/layout/sd_recentlyviewed/recent.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | skin_js
17 | js/sd_recentlyviewed/recent.js
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/app/design/frontend/base/default/template/sd_recentlyviewed/items.phtml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/design/frontend/base/default/template/sd_recentlyviewed/product.phtml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/design/frontend/base/default/template/sd_recentlyviewed/productid.phtml:
--------------------------------------------------------------------------------
1 | getId() : null;
5 | $categoryId = $category ? $category->getId() : null;
6 | // The view count includes the current product being viewed on the PDP.
7 | // Since the current product being viewed is not rendered in this list, the
8 | // number of displayed recent products on the PDP is actually one less than
9 | // the value for viewed_count of recent products. By adding one to max display
10 | // count for the current product being viewed, the default Magento
11 | // config values intuitively reflects the number of recent products visible on PDP.
12 | $maxDisplay = Mage::getStoreConfig('catalog/recently_products/viewed_count') + 1;
13 | ?>
14 |
--------------------------------------------------------------------------------
/app/etc/modules/SomethingDigital_RecentlyViewed.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | true
6 | community
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sdinteractive/somethingdigital_recentlyviewed",
3 | "license": "MIT",
4 | "description": "Add LocalStorage-based recently viewed products",
5 | "homepage": "https://github.com/sdinteractive/SomethingDigital_RecentlyViewed",
6 | "type": "magento-module",
7 | "require": {
8 | "php": ">=5.3"
9 | },
10 | "authors": [
11 | {
12 | "name": "Something Digital",
13 | "email": "info@somethingdigital.com",
14 | "homepage": "http://www.somethingdigital.com/",
15 | "role": "Author/Maintainer"
16 | }
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/modman:
--------------------------------------------------------------------------------
1 | #SomethingDigital_RecentlyViewed
2 | app/code/community/SomethingDigital/RecentlyViewed app/code/community/SomethingDigital/RecentlyViewed
3 | app/design/frontend/base/default/layout/sd_recentlyviewed app/design/frontend/base/default/layout/sd_recentlyviewed
4 | app/design/frontend/base/default/template/sd_recentlyviewed app/design/frontend/base/default/template/sd_recentlyviewed
5 | skin/frontend/base/default/js/sd_recentlyviewed skin/frontend/base/default/js/sd_recentlyviewed
6 | app/etc/modules/*.xml app/etc/modules/
--------------------------------------------------------------------------------
/skin/frontend/base/default/js/sd_recentlyviewed/recent.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var SomethingDigitalRecentlyViewed = Class.create();
4 |
5 | SomethingDigitalRecentlyViewed.prototype = {
6 | items: null,
7 | initialize: function(){
8 | this.initStorage();
9 | this.render();
10 | },
11 |
12 | initStorage: function(){
13 | var recentlyViewed = this.getRecentlyViewed(this.getLoadedStorage());
14 | this.reloadStorage(recentlyViewed);
15 | },
16 |
17 | getLoadedStorage: function(){
18 | if(!this.items){
19 | this.items = JSON.parse(localStorage.getItem('recently-viewed')) || [];
20 | }
21 | return this.items;
22 | },
23 |
24 | reloadStorage: function(recentlyViewed){
25 | localStorage.setItem('recently-viewed',JSON.stringify(recentlyViewed));
26 | },
27 |
28 | reduceRecent: function(memo,a){
29 | if (a && a.id){
30 | if(memo.indexOf(a.id) === -1){
31 | memo.push(a.id);
32 | }
33 | }
34 | return memo;
35 | },
36 |
37 | getRecentlyViewed: function(recentlyViewed){
38 |
39 | if(typeof sdRecentlyViewed == 'undefined'){
40 | return recentlyViewed;
41 | }
42 |
43 | //get unique keys
44 | var uniqueKeys = recentlyViewed.reduce(this.reduceRecent, []),
45 | index = uniqueKeys.indexOf(sdRecentlyViewed.productId);
46 |
47 | //add if current product is not in the unique keys
48 | if(index === -1 && $('recently-viewed')){
49 |
50 | recentlyViewed.push({
51 | id: sdRecentlyViewed.productId,
52 | html: $('recently-viewed').innerHTML
53 | });
54 |
55 | if(recentlyViewed.length > sdRecentlyViewed.maxDisplay){
56 | recentlyViewed.shift();
57 | }
58 |
59 | //move to end if current product *is* in unique keys
60 | } else if (index != -1) {
61 | var obj = recentlyViewed.splice(index, 1)[0];
62 | recentlyViewed.push(obj);
63 | }
64 |
65 | return recentlyViewed;
66 | },
67 |
68 | getRenderedItems: function(){
69 | var items = this.getLoadedStorage();
70 |
71 | return items.map(function(a){
72 | // Don't render the current product since it is already being viewed on PDP
73 | if (a){
74 | if (a.id == sdRecentlyViewed.productId) {
75 | return '';
76 | }
77 | return a.html;
78 | }
79 | }).join('');
80 | },
81 |
82 | render: function(){
83 |
84 | if(!this.items || this.items.length <= 1){
85 | return;
86 | }
87 |
88 | var rvTemplate = $('recently-viewed-product-list'),
89 | target = $$(sdRecentlyViewed.insertAt)[0];
90 |
91 | if(!rvTemplate || !target){
92 | return;
93 | }
94 |
95 | var html = rvTemplate.innerHTML.replace('{{items}}',this.getRenderedItems());
96 | $(target).insert({top: html});
97 |
98 | }
99 | }
100 |
101 | document.observe('dom:loaded',function(){
102 | new SomethingDigitalRecentlyViewed();
103 | });
104 |
--------------------------------------------------------------------------------