You cannot see this page without javascript.

Skip Navigation

XE 레이아웃 카메론 XE LAYOUT CAMERON XE2.0.16


확대 기본 축소
모듈
2020.08.13 14:40

XE의 URL 규칙

profile
(*.168.0.1) Views 91 Votes 0 Comment 0
?

Shortcut

PrevPrev Article

NextNext Article

Larger Font Smaller Font Up Down Go comment Print

URLs on XE

XE에서 생성한 URL 은 깔끔하고 검색엔진에서 색인되기 좋은 구조이다. XE는 일반적인 쿼리스트링 기반의 URL이 아니라 세그먼트 기반의 URL을 사용한다. 쿼리스트링(Query string) URL이란, 다음과 같이 쿼리 문자열을 포함하는 전형적인 URL 형식이다.

<http://www.xeschool.com/xe/index.php?mid=freeboard&document;_srl=123>

서버는 위와 같은 요청을 받게 되면, 물음표를 제외한 쿼리 문자열의 필드와 값(field1=value1&field2;=value2...)을 각각 한 쌍으로 구분하고 , CGI 프로그램 또는 웹 어플리케이션(Application Controller), 여기서는 XE코어에게 제출(submitted)하는 것이다. XE는 요청(Request) 받은 쿼리 문자열을 자신의 URL 규칙에 따라 세그먼트 기반의 문자열 형식으로 변경시킨다. ※ 이 기능을 사용하려면 웹 서버에서 rewrite_mod를 지원해야 하고 XE 제어판에서 짧은 주소 사용을 설정해야 한다. 만약 서버가 rewrite_mod를 지원하지 않는다면 쿼리스트링 기반의 URL을 계속 사용해도 전혀 문제 되지 않는다.

<http://www.xeschool.com/xe/freeboard>
<http://www.xeschool.com/xe/123>

세그먼트(String segment)란, 단어의 의미 그대로 문자열을 "단편, 조각"으로 분리하여 패턴 형식으로 만든다는 뜻이다. 즉 쿼리스트링 URL도 세그먼트 형식의 URL도 네트워크상의 같은 자원을 찾고 있지만 세그먼트 형식은 무척 간단하게 표현되고 쉽고 편리하다.

  • URI(Uniform Resource Identifier) = URL(Locator) + URN(Name) URI 는 통합자원 식별자를 말한다. 인터넷에 있는 자원(문서, 이미지, 파일, 데이터베이스, 전자우편)을 나타내기 위한 식별자를 규정하며 인터넷 프로토콜(HTTP 혹은 FTP)에 항상 붙어다닌다. URL은 네트워크 상에서 자원이 어디 있는지 위치를 알려주기 위한 규약이고 URN은 식별자(URI)가 사용하는 이름으로 자원의 위치, 프로토콜, 호스트 등과는 상관없이 각각의 콘텐츠에 이름을 부여한 것이다. 식별자(Identifier)는 쉽게 말해 신분증과 같다. 신분증에는 자원의 주소(Locator)와 이름(Name/urn scheme)이 있는데 네트워크상에서 어떤 자원에 접근하기 위해서는 보통 URL을 많이 사용한다. URL은 웹 사이트의 주소형식 뿐만 아니라 네트워크상의 자원을 모두 나타낼 수 있다.

어떻게 이것이 가능할까?(How it is possible?)

XE는 대부분 모듈화 되어 있다. 회원관리, 레이아웃, 메뉴, 게시판 등 모두 독립된 프로그램 단위로 존재한다. 쉽게 말해 "초등학교" 모듈이 있다고 가정하자.

초등학교에서 "우진"이를 찾으려면 URL을 다음과 같이 작성하여야 한다.

/xe/index.php?초등학교=4학년&이름=우진

하지만 XE는 우진이라는 네트워크의 자원을 잘 알고 있다. 따라서 다음과 같이 작성해도 XE는 우진이를 찾아서 보여준다.

/xe/우진

