如何将Joomla1.5升级至Joomla2.5

前言

本文转自我之前的博客,写于2012年。以下为文章原文:

近期接了一个荷兰的订单,主要的工作是将当前网站的Joomla1.5系统升级为Joomla2.5系统。

在进行升级工作之前,我曾经查阅了很多互联网上的文献,遗憾的是,国内没有一篇完整记录Joomla1.5升级至2.5的技术类文章。想起来还是我的英语帮了我大忙,经过不断的搜索,从Joomla官方网站上找到了Joomla1.5升级为Joomla2.5的权威文章。文章链接如下:http://docs.joomla.org/Migrating_from_Joomla_1.5_to_Joomla_2.5

为了方便不习惯看英文文档的技术ers,我将文章的精髓进行翻译,并补充各种我在实际升级过程中遇到的问题。

Joomla1.5升级至Joomla2.5神功现在开始!

一、升级之前的准备。

升级开始前,以下准备工作是必须的。

  1. 重新判断一下,你的Joomla是否真的要升级?当然,如果你是接单赚钱的话,没有真不真的问题,你肯定要做的。但是如果是你自己的网站,你真的要考虑一下,是否真的有升级的必要?因为升级就肯定存在风险,而且产生很多附带的工作量,对于这两点,你必须做好思想准备。
  2. 你的Joomla1.5是不是最新版本?这里的最新是针对Joomla1.5这个大版本号而言的,Joomla1.5的最新版本是1.5.26。如果你的Joomla1.5不是最新版本,则必须要将Joomla1.5升级至最新版本后才可以进行后面的操作。(原因:我们将会使用JUpgrade进行Joomla的升级工作,而JUpgrade支持Joomla1.5.26到Joomla2.5的升级,很多朋友都抱怨JUpgrade不好用,其实是因为自己的Joomla1.5版本不对)。
    经验之谈:至于如何将Joomla1.5升级至最新版本,请看这篇文章:how to update from Joomla! 1.5.x to the latest version(这篇文章也是英文的,但是内容比较简单,如果大家有问题可以随时联系我,我抽时间会将此文章也翻译一下)。
  3. 当前的Joomla插件是否支持Joomla2.5?这也是个不大不小的问题。某些在Joomla1.5下面安装的插件在升级后是不支持Joomla2.5的。因此先要对插件的情况进行一下了解。最理想的情况是在升级Joomla之前,现在Joomla1.5的环境下将所有插件都升级到最新版本,之后再进行Joomla的升级。
    经验之谈:在升级过程中,插件方面我是比较幸运的。我没有按照要求对插件进行升级,而是先对Joomla进行了升级,升级后发现,诸如“Acymailing”,“Community Builder”等插件是无法正常使用的。但好在这两个插件都有相关的补救办法,具体方法我再后面还会说明。
  4. 你是否更改了Joomla的核心文件?有关“核心文件”的定义并没有确切的界限,简单的说,凡是升级过程中会被新文件覆盖的文件都属于核心文件。这个问题我想大家不要过于纠结,因为从1.5升级至2.5是大版本号的升级,很多核心文件都会被替换,所以如果你确实修改了很多核心文件的话,我建议你还是考虑一下升级的必要性。
  5. 你当前使用的Joomla模版和Joomla语言包是否支持Joomla2.5,这个插件的兼容性基本上属于一个问题。还是那句话,既然进行大版本号的升级,就要做好一切准备。

二、备份、备份、一定要备份

首先还是要说,我的升级之路比较顺利,虽然遇到过问题,但是没有遇到哪些需要重新来过的大问题。但是对于每一个即将进行升级操作的人而言,我还是想各位说一句“一定要备份、备份、在备份”。这里包括数据库和代码的完整备份,如果哪位连怎么备份都不知道的话,我建议您还是不要升级了,您肯定搞不定接下来的事情。

三、开始升级

1. 首先需要下载升级工具jUpgrade。

地址如下:http://extensions.joomla.org/search?q=jupgrade。话说这个工具真是个神作,这里要特别重复一下,这个工具是绝对好用的,如果你使用的时候有异常,多半情况下是没有按照本文第一部分的要求将Joomla1.5升级至最新版本

2. 安装jUpgrade。

安装方法就是Joomla1.5通用扩展安装方法。

2.1 进入你的Joomla1.5后台,然后依次点击Extensions >> Install/Uninstall。
file
2.2 Browse >> Select com_jupgrade >> Upload File & Install
file
2.3 安装成功
file

3. 启动“Mootools Upgrade ”插件。

  • 进入 Extensions | Plugin Manager
  • 查找 "System - Mootools Upgrade"
  • 将此插件开启
    请确保Mootools Upgrade插件已经正确安装并开启, jUpgrade需要依靠此插件才能正常运行。