"우진"이는 "초등학교" 모듈이 만들어 놓은 자원의 이름이다. 따라서 자원의 이름만 불러 주어도 XE는 우진이를 찾아서 보여 준다. 이것이 모듈의 아이디, 즉 mid 이고, 문서의 번호 document_srl 인 것이다. 게시판 모듈(board)이 새로운 게시판, 이름을 자유게시판(freeboard)이라고 생성하였다면 이 게시판의 고유한 모듈 아이디(mid)는 freeboard가 된다. 위에서 처럼 모듈의 아이디만 불러주어도 XE는 자유게시판을 보여줄 것이다. 그리고 자유게시판에 글이 작성된다면 board 모듈은 글 하나하나 마다 고유한 이름값을 붙여 둔다. 이것이 document_srl 즉 문서의 식별 번호이다. 마찬가지로 문서의 번호만 찾아달라고 요청해도 XE는 "아! 이 문서의 번호(123)는 board 모듈이 생성했던 자유게시판(freeboard)에서 몇번째 글이군! 내가 찾아서 보여주지!" ...^^

이렇게 모듈이 저마다 고유한 아이디와 식별 번호 붙여 생성한 자원은 영구적인 URL 주소값을 갖는다. 이것을 다른 말로 퍼머링크(permalink)라고도 표현하는데, "퍼머링크는 인터넷에서 특정 페이지에 영구적으로 할당된 URL 주소를 뜻한다. 이 주소는 한 번 정해지면 영원하다는 의미에서, 영구적인(permanant) 주소라는 뜻의 permanant link를 줄여 만든 말이다. 영구 링크라는 번역이 원의에 가깝지만 한국에서는 고유 링크고유 주소라는 명칭이 광범위하게 퍼져 있다. 퍼머링크를 사용하는 대표적인 사례는 블로그에서 볼 수 있다. 시간이 지남에 따라 새로운 내용이 추가되면서 블로그의 글은 위치가 쉽게 변하므로, 각각의 글에 영원히 고정된 주소를 제공하는 것이다."[위키백과 인용]

/xe/index.php?mid=모듈의 아이디&document;_srl=문서의 번호
/xe/?mid=모듈의 아이디&document;_srl=문서의 번호 // index.php가 생략된 경우
/xe/문서의 번호

위 형식은 모두 동일한 결과를 얻는다. (※ 문서의 제목과 별칭으로 URLs를 이용하는 방법은 개발자 메뉴얼을 참고하기 바란다. 나는 잘 않된다...^^ p.60)

그러면 어떤 **회원의 식별 번호(member_srl)**를 찾아 정보를 보여 달라고 요청하면 어떻게 될까?

/xe/member_srl=4

허황된 요구는 XE가 완전 무시해 버린다...^^ member_srl은 회원관리(member) 모듈이 회원가입을 통해 받은 회원에게 붙여 둔 회원 식별 번호이다. XE는 위와 같은 요청을 받게 되면 다음과 같이 생각한다. "네가 우리 회원의 정보를 볼 수 있는 자격이나 있나? 넌 누구냐?" 여기서 중요한 것은 회원 정보를 볼 수 있는 권한(permission)이다. 회원정보는 아무나 쉽게 볼 수 있는 내용이 아니다. 따라서 XE의 모듈 중에는 요청하는 자원에 대해 지정된 권한(Admin 권한)이 있는지 확인해 볼 필요가 있고 이러한 요청에 대해서는 특별한 주문(Command pattern)을 넣어야 한다. 이것이 act 즉 액션(action) 이름이다.

※ 커맨드 패턴(Command pattern) : 요청을 객체의 형태로 캡슐화하여 서로 요청이 다른 사용자의 매개변수와, 요청 저장 또는 로깅, 그리고 연산의 취소를 지원하게 만드는 패턴이다.

Admin

관리자로서(Admin) XE에게 회원의 정보(member_srl=4)를 보여달라고 요청하는 주문(action)이다. 회원정보를 보려면 관리자(admin) 모듈의 위치에서 실행할 것이다. 그리고 회원의 번호를 주고 정보를 보여달라고(display) 요청 한다. 회원의 정보를 관리하는 모듈은 회원관리(Member) 모듈이다.

그렇다면 일반회원이 자신의 정보를 보기위한 주문은 어떻게 될까?

/xe/index.php?mid=welcome_page&act;=dispMemberInfo

로그인 회원이라면 위와 같은 주문(액션)은 유효하다. 하지만 비로그인 회원에게는 위와 같은 주문을 넣을 수 조차 없다. 이러한 주문, 액션(act)을 가지고 있는 소유자는 해당 모듈, 즉 여기서는 회원관리를 담당하고 있는 member 모듈이고 액션을 실행할 수 있는 권한은 로그인 사용자에게 주어진다. 이렇게 각각의 모듈들은 자신이 사용할 목적의 액션을 가지고 있고 액션에 따른 실행 권한도 확인해 본다. 그런데 회원가입과 같은 액션(act=dispMemberSignUpForm)은 특별한 권한이 없어도 실행된다. 왜 그럴까?

액션은 곧 함수의 이름이다. MVC 패턴에 의해 설계된 모듈 안에서 각각의 목적과 실행 방법에 따라 무엇을 보여달라고 할 때는 Display의 약자 disp를 머릿말로 사용한다. 무엇을 실행할 때는 Process의 약자 proc, 무엇인가를 얻기 위해서는 get을 붙여 함수의 이름을 만든다. 자세한 내용은 추후에 살펴보겠지만 액션의 이름도 목적과 권한(permission)에 따른 일정한 패턴을 갖고 있는 것이다. 모듈마다 자신이 사용하는 액션(act)과 권한 설정은 모듈 폴더의 conf/module.xml 파일에 모아 둔다. 그리고 요청된 액션의 결과는 미리 약속된 View(웹 페이지)에서 출력하도록 설계하는 것이다.

XE는 쿼리스트링 기반의 URL도 사용할 수 있다. 만약 사용자 파라미터를 전달하기 위해 쿼리스트링 URL을 사용해야 한다면 다음과 같이 작성한다.

/xe/index.php?mid=모듈의 이름&field1;=value1&field2;=value2...

단, 이때의 파리미터는 모듈에서 수신할 수 있는 방법을 미리 정의해 두어야 한다. XE에서의 폼 전송은 XML필터를 이용한다. 따라서 개발자가 의도하지 않은 파라미터는 요청 내용에서 제외된다. 만약 외부 페이지 모듈로 전송할 경우에는 {@ Context::get('변수이름')}으로 인자(argument)를 수신 받을 수 있다. (※ 참고자료 : {getUrl()})

모듈(document/모듈의 이름)과 모듈의 아이디(mid)는 전혀 다르다. 모듈은 프로그램의 단위를 말하며 곧 모듈 폴더(/xe/modules/document)의 이름과 같다. 모듈의 아이디(mid)는 모듈이 생성한 객체의 고유한 이름값이다. 예를 들어 board 모듈이 게시판을 생성할 때 붙여준 고유한 이름이 모듈 아이디(mid)가 된다. URL에서 모듈은 파라미터로 아무런 가치를 전달하지 못하지만 모듈의 아이디(mid) 또는 문서의 번호(document_srl), 액션의 이름 등은 XE코어에게 요청할 수 있는 충분한 자원적 가치를 갖는다. 한가지 예외로 URL 끝에 다음과 같이 admin을 요청하면 XE코어의 관리자 페이지를 보여준다.

/xe/admin

이것은 XE의 .htaccess 파일에서 다음과 같은 RewriteRule(URL 재작성)이 추가되어 있기 때문이다.

# administrator page
RewriteRule ^admin/?$ ./index.php?module=admin [L]

XE코어가 설치된 URL 뒤에 admin 만 요구해도 /index.php?module=admin 과 같은 요청이 된다는 뜻이고 admin 모듈은 모듈의 이름만 불러도 미리 설정해 두었던 관리자 화면을 보여준다. 그밖의 다른 모듈들은 모듈의 이름을 아무리 불러 보아도 대답하지 않는다. 무조건 시작 모듈로 보내 버린다...^^

만약 XE코어에 예기치 못한 문제가 발생하는 경우 다음의 액션을 URL 뒤에 넣어보자.

/?module=admin&act=dispAdminConfig

module=admin 은 관리자 초기 페이지를 보여주지만 act=dispAdminConfig 는 관리자 설정 화면을 직접 보여 준다는 것이 다르다. 시작모듈과 설정에 따른 문제가 있는 경우 바로 확인해 볼 수 있는 매우 유용한 액션이다.