4. 对JUpgrade进行设置。

截止到本文编写时,JUpgrade的版本号是2.5,支持将Joomla从1.5升级至1.7或者2.5,并附带了众多的升级选项设置。具体设置位置在:Administrator > Components > jUpgrade > Parameters.Global

  • Distribution - 选择要升级到的Joomla版本号,1.7或是2.5
  • Prefix for old database - 当前Joomla网站的数据库表前缀
  • Prefix for new database - 升级后的Joomla网站的数据库表前缀

Skips
Skip checks - 略过升级前的检测
Skip download - 略过下载升级包(注意:当你已经自行下载了升级包,并将升级包放入temp文件夹中,才选择此选项)
Skip decompress - 略过解压缩(注意:当你自行下载升级包后,且将升级包放入temp文件夹中,并自行解压缩后,才选择此选项)

Templates
Keep original positions - 保留原始的目录结构

Debug
Enable Debug - 允许错误调试,当升级出现错误的时候,显示相关的错误信息。

以上信息配置完成后,保存即可。

5. 移植开始。

依次进入:Components >> jUpgrade
file
开始升级
file
file
这个时候要注意不要退出页面,直至所有加载条都完成加载后才可以关闭页面。
file

另一个注意事项,JUpgrade只将Joomla1.5的默认模版进行了升级,因此当你打开升级后的网站时,网站的默认模版是被选中的,需要在后台进行切换才可以。

四、升级之后

  1. 首先先要恭喜你经过了这个惊心动魄的过程。话说我在进行升级的过程中,每点击一个按钮时心都提到嗓子眼了,当发现没有报错,又会暗自狂喜一下。
  2. JUpgrade的升级过程实际上是非常安全的。JUpgrade在升级网站的时候,没有对原来的Joomla网站进行任何的修改,原来的数据库表、源文件还是在那里,JUpgrade实际是在原来网站的根目录里面创建了一个“jupgrade”文件夹,并将升级后的Joomla2.5网站文件保存在了这个文件夹里面。
  3. 依次检查一下下面的这些功能是否还是正常工作:
    Banners
    Categories
    Contacts
    Content
    Menus
    Modules
    Newsfeeds
    Users
  4. 了解了升级原理,并确认升级成功后,下面就可以对原有网站进行清楚了。清楚地方法也很简单,将数据库中Joomla1.5表前缀的数据表全部清除,并将网站根目录中除了jugrade文件夹的源文件全部删除,然后将jugrade文件夹中的文件转移至网站根目录即可。

五、有关“Acymailing”和“Community Builder”升级后的问题。

这两个插件在Joomla从1.5升级至2.5都出现了问题。问题描述和解决办法如下:

1. Acymailing

问题描述:升级后Acymailing在Component菜单下直接消失了。
解决方法:很简单,下载一个最新版的Acymailing插件,然后重新安装即可。可以放心,原来的数据都会保留。

2. Community Builder

问题描述:升级后点击Community Builder菜单后报错。
解决方法:也不难,下载一个最新版的CB,解压缩后按照里面的提示对CB进行升级即可,原来的数据库也会保留。

彻底搞懂npm -g,npm -save,npm -save-dev

1. 回顾 npm install 命令

最近在写Node程序的时候,突然对 npm install 的-save和-save-dev 这两个参数的使用比较混乱。其实博主在这之前对这两个参数的理解也是模糊的,各种查资料和实践后对它们之间的异同点略有理解。遂写下这篇文章避免自己忘记,同时也给node猿友一点指引。

我们在使用 npm install 安装模块的模块的时候 ,一般会使用下面这几种命令形式:

npm install moduleName # 安装模块到项目目录下

npm install -g moduleName # -g 的意思是将模块安装到全局,具体安装到磁盘哪个位置,要看 npm config prefix 的位置。

npm install -save moduleName # -save 的意思是将模块安装到项目目录下,并在package.json文件的dependencies节点写入依赖。

npm install -save-dev moduleName # -save-dev 的意思是将模块安装到项目目录下,并在package.json文件的devDependencies节点写入依赖。

那么问题来了,在项目中我们应该使用四个命令中的哪个呢?这个就要视情况而定了。下面对这四个命令进行对比,看完后你就不再这么问了。

2. npm install moduleName 命令

  1. 安装模块到项目node_modules目录下。
  2. 不会将模块依赖写入package.json的devDependencies或dependencies节点。
  3. 运行 npm install 初始化项目时不会下载模块。

3. npm install -g moduleName 命令

  1. 安装模块到全局,不会在项目node_modules目录中保存模块包。
  2. 不会将模块依赖写入package.json的devDependencies或dependencies 节点。
  3. 运行 npm install 初始化项目时不会下载模块。

4. npm install -save moduleName 命令

  1. 安装模块到项目node_modules目录下。
  2. 将模块依赖写入package.json的dependencies节点。
  3. 运行 npm install 初始化项目时,会将模块下载到项目目录下。
  4. 运行npm install --production或者注明NODE_ENV变量值为production时,会自动下载模块到node_modules目录中。

5. npm install -save-dev moduleName 命令

  1. 安装模块到项目node_modules目录下。
  2. 将模块依赖写入package.json的devDependencies节点。
  3. 运行 npm install 初始化项目时,会将模块下载到项目目录下。
  4. 运行npm install --production或者注明NODE_ENV变量值为production时,不会自动下载模块到node_modules目录中。

6. 总结

devDependencies 节点下的模块是我们在开发时需要用的,比如项目中使用的 gulp ,压缩css、js的模块。这些模块在我们的项目部署后是不需要的,所以我们可以使用 -save-dev 的形式安装。像 express 这些模块是项目运行必备的,应该安装在 dependencies 节点下,所以我们应该使用 -save 的形式安装。

本文转自:https://www.limitcode.com/detail/59a15b1a69e95702e0780249.html

ECMAScript6随学随记

1.let

ES6新增了let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。
可以简单的理解为,var声明的是全局变量,let声明的局部变量。

function f1() {
    var n = 5;
    if (true) {
      var n = 10;
    }
    console.log(n);
  }
  f1();//输出结果为10

  function f2() {
    var n = 5;
    if (true) {
      let n = 10;
    }
    console.log(n);
  }
  f2();//输出结果为5

2. const

const声明一个只读的常量。一旦声明,常量的值就不能改变。
这意味着,const一旦声明变量,就必须立即初始化,不能留到以后赋值。

但对于复合类型的变量,变量名不指向数据,而是指向数据所在的地址。const命令只是保证变量名指向的地址不变,并不保证该地址的数据不变,所以将一个对象声明为常量必须非常小心。

3. 模板字符串

传统的JavaScript语言,输出模板通常是这样写的($('#xxx')是JQuery语法)。

$('#result').append(
  'There are <b>' + basket.count + '</b> ' +
  'items in your basket, ' +
  '<em>' + basket.onSale +
  '</em> are on sale!'
);

上面这种写法相当繁琐不方便,ES6引入了模板字符串解决这个问题。

$('#result').append(`
  There are <b>${basket.count}</b> items
   in your basket, <em>${basket.onSale}</em>
  are on sale!
`);

模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。

// 普通单行字符串
`In JavaScript '\n' is a line-feed.`

// 多行字符串
`In JavaScript this is
 not legal.`

console.log(`string text line 1
string text line 2`);

// 字符串中嵌入变量
var name = "Bob";
var time = "today";

//模板字符串中嵌入变量,需要将变量名写在${}之中。
var nameTime = `Hello ${name}, how are you ${time}?`;
console.log(nameTime);//输出:Hello Bob, how are you today?

//大括号内部可以放入任意的JavaScript表达式,可以进行运算,以及引用对象属性。
var x = 1;
var y = 2;
`${x} + ${y} = ${x + y}`// "1 + 2 = 3"
`${x} + ${y * 2} = ${x + y * 2}`// "1 + 4 = 5"
var obj = {x: 1, y: 2};
`${obj.x + obj.y}`// 3

//模板字符串之中还能调用函数。
function fn() {
  return "Hello World";
}
`foo ${fn()} bar`// foo Hello World bar

4. 标签模板

模板字符串的功能,不仅仅是上面这些。它可以紧跟在一个函数名后面,该函数将被调用来处理这个模板字符串。这被称为“标签模板”功能(tagged template)。

alert`123`
// 等同于
alert(123)

“标签模板”的一个重要应用,就是过滤HTML字符串,防止用户输入恶意内容。

var sender = '<script>alert("abc")</script>'; // 恶意代码
var message = SaferHTML`<p>${sender} has sent you a message.</p>`;//SaferHTML是个自定义函数。

console.log(message);// <p><script>alert("abc")</script> has sent you a message.</p>

5. 对象扩展

ES6允许在对象之中,只写属性名,不写属性值。这时,属性值等于属性名所代表的变量。下面是另一个例子。

function f(x, y) {
  return {x, y};
}
// 等同于
function f(x, y) {
  return {x: x, y: y};
}
f(1, 2) // Object {x: 1, y: 2}

6. Module