간단히 정리해 보면, XE는 URL을 통해 유입되는 모든 요구에 대해 index.php를 거쳐 처리하는데 우선적으로 요청(Request)에 해당하는 모듈과 액션 이름을 찾아보고 없으면 기본값으로 설정된 모듈 페이지(시작 모듈)를 보여주게 된다. 세그먼트 기반의 URL을 사용하는 XE는 모듈의 아이디(mid), 문서의 번호(document_srl) 또는 가상 사이트(vid)와 해당하는 항목(entry) 등으로도 자원을 찾아 출력할 수 있다.

* User ID : leesungmin
* User Name : 이성민
* Email : imadonis@naver.com
* Homepage : https://4880.net
* Birthday : 1972-07-24
* Member Group : 관리그룹,유료회원,문제출제
* Signup Date : 2012-07-19
* Following : 랩퍼투혼 whom the member is following.
* Following Count : 1people
* Followed by : 랩퍼투혼, 탑돌이 ... now follwing this member.
* Followed Count : 2people

< 빌립보서 4장 13절>
내가 주 안에서 크게 기뻐함은 너희가 나를 생각하던 것이 이제 다시 싹이 남이니 너희가 또한 이를 위하여 생각은 하였으나 기회가 없었느니라   
내가 궁핍하므로 말하는 것이 아니니라 어떠한 형편에든지 나는 자족하기를 배웠노니    
나는 비천에 처할 줄도 알고 풍부에 처할 줄도 알아 모든 일 곧 배부름과 배고픔과 풍부와 궁핍에도 처할 줄 아는 일체의 비결을 배웠노라
내게 능력 주시는 자 안에서 내가 모든 것을 할 수 있느니라 

* Document Count : 17357
* Comment Count : 82
* Document Count : 36
* Document Count : 115
* Comment Count : 123
* Document Count : 2
* Comment Count : 2
* Document Count : 1
* Comment Count : -1
카카오링크
Attach Images or Files

Drop your files here, or click the button to the left.

Maximum File Size : 0MB (Allowed extentsions : *.*)

0 file(s) attached ( / )

제로XE/라이믹스/그누/워드프레스

회원만 쓰기 가능합니다.