6.1 解决Javascript的模块化问题。

早期的Javascript,最让人头痛的就是js代码无法互相引用的问题。这对于大型项目而言就像噩梦一般。
ES6原生了代码引用功能,从根本上解决了js代码模块化的问题。

6.2 export和import语法。

6.2.1 使用export暴露模块。
// profile.js
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;
function v1() { ... }
export {
  firstName,
  lastName,
  year,
  v1 as streamV1,
};
6.2.2 使用export default暴露模块
export default function foo() {
  console.log('foo');
}
//等同于
function foo() {
  console.log('foo');
}
export default foo;

每个模块只能有一个export default

6.2.3 使用import使用模块。
// 使用export default输出
export default function crc32() {
  // ...
}
// 针对export default的输入语法
import anyName from 'crc32';

// 使用普通export输出
export function crc32() {
  // ...
};
// 针对普通export的输入语法
import {crc32} from 'crc32';

上面代码的两组写法,第一组是使用export default时,对应的import语句不需要使用大括号;第二组是不使用export default时,对应的import语句需要使用大括号。

export default命令用于指定模块的默认输出。显然,一个模块只能有一个默认输出,因此export deault命令只能使用一次。所以,import命令后面才不用加大括号,因为只可能对应一个方法。

本质上,export default就是输出一个叫做default的变量或方法,然后系统允许你为它取任意名字。

6.4 ECMAScript6和CommonJS在模块化上的区别

参考:https://www.w3cschool.cn/ecmascript/ueqp1q5g.html

6.4.1 Node.js不支持ES6的模块语法

做这个比较主要是由于Node.js不支持ES6的import和export功能导致的。说来也奇怪,Node.js已经支持了92%的ES6语法,唯独对ES6这个最重要的模块功能不支持。这一点可以通过安装ES-Checker模块来查看Node.js对ES6的支持:

$ npm install -g es-checker
$ es-checker

结果如下:
file

6.4.2 Node.js使用CommonJS解决模块问题

在Node.js中默认集成了CommonJS,所以一般都用CommonJS来实现模块的输入输出。
CommonJS的模块语法是使用require和exports。
exports示例如下:

//  ./utils/util.js
var textHello = "Hello World!";

function addFun(a,b){
    return a+b;
}
function sayHello(){
    return "Say Hello!";
}

//完整写法:module.exports.在外面被引用的名字 = 模块内的名字
module.exports.textHello = textHello;
//简写:exports.在外面被引用的名字 = 模块内的名字
exports.addFun = addFun;
//在外面被引用的名字和模块内的名字可以不一样
exports.sayH = sayHello;

//上面三个export语句等同于下面一句
module.exports = {
    textHello:textHello,    //完整写法 - 在外面被引用的名字:模块内的名字
    addFun,                 //简写 - 在外面被引用的名字和模块内的名字相同,可以只写一个
    sayH:sayHello           //如在外面被引用的名字与模块内的名字不同,则必须用:方式
}

require示例如下:

// main.js
moduleUtil = require("./utils/util");
console.log(moduleUtil.textHello);
console.log(moduleUtil.addFun(2,3));
console.log(moduleUtil.sayH());
/*以上三行输出:
Hello World!
5
Say Hello!
*/

当然,如果你必须要在Node.js中使用ES6原生的import和export也是可以的,前提是必须借助Babel这类的转换器。

6.4.3 两者的区别

ES6模块加载的机制,与CommonJS模块完全不同。CommonJS模块输出的是一个值的拷贝,而ES6模块输出的是值的引用。

CommonJS模块输出的是被输出值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。

ES6模块的运行机制与CommonJS不一样,它遇到模块加载命令import时,不会去执行模块,而是只生成一个动态的只读引用。等到真的需要用到时,再到模块里面去取值,换句话说,ES6的输入有点像Unix系统的“符号连接”,原始值变了,import输入的值也会跟着变。

7. 属性和方法的简写

var name = "Tom";
var app = {
    name = name,
    run:function(){
        console.log(`${name} is running!`);
    }
}

等同于:

var name = "Tom";
var app = {
    name, //前提是属性名和属性值相同
    run(){
        console.log(`${name} is running!`);
    }
}

8. 箭头函数

箭头函数可以理解为是对匿名函数的一种缩写。但是与匿名函数不同的是,箭头函数里面的this指向的是上下文。

8.1 极简示例。

function (x) {
    return x * x;
}

等同于

(x)=>{return x * x;}

8.2 另一个示例。

setTimeout(function(){
    console.log("Hello!There!");
},1000);

等同于

setTimeout(()=>{
    console.log("Hello!There2!");
},1000);