List of Articles
No. Category Subject Author Date Views
Notice Tip&Tech xe 동작순서 부운영자 2015.08.24 1010
Notice Tip&Tech XE의 애드온 및 모듈의 기능 요약표 부운영자 2015.01.16 1261
Notice Tip&Tech XEReferences 부운영자 2014.11.29 933
Notice Tip&Tech XE 스킨 제작 매뉴얼 v1.1 (Korean, PDF) file 부운영자 2014.11.29 1273
Notice Tip&Tech XE 개발자 매뉴얼 v1.1 (Korean, PDF) file 부운영자 2014.11.29 1788
Notice Tip&Tech xe 레퍼런스 모음 file 부운영자 2014.10.10 2534
화제의 글 Tip&Tech PHP용 로그 라이브러리 공유합니다. 부운영자 2021.03.29 75
화제의 글 XE/라이믹스 게시글 DB 수동이동 부운영자 2021.03.17 51
화제의 글 매뉴얼 xml 쿼리 사용법 부운영자 2021.03.08 56
228 모듈 프론트엔드와 백엔드 뷰(View) Front and back ends 프론트 엔드(front-end)와 백 엔드(back-end)는, 사용자가 접근하는 영역을 말하는데 이때 사용자는 사람이 아닌 프로그램이 될 수도 있다. 예를 들어 컴퓨터 OS의 그래픽 파일 관리자는 컴퓨터의 파일 시스템에 대한 프론트 엔드이고 사용자와 직접 상호작용을 할 수 있다. 백 엔드 응용프로그램은 보... 부운영자 2020.08.13 335
227 모듈 MVC 구조의 이해 Model-View-Controller XE Core는 모델-뷰-컨트롤러(Model-View-Controller) 개발 패턴에 기반한다. 이것을 줄여서 MVC 구조라고 말한다. 소프트웨어 공학에서 프로그램의 설계는 건축(architecture)과 같다. 시스템의 운영 구조를 목적과 명세에 따라 유기적 관계로 설계하고 업그레이드를 통제하는 지침과 원칙, 이것을 아... 부운영자 2020.08.13 64
226 모듈 폼(form)과 DB Form &amp; DB XE 모듈을 이해하기 위한 기초 과정으로 폼(form)의 동작 방식을 살펴보자. 모듈은 결론적으로 폼과 DB의 관계이다. 모듈은 자신이 관리하는 테이블을 한두개 이상 가지고 있고 이것을 다루기 위해 폼을 사용한다. 이때 모듈에서의 폼의 처리 과정은 모델 뷰 컨트롤러 (Model-View-Controller) 개발 패턴에 기반한... 부운영자 2020.08.13 101
» 모듈 XE의 URL 규칙 URLs on XE XE에서 생성한 URL 은 깔끔하고 검색엔진에서 색인되기 좋은 구조이다. XE는 일반적인 쿼리스트링 기반의 URL이 아니라 세그먼트 기반의 URL을 사용한다. 쿼리스트링(Query string) URL이란, 다음과 같이 쿼리 문자열을 포함하는 전형적인 URL 형식이다. &lt;http://www.xeschool.com/xe/index.php?mid=freeboard&amp;do... 부운영자 2020.08.13 91
224 모듈 모듈의 기본 이해 The Story of XE Modules XE코어의 모듈 이야기... 1. 백엔드 어드민(Admin) 뷰(View) 구현을 위한 example 모듈 만들기 2. 프론트 엔드 뷰(View) 구현을 위한 BOOK 모듈 만들기 3. v1.5 룰셋(ruleset)과 BOOKMARK 모듈 만들기 . XE의 URL 규칙 폼(form)과 DB MVC 구조의 이해 프론트엔드와 백엔드 뷰(View) 모듈 확장과 모... 부운영자 2020.08.13 25
223 모듈 XE 모듈 The Story of XE Modules XE코어의 모듈 이야기... 1. 백엔드 어드민(Admin) 뷰(View) 구현을 위한 example 모듈 만들기 2. 프론트 엔드 뷰(View) 구현을 위한 BOOK 모듈 만들기 3. v1.5 룰셋(ruleset)과 BOOKMARK 모듈 만들기 모듈의 기본 이해 BOOK 모듈 만들기 룰셋과 북마크 모듈 만들기 부운영자 2020.08.13 18
222 XE코어 반복문 loop XE Template Syntax 반복문 loop 주어진 조건에 따라 필요한 내용을 반복해서 출력해야 할 때 반복문(루프/loop)을 사용한다. 1. 반복문의 이해 반복문은 컴퓨터가 만들어지면서 가장 먼저 시도된 증조 할아버지뻘 되는 구문이고 문법이다. 1+1 은 쉽다. 하지만 1에서 10까지 더하라고 하면 약간 머리가 복잡해진다. 사람들... 부운영자 2020.08.13 45
221 XE코어 조건문 IF XE Template Syntax 주어진 조건에 따라 필요한 내용을 문맥에 알맞게 출력하거나 배제할 때 조건문을 사용한다. 1. IF 문 IF 조건문은 PHP의 IF 조건문과 동일하고 &quot;if, elseif, else, end&quot;와 &quot;조건식&quot;으로 이루어져 있다. if 문이 시작되면 반드시 end 문으로 닫아서 조건문이 끝났음을 선언해야 하고 조건식의 내용은 PHP... 부운영자 2020.08.13 35
220 XE코어 파일 포함 include XE Template Syntax XE 템플릿 스킨의 HTML 문서 안으로 외부 파일을 불러와 포함시키기 위한 문법이다. 파일 포함 문법에서는 불러 들이고자 하는 외부 파일의 경로 설정을 상대 경로로 표시한다. 즉 HTML 문서의 자신을 기준으로 상대적인 위치의 경로를 이용한다. HTML 문서가 있는 같은 폴더 안의 default.css 파일을 포... 부운영자 2020.08.13 53
219 XE코어 기본 문법 default XE Template Syntax 1. 변수 PHP에서 변수를 다루는 것과 동일한 방법으로 XE 템플릿 안에서 변수를 정의하고 출력할 수 있다. 변수를 나타내는 문자열 앞에는 달러($) 기호를 붙여 사용하며 변수명은 대소문자를 구별한다. 변수는 프로그램에서 미리 선언한 내용 또는 템플릿 안에서 사용자의 필요에 따라 새로운 변수를 정... 부운영자 2020.08.13 77
218 XE코어 XE 템플릿 문법의 이해 XE Template Syntax 템플릿(template)이란 붕어빵을 만드는 틀로 비유된다. 같은 모양, 같은 크기의 객체(object)를 만들기 쉽다. 프로그래밍 언어에서 템플릿 구문은 초등학교 시절의 플라스틱 모형자를 생각하면 이해가 쉽다. 제각각 다른 모양, 다른 크기로 그려지는 삼각형도 모형자 하나만 있으면 모두들 똑같은 삼각형... 부운영자 2020.08.13 52
217 XE코어 logged_info $logged_info XE에 접근하면 XE는 항상 방문자의 로그인 여부를 우선 먼저 확인하게 된다. 이때 사용하는 변수가 $is_logged 와 $logged_info 이다. Context.class.php 파일 137라인을 참고해 보면 member 모듈의 member.controller.php 파일의 메서드(해야 할 일)를 참고하여 방문자가 로그인했는지, 로그인했다면 세션과 ... 부운영자 2020.08.13 112
216 XE코어 getUrl() getUrl() XE 레이아웃에 많이 쓰이는 getUrl() 함수이다. &quot;getUrl()은 현재 요청된 RequestURI에 주어진 인자의 값으로 변형하여 url을 리턴한다.&quot;고 설명되어 있다. 또한 인자는 (key, value)... 의 형식으로 주어져야 하고 (예... getUrl(&#039;key1&#039;,&#039;val1&#039;, &#039;key2&#039;, &#039;&#039;) : key1, key2를 val1과 &#039;&#039; 로 변형) 아무런 인자가 없... 부운영자 2020.08.13 120
215 XE코어 Context.class.php 요청 인자(request arguments), 환경 변수(environment variables)와 같은 모든 컨텍스트(Context)를 관리 Context::methodname()로 호출할 수도 있고 정적 객체로도 호출할 수 있는 사용하기 쉬운 이중 방식 구조를 가지고 있다. Context는 GET/POST의 값을 수신하고 변수와 다양한 정보를 템플릿에 전달한다. 또한, 요청이... 부운영자 2020.08.13 95
214 XE코어 Object.class.php XE 모듈 사이의 객체 인스턴스를 전달하는 기본 클래스(데이터를 주고 받기 위한 클래스) 모든 모듈은 객체(Object)를 상속한다. 객체(Object)의 error, message, variables 를 이용하여 통신을 하게 된다 Object 함수 목록 : 속성 var $error = 0; ///&lt; 에러 코드 (0이면 에러 아님) var $message = &#039;success&#039;; ///&lt; 에러 ... 부운영자 2020.08.13 68
213 XE코어 함수라이브러리 func.inc.php clone($object) iconv($in_charset, $out_charset, $str) &amp;getModule($module_name, $type = &#039;view&#039;, $kind = &#039;&#039;) &amp;getController($module_name) &amp;getAdminController($module_name) &amp;getView($module_name) &amp;getMobile($module_name) &amp;getAdminView($module_name) &amp;getModel($module_name) &amp;getAdminModel($module_name) &amp;g... 부운영자 2020.08.13 154
212 XE코어 환경설정 config.inc.php XE의 버전 및 개발자용 디버깅 설정이 저장된 파일 XE가 기본적으로 사용하는 함수라이브러리 func.inc.php 파일과 클래스(class)파일을 시작페이지 index.php 파일로 가져간다 define(&#039;ZBXE_VERSION&#039;, &#039;1.4.5.7&#039;); XE코어의 버전은 이곳에서 정의된다. require(XE_PATH.&#039;config/func.inc.php&#039;); XE코어에서 사용하기 위한 ... 부운영자 2020.08.13 55
211 XE코어 XML 쿼리 언어 XML 쿼리 언어 XML Query Language SMaker님의 글을 전문인용하여 재구성하였다. - http://xe.xpressengine.net/wiki/18180631 개요 쿼리 사용방법 XML sample Select query 예제 Join Select 예제 Letf Join Select 예제 Insert 예제 update 예제 delete 예제 Select Click Count 예제 개요 XpressEngine는 SQL 쿼리를 그대... 부운영자 2020.08.12 49
210 XE코어 XE 템플릿 문법 XE 템플릿 문법의 이해 기본 문법 default 파일 포함 include 조건문 IF 반복문 loop 부운영자 2020.08.12 33
209 XE코어 유용한 함수들 getUrl() logged_info 부운영자 2020.08.12 41
List
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 ... 14 Next
/ 14