├── .gitignore
├── assets
├── css
│ ├── _mixins.scss
│ ├── admin.css
│ ├── admin.scss
│ ├── woo-projects-handheld.css
│ ├── woo-projects-handheld.scss
│ ├── woo-projects.css
│ └── woo-projects.scss
├── images
│ └── placeholder.png
└── js
│ ├── admin.js
│ ├── script.js
│ └── script.min.js
├── classes
├── class-projects-admin.php
├── class-projects-frontend.php
├── class-projects-integrations.php
├── class-projects-query.php
├── class-projects-settings.php
├── class-projects-shortcodes.php
├── class-projects-taxonomy.php
├── class-projects-template-loader.php
├── class-widget-project-categories.php
└── class-widget-projects.php
├── config.codekit
├── dummy_data.xml
├── lang
└── projects-by-woothemes.pot
├── projects-core-functions.php
├── projects-hooks.php
├── projects-template.php
├── projects.php
├── readme.txt
└── templates
├── archive-project.php
├── content-project-category.php
├── content-project-widget.php
├── content-project.php
├── content-single-project.php
├── layout
├── sidebar.php
├── wrapper-end.php
└── wrapper-start.php
├── loop
├── loop-end.php
├── loop-start.php
├── no-projects-found.php
├── pagination.php
└── short-description.php
├── single-project.php
├── single-project
├── description.php
├── meta.php
├── pagination.php
├── project-feature.php
├── project-gallery.php
├── short-description.php
└── title.php
└── taxonomy-project-category.php
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .sass-cache
--------------------------------------------------------------------------------
/assets/css/_mixins.scss:
--------------------------------------------------------------------------------
1 | @import "bourbon";
2 |
3 | // Vars
4 | $error: #f63121;
5 |
6 | // Mixins
7 | @mixin iconbefore( $glyph: "\f179" )
8 | {
9 | font-family: 'dashicons';
10 | vertical-align: top;
11 | margin-right: .618em;
12 | content: $glyph;
13 | }
14 |
15 | @mixin iconafter( $glyph: "\f179" )
16 | {
17 | font-family: 'dashicons';
18 | vertical-align: top;
19 | margin-left: .618em;
20 | content: $glyph;
21 | }
22 |
23 | @mixin icon( $glyph: "\f179" )
24 | {
25 | font-family: 'dashicons';
26 | speak: none;
27 | font-weight: normal;
28 | font-variant: normal;
29 | text-transform: none;
30 | line-height: 1;
31 | -webkit-font-smoothing: antialiased;
32 | margin:0;
33 | text-indent: 0;
34 | position: absolute;
35 | top:0;
36 | left:0;
37 | width:100%;
38 | height: 100%;
39 | text-align: center;
40 | content: $glyph;
41 | }
42 |
43 | // Mixins
44 | @mixin border_radius_reset()
45 | {
46 | -webkit-border-radius: none;
47 | -moz-border-radius: none;
48 | border-radius: none;
49 | }
50 |
51 | @mixin opacity($opacity:0.75)
52 | {
53 | opacity: $opacity;
54 | filter: alpha(opacity=$opacity * 100);
55 | }
--------------------------------------------------------------------------------
/assets/css/admin.css:
--------------------------------------------------------------------------------
1 | .post-type-project.edit-php table.wp-list-table .column-image {
2 | width: 120px;
3 | text-align: center; }
4 | .post-type-project.edit-php table.wp-list-table .column-image img {
5 | width: 60px;
6 | height: auto; }
7 |
8 | #project-images .inside {
9 | margin: 0;
10 | padding: 0; }
11 | #project-images .inside .add_project_images {
12 | padding: 0 12px 12px; }
13 | #project-images .inside #project_images_container {
14 | padding: 0 0 0 9px; }
15 | #project-images .inside #project_images_container ul {
16 | margin: 0;
17 | padding: 0; }
18 | #project-images .inside #project_images_container ul:after {
19 | content: "";
20 | display: table;
21 | clear: both; }
22 | #project-images .inside #project_images_container ul li.image,
23 | #project-images .inside #project_images_container ul li.add,
24 | #project-images .inside #project_images_container ul li.projects-metabox-sortable-placeholder {
25 | width: 80px;
26 | float: left;
27 | cursor: move;
28 | margin: 9px 9px 0 0;
29 | background: #f7f7f7;
30 | position: relative;
31 | background: #000;
32 | -webkit-box-sizing: border-box;
33 | /* Safari/Chrome, other WebKit */
34 | -moz-box-sizing: border-box;
35 | /* Firefox, other Gecko */
36 | box-sizing: border-box;
37 | /* Opera/IE 8+ */ }
38 | #project-images .inside #project_images_container ul li.image img,
39 | #project-images .inside #project_images_container ul li.add img,
40 | #project-images .inside #project_images_container ul li.projects-metabox-sortable-placeholder img {
41 | width: 100%;
42 | height: auto;
43 | display: block;
44 | -webkit-animation: all ease 0.2s;
45 | -moz-animation: all ease 0.2s;
46 | animation: all ease 0.2s; }
47 | #project-images .inside #project_images_container ul li.image:hover img,
48 | #project-images .inside #project_images_container ul li.add:hover img,
49 | #project-images .inside #project_images_container ul li.projects-metabox-sortable-placeholder:hover img {
50 | opacity: 0.75;
51 | filter: alpha(opacity=75); }
52 | #project-images .inside #project_images_container ul li.projects-metabox-sortable-placeholder {
53 | background: #f1f1f1; }
54 | #project-images .inside #project_images_container ul ul.actions {
55 | position: absolute;
56 | top: 0;
57 | right: 0;
58 | -webkit-animation: all ease 0.2s;
59 | -moz-animation: all ease 0.2s;
60 | animation: all ease 0.2s;
61 | opacity: 0;
62 | filter: alpha(opacity=0); }
63 | #project-images .inside #project_images_container ul ul.actions li {
64 | float: right; }
65 | #project-images .inside #project_images_container ul ul.actions li a {
66 | width: 20px;
67 | margin: 0;
68 | height: 20px;
69 | font-size: 16px;
70 | display: block;
71 | overflow: hidden;
72 | color: #fff;
73 | background: #000;
74 | font-weight: 300;
75 | line-height: 20px;
76 | text-align: center;
77 | text-decoration: none;
78 | -webkit-animation: all ease 0.2s;
79 | -moz-animation: all ease 0.2s;
80 | animation: all ease 0.2s; }
81 | #project-images .inside #project_images_container ul ul.actions li a.edit, #project-images .inside #project_images_container ul ul.actions li a.delete {
82 | text-indent: -999px;
83 | position: relative;
84 | background: #000; }
85 | #project-images .inside #project_images_container ul ul.actions li a.edit:before, #project-images .inside #project_images_container ul ul.actions li a.delete:before {
86 | content: "\f464";
87 | display: block;
88 | position: absolute;
89 | top: 0;
90 | right: 0;
91 | bottom: 0;
92 | left: 0;
93 | font-family: 'Dashicons';
94 | color: #fff;
95 | text-indent: 0;
96 | font-weight: normal; }
97 | #project-images .inside #project_images_container ul ul.actions li a.edit:hover, #project-images .inside #project_images_container ul ul.actions li a.delete:hover {
98 | background: #444; }
99 | #project-images .inside #project_images_container ul ul.actions li a.delete {
100 | background-color: #f63121; }
101 | #project-images .inside #project_images_container ul ul.actions li a.delete:before {
102 | content: "\f335"; }
103 | #project-images .inside #project_images_container ul ul.actions li a.delete:hover {
104 | background: #d40f00; }
105 | #project-images .inside #project_images_container ul li:hover ul.actions {
106 | opacity: 1;
107 | filter: alpha(opacity=100); }
108 |
109 | .post-type-project .ui-autocomplete {
110 | font-family: inherit;
111 | font-size: 1em;
112 | background: #fafafa;
113 | -webkit-box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.1);
114 | box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.1);
115 | -webkit-border-radius: 0 0 4px 4px;
116 | border-radius: 0 0 4px 4px;
117 | -webkit-transform: translateY(-1px);
118 | transform: translateY(-1px); }
119 | .post-type-project .ui-autocomplete li a {
120 | -webkit-border-radius: 0;
121 | border-radius: 0;
122 | border: 0;
123 | background: none; }
124 | .post-type-project .ui-autocomplete li a:hover {
125 | border: 0;
126 | background: #f6f6f6; }
127 | .post-type-project .ui-autocomplete li:last-child a {
128 | -webkit-border-radius: 0 0 4px 4px;
129 | border-radius: 0 0 4px 4px; }
130 | .post-type-project .projects-radio label {
131 | display: block;
132 | line-height: 1.5; }
133 |
--------------------------------------------------------------------------------
/assets/css/admin.scss:
--------------------------------------------------------------------------------
1 | // Imports
2 | @import 'mixins';
3 |
4 | // Projects screen
5 | .post-type-project.edit-php {
6 | table.wp-list-table {
7 | .column-image {
8 | width: 120px;
9 | text-align: center;;
10 |
11 | img {
12 | width: 60px;
13 | height: auto;
14 | }
15 | }
16 | }
17 | }
18 |
19 | // Project Gallery
20 | #project-images {
21 | .inside {
22 | margin: 0;
23 | padding: 0;
24 | .add_project_images {
25 | padding: 0 12px 12px;
26 | }
27 | #project_images_container {
28 | padding: 0 0 0 9px;
29 | ul {
30 | margin: 0;
31 | padding: 0;
32 | @include clearfix;
33 |
34 | li.image,
35 | li.add,
36 | li.projects-metabox-sortable-placeholder {
37 | width: 80px;
38 | float: left;
39 | cursor: move;
40 | margin: 9px 9px 0 0;
41 | background: #f7f7f7;
42 | position: relative;
43 | background: #000;
44 | -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
45 | -moz-box-sizing: border-box; /* Firefox, other Gecko */
46 | box-sizing: border-box; /* Opera/IE 8+ */
47 | img {
48 | width: 100%;
49 | height: auto;
50 | display: block;
51 | @include animation(all ease .2s);
52 | }
53 | &:hover {
54 | img {
55 | @include opacity(0.75);
56 | }
57 | }
58 | }
59 | li.projects-metabox-sortable-placeholder {
60 | background: #f1f1f1;
61 | }
62 | ul.actions {
63 | position: absolute;
64 | top:0;
65 | right: 0;
66 | @include animation(all ease .2s);
67 | @include opacity(0);
68 | li {
69 | float: right;
70 | //margin: 0 0 0 1px;
71 | a {
72 | width: 20px;
73 | margin: 0;
74 | height: 20px;
75 | font-size: 16px;
76 | display: block;
77 | overflow: hidden;
78 | color: #fff;
79 | background:#000;
80 | font-weight: 300;
81 | line-height: 20px;
82 | text-align: center;
83 | text-decoration: none;
84 | @include animation(all ease .2s);
85 | &.edit,
86 | &.delete {
87 | text-indent: -999px;
88 | position: relative;
89 | background: #000;
90 |
91 | &:before {
92 | content: "\f464";
93 | display: block;
94 | position: absolute;
95 | top: 0;
96 | right: 0;
97 | bottom: 0;
98 | left: 0;
99 | font-family: 'Dashicons';
100 | color: #fff;
101 | text-indent: 0;
102 | font-weight: normal;
103 | }
104 |
105 | &:hover {
106 | background: #444;
107 | }
108 | }
109 |
110 | &.delete {
111 | background-color: $error;
112 | &:before {
113 | content: "\f335";
114 | }
115 | &:hover {
116 | background: $error - #222;
117 | }
118 | }
119 | }
120 | }
121 | }
122 | li:hover ul.actions {
123 | @include opacity(1);
124 | }
125 | }
126 | }
127 | }
128 | }
129 |
130 | // Autocomplete
131 | .post-type-project {
132 | .ui-autocomplete {
133 | font-family: inherit;
134 | font-size: 1em;
135 | background: #fafafa;
136 | -webkit-box-shadow: 0 1px 2px 0 rgba(0,0,0,0.1);
137 | box-shadow: 0 1px 2px 0 rgba(0,0,0,0.1);
138 | -webkit-border-radius: 0 0 4px 4px;
139 | border-radius: 0 0 4px 4px;
140 | -webkit-transform: translateY(-1px);
141 | transform: translateY(-1px);
142 | li {
143 | a {
144 | -webkit-border-radius: 0;
145 | border-radius: 0;
146 | border: 0;
147 | background: none;
148 | &:hover {
149 | border: 0;
150 | background: #f6f6f6;
151 | }
152 | }
153 | &:last-child {
154 | a {
155 | -webkit-border-radius: 0 0 4px 4px;
156 | border-radius: 0 0 4px 4px;
157 | }
158 | }
159 | }
160 | }
161 |
162 | .projects-radio {
163 | label {
164 | display: block;
165 | line-height: 1.5;
166 | }
167 | }
168 | }
--------------------------------------------------------------------------------
/assets/css/woo-projects-handheld.css:
--------------------------------------------------------------------------------
1 | @media only screen and (max-width: 768px) {
2 | .projects ul.projects li.project, .projects-page ul.projects li.project {
3 | width: 48%;
4 | float: left;
5 | clear: both; }
6 | .projects ul.projects li.project:nth-child(2n), .projects-page ul.projects li.project:nth-child(2n) {
7 | margin-right: 0;
8 | float: right;
9 | clear: none !important; }
10 |
11 | .single-project.has-gallery .gallery,
12 | .single-project.has-gallery .summary {
13 | width: 100%;
14 | float: none;
15 | padding: 0; }
16 | .single-project.has-gallery .summary > div {
17 | font-size: 1em; }
18 | .single-project.no-gallery .project_title,
19 | .single-project.no-gallery .single-project-description,
20 | .single-project.no-gallery .project-meta {
21 | width: 100% !important;
22 | float: none; } }
23 |
--------------------------------------------------------------------------------
/assets/css/woo-projects-handheld.scss:
--------------------------------------------------------------------------------
1 | // Imports
2 | @import 'mixins';
3 |
4 | // Styles for handheld devices
5 |
6 | @media only screen and ( max-width: 768px ) {
7 |
8 |
9 |
10 | .projects, .projects-page {
11 | ul.projects {
12 | li.project {
13 | width:48%;
14 | float: left;
15 | clear:both;
16 | &:nth-child(2n) {
17 | margin-right:0;
18 | float: right;
19 | clear: none !important;
20 | }
21 | }
22 | }
23 | }
24 |
25 | .single-project {
26 | &.has-gallery {
27 | .gallery,
28 | .summary {
29 | width: 100%;
30 | float: none;
31 | padding: 0;
32 | }
33 |
34 | .summary {
35 | > div {
36 | font-size: 1em;
37 | }
38 | }
39 | }
40 |
41 | &.no-gallery {
42 | .project_title,
43 | .single-project-description,
44 | .project-meta {
45 | width: 100% !important;
46 | float: none;
47 | }
48 | }
49 | }
50 |
51 | }
--------------------------------------------------------------------------------
/assets/css/woo-projects.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Layout Styles
3 | */
4 | .projects ul.projects,
5 | .projects-page ul.projects {
6 | list-style: none;
7 | margin: 0;
8 | margin-left: 0 !important;
9 | padding: 0 !important;
10 | *zoom: 1; }
11 | .projects ul.projects:before, .projects ul.projects:after,
12 | .projects-page ul.projects:before,
13 | .projects-page ul.projects:after {
14 | content: " ";
15 | display: table; }
16 | .projects ul.projects:after,
17 | .projects-page ul.projects:after {
18 | clear: both; }
19 | .projects ul.projects li.project,
20 | .projects-page ul.projects li.project {
21 | margin: 0 0 2.618em;
22 | padding: 0;
23 | width: 48%;
24 | float: left;
25 | margin-right: 3.8%; }
26 | .projects ul.projects li.project .project-thumbnail,
27 | .projects-page ul.projects li.project .project-thumbnail {
28 | margin: 0 0 1em; }
29 | .projects ul.projects li.project a,
30 | .projects-page ul.projects li.project a {
31 | text-decoration: none; }
32 | .projects ul.projects li.project h3,
33 | .projects-page ul.projects li.project h3 {
34 | margin-bottom: .618em; }
35 | .projects ul.projects li.project img,
36 | .projects-page ul.projects li.project img {
37 | max-width: 100%;
38 | height: auto;
39 | -webkit-box-shadow: none;
40 | -moz-box-shadow: none;
41 | box-shadow: none;
42 | border-top-left-radius: 0;
43 | border-top-right-radius: 0;
44 | border-bottom-left-radius: 0;
45 | border-bottom-right-radius: 0;
46 | padding: 0;
47 | border: 0;
48 | margin: 0 auto;
49 | display: block; }
50 | .projects ul.projects li.project.first,
51 | .projects-page ul.projects li.project.first {
52 | clear: both; }
53 | .projects ul.projects li.project.last,
54 | .projects-page ul.projects li.project.last {
55 | margin-right: 0; }
56 | .projects ul.project-categories,
57 | .projects-page ul.project-categories {
58 | margin-left: 0 !important;
59 | padding: 0 !important;
60 | list-style: none; }
61 | .projects ul.project-categories:after,
62 | .projects-page ul.project-categories:after {
63 | content: "";
64 | display: table;
65 | clear: both; }
66 | .projects ul.project-categories li,
67 | .projects-page ul.project-categories li {
68 | display: inline-block;
69 | margin-right: .5em;
70 | list-style: none;
71 | margin-left: 0 !important; }
72 | .projects ul.project-categories li:after,
73 | .projects-page ul.project-categories li:after {
74 | content: "|";
75 | display: inline-block;
76 | padding-left: .5em; }
77 | .projects ul.project-categories li:last-child:after,
78 | .projects-page ul.project-categories li:last-child:after {
79 | display: none; }
80 | .projects .projects-pagination,
81 | .projects-page .projects-pagination {
82 | text-align: center; }
83 | .projects .projects-pagination li,
84 | .projects-page .projects-pagination li {
85 | display: inline-block;
86 | margin: 0 .236em; }
87 |
88 | .projects.columns-2:after, .projects.columns-3:after, .projects.columns-4:after, .projects.columns-5:after, .projects.columns-6:after {
89 | content: "";
90 | display: table;
91 | clear: both; }
92 | .projects.columns-2 ul.projects li.project, .projects.columns-3 ul.projects li.project, .projects.columns-4 ul.projects li.project, .projects.columns-5 ul.projects li.project, .projects.columns-6 ul.projects li.project {
93 | float: left;
94 | margin-right: 3.8%;
95 | clear: none; }
96 | .projects.columns-2 ul.projects li.project.first, .projects.columns-3 ul.projects li.project.first, .projects.columns-4 ul.projects li.project.first, .projects.columns-5 ul.projects li.project.first, .projects.columns-6 ul.projects li.project.first {
97 | clear: both; }
98 | .projects.columns-2 ul.projects li.project.last, .projects.columns-3 ul.projects li.project.last, .projects.columns-4 ul.projects li.project.last, .projects.columns-5 ul.projects li.project.last, .projects.columns-6 ul.projects li.project.last {
99 | margin-right: 0; }
100 | .projects.columns-2 ul.projects li.project:nth-child(2), .projects.columns-3 ul.projects li.project:nth-child(2), .projects.columns-4 ul.projects li.project:nth-child(2), .projects.columns-5 ul.projects li.project:nth-child(2), .projects.columns-6 ul.projects li.project:nth-child(2) {
101 | float: left;
102 | clear: none; }
103 | .projects.columns-1 ul.projects li.project {
104 | width: 100%; }
105 | .projects.columns-2 ul.projects li.project {
106 | width: 48%; }
107 | .projects.columns-3 ul.projects li.project {
108 | width: 30.75%; }
109 | .projects.columns-4 ul.projects li.project {
110 | width: 22.05%; }
111 | .projects.columns-5 ul.projects li.project {
112 | width: 16.9%; }
113 | .projects.columns-6 ul.projects li.project {
114 | width: 13.5%; }
115 |
116 | .single-project .project {
117 | margin-bottom: 1.618em; }
118 | .single-project .project:after {
119 | content: "";
120 | display: table;
121 | clear: both; }
122 | .single-project .project .single-project-short-description {
123 | margin-bottom: 1.618em; }
124 | .single-project .project .summary .single-project-categories li:before {
125 | font-family: 'dashicons';
126 | vertical-align: top;
127 | margin-right: .618em;
128 | content: "\f318"; }
129 | .single-project .project .summary .client-name:before {
130 | font-family: 'dashicons';
131 | vertical-align: top;
132 | margin-right: .618em;
133 | content: "\f338"; }
134 | .single-project .project .summary .project-url:before {
135 | font-family: 'dashicons';
136 | vertical-align: top;
137 | margin-right: .618em;
138 | content: "\f319"; }
139 | .single-project .project .summary .single-project-categories,
140 | .single-project .project .summary .url,
141 | .single-project .project .summary .client {
142 | margin-bottom: 1.618em; }
143 | .single-project .project .summary .project-meta ul,
144 | .single-project .project .summary .project-meta li {
145 | list-style: none; }
146 | .single-project .project .summary .purchase .amount {
147 | display: block; }
148 | .single-project .single-featured {
149 | margin-bottom: 1.618em; }
150 | .single-project.has-gallery .gallery {
151 | width: 62%;
152 | float: left; }
153 | .single-project.has-gallery .gallery a {
154 | display: block; }
155 | .single-project.has-gallery .gallery img {
156 | border-top-left-radius: 0;
157 | border-top-right-radius: 0;
158 | border-bottom-left-radius: 0;
159 | border-bottom-right-radius: 0;
160 | max-width: 100%;
161 | height: auto;
162 | -webkit-box-shadow: none;
163 | -moz-box-shadow: none;
164 | box-shadow: none;
165 | display: block; }
166 | .single-project.has-gallery .summary {
167 | width: 38%;
168 | float: right;
169 | padding: 0 0 0 2.618em;
170 | -webkit-box-sizing: border-box;
171 | -moz-box-sizing: border-box;
172 | box-sizing: border-box; }
173 | .single-project.has-gallery .summary > div {
174 | font-size: .857em; }
175 | .single-project.no-gallery .summary:after {
176 | content: "";
177 | display: table;
178 | clear: both; }
179 | .single-project.no-gallery .summary .project_title,
180 | .single-project.no-gallery .summary .single-project-description {
181 | width: 62%;
182 | float: left; }
183 | .single-project.no-gallery .summary .project-meta {
184 | width: 34%;
185 | float: right; }
186 | .single-project .projects-single-pagination:after {
187 | content: "";
188 | display: table;
189 | clear: both; }
190 | .single-project .projects-single-pagination .previous a,
191 | .single-project .projects-single-pagination .next a {
192 | text-decoration: none; }
193 | .single-project .projects-single-pagination .previous {
194 | float: right; }
195 | .single-project .projects-single-pagination .previous a:after {
196 | font-family: 'dashicons';
197 | vertical-align: top;
198 | margin-left: .618em;
199 | content: "\f344"; }
200 | .single-project .projects-single-pagination .next {
201 | float: left; }
202 | .single-project .projects-single-pagination .next a:before {
203 | font-family: 'dashicons';
204 | vertical-align: top;
205 | margin-right: .618em;
206 | content: "\f340"; }
207 | .single-project .project-testimonial blockquote {
208 | padding: 1.618em;
209 | border: 1px solid rgba(0, 0, 0, 0.1);
210 | position: relative;
211 | margin: 0;
212 | margin-bottom: 1.387em; }
213 | .single-project .project-testimonial blockquote:after {
214 | content: "";
215 | display: block;
216 | border: 10px solid rgba(0, 0, 0, 0.1);
217 | border-color: rgba(0, 0, 0, 0.1) transparent transparent transparent;
218 | position: absolute;
219 | bottom: -21px;
220 | left: 1em; }
221 | .single-project .project-testimonial .quote:after {
222 | content: "";
223 | display: table;
224 | clear: both; }
225 | .single-project .project-testimonial .quote .avatar-link {
226 | float: left;
227 | display: block;
228 | margin: 0 1em 1em 0; }
229 | .single-project .project-testimonial .quote cite span {
230 | display: block; }
231 |
232 | /**
233 | * Widgets
234 | */
235 | .projects_list_widget li {
236 | margin-bottom: 1.618em; }
237 | .projects_list_widget li a {
238 | display: block; }
239 | .projects_list_widget li a:after {
240 | content: "";
241 | display: table;
242 | clear: both; }
243 | .projects_list_widget li img {
244 | float: right;
245 | max-width: 60px;
246 | height: auto; }
247 | .projects_list_widget li .project-title {
248 | float: left; }
249 |
250 | .widget_projects_categories ul.children {
251 | margin-left: 2.618em; }
252 |
253 | /**
254 | * Twenty Thirteen Specific
255 | */
256 | .single-project .twentythirteen .entry-summary {
257 | padding: 0; }
258 | .single-project .twentythirteen ul.single-project-categories {
259 | padding-left: 0; }
260 | .single-project.has-gallery .twentythirteen .summary {
261 | width: 36%; }
262 | .single-project.has-gallery .twentythirteen .gallery {
263 | width: 61%; }
264 |
265 | /**
266 | * Twenty Fourteen Specific
267 | */
268 | .single-project.has-gallery .tfp .gallery {
269 | width: 50%; }
270 | .single-project.has-gallery .tfp .entry-summary {
271 | width: 50%;
272 | padding-left: 2.618em !important; }
273 |
274 | .twentyfourteen .tfp {
275 | padding: 12px 10px 0;
276 | max-width: 474px;
277 | margin: 0 auto; }
278 | .twentyfourteen .tfp .project .entry-summary {
279 | padding: 0;
280 | margin: 0 0 1.618em !important; }
281 | .twentyfourteen .tfp div.project.hentry.has-post-thumbnail {
282 | margin-top: 0; }
283 | .twentyfourteen .tfp .project .images img {
284 | margin-bottom: 1em; }
285 |
286 | @media screen and (min-width: 673px) {
287 | .twentyfourteen .tfp {
288 | padding-right: 30px;
289 | padding-left: 30px; } }
290 | @media screen and (min-width: 1040px) {
291 | .twentyfourteen .tfp {
292 | padding-right: 15px;
293 | padding-left: 15px; } }
294 | @media screen and (min-width: 1110px) {
295 | .twentyfourteen .tfp {
296 | padding-right: 30px;
297 | padding-left: 30px; } }
298 | @media screen and (min-width: 1218px) {
299 | .twentyfourteen .tfp {
300 | margin-right: 54px; }
301 |
302 | .full-width .twentyfourteen .tfp {
303 | margin-right: auto; } }
304 |
--------------------------------------------------------------------------------
/assets/css/woo-projects.scss:
--------------------------------------------------------------------------------
1 | // Imports
2 | @import 'mixins';
3 |
4 | /**
5 | * Layout Styles
6 | */
7 | .projects,
8 | .projects-page {
9 | ul.projects {
10 | list-style: none;
11 | margin: 0;
12 | margin-left: 0 !important;
13 | padding: 0 !important;
14 | *zoom: 1;
15 |
16 | &:before, &:after {
17 | content: " ";
18 | display: table;
19 | }
20 |
21 | &:after {
22 | clear: both;
23 | }
24 |
25 | li.project {
26 | margin: 0 0 2.618em;
27 | padding: 0;
28 | width: 48%;
29 | float: left;
30 | margin-right: 3.8%;
31 |
32 | .project-thumbnail {
33 | margin: 0 0 1em;
34 | }
35 |
36 | a {
37 | text-decoration: none;
38 | }
39 |
40 | h3 {
41 | margin-bottom: .618em;
42 | }
43 |
44 | img {
45 | max-width: 100%;
46 | height: auto;
47 | -webkit-box-shadow: none;
48 | -moz-box-shadow: none;
49 | box-shadow: none;
50 | @include border-top-radius(0);
51 | @include border-bottom-radius(0);
52 | padding: 0;
53 | border: 0;
54 | margin: 0 auto;
55 | display: block;
56 | }
57 |
58 | &.first {
59 | clear: both;
60 | }
61 |
62 | &.last {
63 | margin-right: 0;
64 | }
65 | }
66 | }
67 |
68 | ul.project-categories {
69 | margin-left: 0 !important;
70 | padding: 0 !important;
71 | @include clearfix;
72 | list-style: none;
73 |
74 | li {
75 | display: inline-block;
76 | margin-right: .5em;
77 | list-style: none;
78 | margin-left: 0 !important;
79 |
80 | &:after {
81 | content: "|";
82 | display: inline-block;
83 | padding-left: .5em;
84 | }
85 |
86 | &:last-child {
87 | &:after {
88 | display: none;
89 | }
90 | }
91 | }
92 | }
93 |
94 | .projects-pagination {
95 | text-align: center;
96 |
97 | li {
98 | display: inline-block;
99 | margin:0 .236em;
100 | }
101 | }
102 | }
103 |
104 | .projects {
105 | &.columns-2,
106 | &.columns-3,
107 | &.columns-4,
108 | &.columns-5,
109 | &.columns-6 {
110 | @include clearfix;
111 |
112 | ul.projects li.project {
113 | float: left;
114 | margin-right: 3.8%;
115 | clear: none;
116 |
117 | &.first {
118 | clear: both;
119 | }
120 |
121 | &.last {
122 | margin-right: 0;
123 | }
124 |
125 | &:nth-child(2) {
126 | float: left;
127 | clear: none;
128 | }
129 | }
130 | }
131 |
132 | &.columns-1 {
133 | ul.projects li.project {
134 | width: 100%;
135 | }
136 | }
137 |
138 | &.columns-2 {
139 | ul.projects li.project {
140 | width: 48%;
141 | }
142 | }
143 |
144 | &.columns-3 {
145 | ul.projects li.project {
146 | width: 30.75%;
147 | }
148 | }
149 |
150 | &.columns-4 {
151 | ul.projects li.project {
152 | width: 22.05%;
153 | }
154 | }
155 |
156 | &.columns-5 {
157 | ul.projects li.project {
158 | width: 16.9%;
159 | }
160 | }
161 |
162 | &.columns-6 {
163 | ul.projects li.project {
164 | width: 13.5%;
165 | }
166 | }
167 | }
168 |
169 | .single-project {
170 | .project {
171 | @include clearfix;
172 | margin-bottom: 1.618em;
173 |
174 | .single-project-short-description {
175 | margin-bottom: 1.618em;
176 | }
177 |
178 | .summary {
179 | .single-project-categories {
180 | li:before {
181 | @include iconbefore( "\f318" );
182 | }
183 | }
184 |
185 | .client-name {
186 | &:before {
187 | @include iconbefore( "\f338" );
188 | }
189 | }
190 |
191 | .project-url {
192 | &:before {
193 | @include iconbefore( "\f319" );
194 | }
195 | }
196 |
197 | .single-project-categories,
198 | .url,
199 | .client {
200 | margin-bottom: 1.618em;
201 | }
202 |
203 | .project-meta {
204 | ul,
205 | li {
206 | list-style: none;
207 | }
208 | }
209 |
210 | .purchase {
211 | .amount {
212 | display: block;
213 | }
214 | }
215 | }
216 | }
217 |
218 | .single-featured {
219 | margin-bottom: 1.618em;
220 | }
221 |
222 | &.has-gallery {
223 | .gallery {
224 | width: 62%;
225 | float: left;
226 | a {
227 | display: block;
228 | }
229 |
230 | img {
231 | @include border-top-radius(0);
232 | @include border-bottom-radius(0);
233 | max-width: 100%;
234 | height: auto;
235 | -webkit-box-shadow: none;
236 | -moz-box-shadow: none;
237 | box-shadow: none;
238 | display: block;
239 | }
240 | }
241 | .summary {
242 | width: 38%;
243 | float: right;
244 | padding: 0 0 0 2.618em;
245 | @include box-sizing(border-box);
246 | > div {
247 | font-size: .857em;
248 | }
249 | }
250 | }
251 |
252 | &.no-gallery {
253 | .summary {
254 | @include clearfix;
255 |
256 | .project_title,
257 | .single-project-description {
258 | width: 62%;
259 | float: left;
260 | }
261 |
262 | .project-meta {
263 | width: 34%;
264 | float: right;
265 | }
266 | }
267 | }
268 |
269 | .projects-single-pagination {
270 | @include clearfix;
271 |
272 | .previous,
273 | .next {
274 | a {
275 | text-decoration: none;
276 | }
277 | }
278 |
279 | .previous {
280 | float: right;
281 |
282 | a:after {
283 | @include iconafter( "\f344" );
284 | }
285 | }
286 |
287 | .next {
288 | float: left;
289 |
290 | a:before {
291 | @include iconbefore( "\f340" );
292 | }
293 | }
294 | }
295 |
296 | .project-testimonial {
297 | blockquote {
298 | padding: 1.618em;
299 | border: 1px solid rgba(0,0,0,0.1);
300 | position: relative;
301 | margin: 0;
302 | margin-bottom: 1.387em;
303 |
304 | &:after {
305 | content: "";
306 | display: block;
307 | border: 10px solid rgba(0,0,0,0.1);
308 | border-color: rgba(0,0,0,0.1) transparent transparent transparent;
309 | position: absolute;
310 | bottom: -21px;
311 | left: 1em;
312 | }
313 | }
314 |
315 | .quote {
316 | @include clearfix();
317 |
318 | .avatar-link {
319 | float: left;
320 | display: block;
321 | margin: 0 1em 1em 0;
322 | }
323 |
324 | cite {
325 | span {
326 | display: block;
327 | }
328 | }
329 | }
330 | }
331 | }
332 |
333 | /**
334 | * Widgets
335 | */
336 | .projects_list_widget {
337 | li {
338 | margin-bottom: 1.618em;
339 |
340 | a {
341 | display: block;
342 | @include clearfix;
343 | }
344 |
345 | img {
346 | float: right;
347 | max-width: 60px;
348 | height: auto;
349 | }
350 |
351 | .project-title {
352 | float: left;
353 | }
354 | }
355 | }
356 |
357 | .widget_projects_categories {
358 | ul.children {
359 | margin-left: 2.618em;
360 | }
361 | }
362 |
363 | /**
364 | * Twenty Thirteen Specific
365 | */
366 | .single-project {
367 | .twentythirteen {
368 | .entry-summary {
369 | padding: 0;
370 | }
371 |
372 | ul.single-project-categories {
373 | padding-left: 0;
374 | }
375 | }
376 |
377 | &.has-gallery {
378 | .twentythirteen {
379 | .summary {
380 | width: 36%;
381 | }
382 |
383 | .gallery {
384 | width: 61%;
385 | }
386 | }
387 | }
388 | }
389 |
390 | /**
391 | * Twenty Fourteen Specific
392 | */
393 | .single-project.has-gallery {
394 | .tfp {
395 | .gallery {
396 | width: 50%;
397 | }
398 |
399 | .entry-summary {
400 | width: 50%;
401 | padding-left: 2.618em !important;
402 | }
403 | }
404 | }
405 |
406 | .twentyfourteen {
407 | .tfp {
408 | padding: 12px 10px 0;
409 | max-width: 474px;
410 | margin:0 auto;
411 | .project .entry-summary {
412 | padding: 0;
413 | margin: 0 0 1.618em !important;
414 | }
415 | div.project.hentry.has-post-thumbnail {
416 | margin-top:0;
417 | }
418 | .project {
419 | .images {
420 | img {
421 | margin-bottom:1em;
422 | }
423 | }
424 | }
425 | }
426 | }
427 |
428 | @media screen and (min-width: 673px) {
429 | .twentyfourteen {
430 | .tfp {
431 | padding-right: 30px;
432 | padding-left: 30px;
433 | }
434 | }
435 | }
436 |
437 | @media screen and (min-width: 1040px) {
438 | .twentyfourteen {
439 | .tfp {
440 | padding-right: 15px;
441 | padding-left: 15px;
442 | }
443 | }
444 | }
445 |
446 | @media screen and (min-width: 1110px) {
447 | .twentyfourteen {
448 | .tfp {
449 | padding-right: 30px;
450 | padding-left: 30px;
451 | }
452 | }
453 | }
454 |
455 | @media screen and (min-width: 1218px) {
456 | .twentyfourteen {
457 | .tfp {
458 | margin-right: 54px;
459 | }
460 | }
461 | .full-width {
462 | .twentyfourteen {
463 | .tfp {
464 | margin-right: auto;
465 | }
466 | }
467 | }
468 | }
--------------------------------------------------------------------------------
/assets/images/placeholder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/woocommerce/projects/919846f486d268171e16c6a05ed034b520c28755/assets/images/placeholder.png
--------------------------------------------------------------------------------
/assets/js/admin.js:
--------------------------------------------------------------------------------
1 | jQuery(document).ready(function($){
2 |
3 | // Uploading files
4 | var project_gallery_frame;
5 | var $image_gallery_ids = $( '#project_image_gallery' );
6 | var $project_images = $( '#project_images_container ul.project_images' );
7 |
8 | jQuery( '.add_project_images' ).on( 'click', 'a', function( event ) {
9 |
10 | var $el = $(this);
11 | var attachment_ids = $image_gallery_ids.val();
12 |
13 | event.preventDefault();
14 |
15 | // If the media frame already exists, reopen it.
16 | if ( project_gallery_frame ) {
17 | project_gallery_frame.open();
18 | return;
19 | }
20 |
21 | // Create the media frame.
22 | project_gallery_frame = wp.media.frames.downloadable_file = wp.media({
23 | // Set the title of the modal.
24 | title: woo_projects_admin.gallery_title,
25 | button: {
26 | text: woo_projects_admin.gallery_button,
27 | },
28 | multiple: true
29 | });
30 |
31 | // When an image is selected, run a callback.
32 | project_gallery_frame.on( 'select', function() {
33 |
34 | var selection = project_gallery_frame.state().get( 'selection' );
35 |
36 | selection.map( function( attachment ) {
37 |
38 | attachment = attachment.toJSON();
39 |
40 | if ( attachment.id ) {
41 | attachment_ids = attachment_ids ? attachment_ids + "," + attachment.id : attachment.id;
42 |
43 | $project_images.append('\
44 |
\
45 | \
46 | \
49 | ');
50 | }
51 |
52 | } );
53 |
54 | $image_gallery_ids.val( attachment_ids );
55 | });
56 |
57 | // Finally, open the modal.
58 | project_gallery_frame.open();
59 | });
60 |
61 | // Image ordering
62 | $project_images.sortable({
63 | items: 'li.image',
64 | cursor: 'move',
65 | scrollSensitivity:40,
66 | forcePlaceholderSize: true,
67 | forceHelperSize: false,
68 | helper: 'clone',
69 | opacity: 0.65,
70 | placeholder: 'projects-metabox-sortable-placeholder',
71 | start:function(event,ui){
72 | ui.item.css( 'background-color','#f6f6f6' );
73 | },
74 | stop:function(event,ui){
75 | ui.item.removeAttr( 'style' );
76 | },
77 | update: function(event, ui) {
78 | var attachment_ids = '';
79 | $( '#project_images_container ul li.image' ).css( 'cursor','default' ).each(function() {
80 | var attachment_id = jQuery(this).attr( 'data-attachment_id' );
81 | attachment_ids = attachment_ids + attachment_id + ',';
82 | });
83 | $image_gallery_ids.val( attachment_ids );
84 | }
85 | });
86 | // Remove images
87 | $( '#project_images_container' ).on( 'click', 'a.delete', function() {
88 | $(this).closest( 'li.image' ).remove();
89 |
90 | var attachment_ids = '';
91 |
92 | $( '#project_images_container ul li.image' ).css( 'cursor','default' ).each(function() {
93 | var attachment_id = jQuery(this).attr( 'data-attachment_id' );
94 | attachment_ids = attachment_ids + attachment_id + ',';
95 | });
96 |
97 | $image_gallery_ids.val( attachment_ids );
98 |
99 | return false;
100 | } );
101 |
102 |
103 |
104 | // Instantiates the variable that holds the media library frame.
105 | var projects_data_frame;
106 |
107 | // Runs when the image button is clicked.
108 | jQuery( '#project-data' ).on( 'click', '.projects-upload', function( event ) {
109 |
110 | // Prevents the default action from occuring.
111 | event.preventDefault();
112 |
113 | // store button object
114 | $button = $(this);
115 |
116 | // If the frame already exists, re-open it.
117 | if ( projects_data_frame ) {
118 | projects_data_frame.open();
119 | return;
120 | }
121 |
122 | title = $button.data( 'title' ) ? $button.data( 'title' ) : woo_projects_admin.default_title;
123 | button = $button.data( 'button' ) ? $button.data( 'button' ) : woo_projects_admin.default_button;
124 | library = $button.data( 'library' ) ? $button.data( 'library' ) : '';
125 |
126 | // Sets up the media library frame
127 | projects_data_frame = wp.media.frames.projects_data_frame = wp.media({
128 | title: title,
129 | button: { text: button },
130 | library: { type: library }
131 | });
132 |
133 | // Runs when an image is selected.
134 | projects_data_frame.on( 'select', function(){
135 |
136 | // Grabs the attachment selection and creates a JSON representation of the model.
137 | var media_attachment = projects_data_frame.state().get( 'selection' ).first().toJSON();
138 |
139 | // Sends the attachment URL to our custom image input field.
140 | $button.prev( 'input.projects-upload-field' ).val( media_attachment.url );
141 |
142 | });
143 |
144 | // Opens the media library frame.
145 | projects_data_frame.open();
146 | });
147 |
148 | });
--------------------------------------------------------------------------------
/assets/js/script.js:
--------------------------------------------------------------------------------
1 | jQuery(document).ready(function($){
2 | jQuery('ul.sorting a').click(function(e) {
3 | e.preventDefault();
4 | jQuery(this).css('outline','none');
5 | jQuery('ul.sorting .current').removeClass('current');
6 | jQuery(this).parent().addClass('current');
7 |
8 | // filterVal = slug of active link
9 | var filterVal = jQuery(this).text().toLowerCase().replace(' ','-');
10 |
11 | // filterVal default = 'all'
12 | if( filterVal == 'all' ) {
13 | jQuery('ul.projects li.hidden').show().removeClass('hidden').addClass('visible');
14 | } else {
15 |
16 | // Show / hide based on active link
17 | jQuery('ul.projects li').each(function() {
18 |
19 | if( ! jQuery(this).hasClass( filterVal ) ) {
20 | // If the li doesn't have a class = filterVal, hide it
21 | jQuery(this).hide().addClass('hidden').removeClass('visible');
22 | } else {
23 | // If it does, show it
24 | jQuery(this).show().removeClass('hidden').addClass('visible');
25 | }
26 | });
27 | }
28 |
29 | //jQuery('ul.projects').hide().fadeIn(300);
30 |
31 | return false;
32 | });
33 |
34 | jQuery('ul.sorting a').click(function() {
35 | jQuery('ul.projects').find('li').removeClass('last').removeClass('first');
36 | });
37 |
38 | jQuery('ul.sorting a').click(function() {
39 | jQuery('ul.projects li.visible').each(function(i) {
40 | i=( i+1 );
41 | x=( i+2 );
42 | if ( i%3==0 ) {
43 | jQuery(this).removeClass('first').addClass('last');
44 | }
45 | if ( x%3==0 ) {
46 | jQuery(this).removeClass('last').addClass('first');
47 | }
48 | });
49 | });
50 | });
--------------------------------------------------------------------------------
/assets/js/script.min.js:
--------------------------------------------------------------------------------
1 | jQuery(document).ready(function(e){jQuery("ul.sorting a").click(function(e){e.preventDefault();jQuery(this).css("outline","none");jQuery("ul.sorting .current").removeClass("current");jQuery(this).parent().addClass("current");var t=jQuery(this).text().toLowerCase().replace(" ","-");t=="all"?jQuery("ul.projects li.hidden").show().removeClass("hidden").addClass("visible"):jQuery("ul.projects li").each(function(){jQuery(this).hasClass(t)?jQuery(this).show().removeClass("hidden").addClass("visible"):jQuery(this).hide().addClass("hidden").removeClass("visible")});return!1});jQuery("ul.sorting a").click(function(){jQuery("ul.projects").find("li").removeClass("last").removeClass("first")});jQuery("ul.sorting a").click(function(){jQuery("ul.projects li.visible").each(function(e){e+=1;x=e+2;e%3==0&&jQuery(this).removeClass("first").addClass("last");x%3==0&&jQuery(this).removeClass("last").addClass("first")})})});
--------------------------------------------------------------------------------
/classes/class-projects-admin.php:
--------------------------------------------------------------------------------
1 | dir = dirname( $file );
35 | $this->file = $file;
36 | $this->assets_dir = trailingslashit( $this->dir ) . 'assets';
37 | $this->assets_url = esc_url( trailingslashit( plugins_url( '/assets/', $file ) ) );
38 | $this->token = 'projects';
39 | $this->post_type = 'project';
40 |
41 | global $pagenow;
42 |
43 | add_action( 'admin_menu', array( $this, 'meta_box_setup' ), 20 );
44 | add_action( 'save_post', array( $this, 'meta_box_save' ) );
45 | add_filter( 'enter_title_here', array( $this, 'enter_title_here' ) );
46 | add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_styles' ) );
47 | add_filter( 'post_updated_messages', array( $this, 'updated_messages' ) );
48 | add_action( 'admin_notices', array( $this, 'configuration_admin_notice' ) );
49 | add_action( 'do_meta_boxes', array( $this, 'featured_image_label' ) );
50 | add_filter( 'admin_post_thumbnail_html', array( $this, 'featured_image_set_link' ) );
51 | add_filter( 'admin_post_thumbnail_html', array( $this, 'featured_image_remove_link' ) );
52 | add_filter( 'media_view_strings', array( $this, 'featured_image_popup_set_link' ) );
53 | add_filter( 'manage_edit-' . $this->post_type . '_columns', array( $this, 'register_custom_column_headings' ), 10, 1 );
54 | add_action( 'manage_' . $this->post_type .'_posts_custom_column', array( $this, 'register_custom_columns' ), 10, 2 );
55 |
56 | if ( $pagenow == 'edit.php' && isset( $_GET['post_type'] ) && esc_attr( $_GET['post_type'] ) == $this->post_type ) {
57 | add_action( 'restrict_manage_posts', array( $this, 'projects_restrict_manage_posts' ) );
58 | add_filter( 'parse_query', array( $this, 'projects_post_type_request' ) );
59 | }
60 | } // End __construct()
61 |
62 | /**
63 | * Filter the request to just give posts for the given taxonomy, if applicable.
64 | *
65 | * @access public
66 | * @param array $post_types - post types to add taxonomy filtering to
67 | * @uses wp_dropdown_categories()
68 | * @since 1.1.0
69 | * @return void
70 | */
71 | function projects_restrict_manage_posts() {
72 | global $typenow;
73 |
74 | $post_types = array( 'project' );
75 |
76 | if ( in_array( $typenow, $post_types ) ) {
77 | $filters = get_object_taxonomies( $typenow );
78 |
79 | foreach ( $filters as $tax_slug ) {
80 |
81 | $tax_obj = get_taxonomy( $tax_slug );
82 |
83 | if ( isset( $_GET[$tax_slug] ) ) {
84 | $selected = esc_attr( $_GET[$tax_slug] );
85 | } else {
86 | $selected = null;
87 | }
88 |
89 | wp_dropdown_categories( array(
90 | 'show_option_all' => __( 'Show All ' . $tax_obj->label, 'projects-by-woothemes' ),
91 | 'taxonomy' => $tax_slug,
92 | 'name' => $tax_obj->name,
93 | 'orderby' => 'name',
94 | 'selected' => $selected,
95 | 'hierarchical' => $tax_obj->hierarchical,
96 | 'show_count' => true,
97 | 'hide_empty' => true,
98 | ) );
99 | }
100 | }
101 | } // projects_restrict_manage_posts()
102 |
103 | /**
104 | * Adjust the query string to use taxonomy slug instead of ID.
105 | *
106 | * @access public
107 | * @param array $filters - all taxonomies for the current post type
108 | * @uses get_object_taxonomies()
109 | * @uses get_term_by()
110 | * @since 1.1.0
111 | * @return void
112 | */
113 | function projects_post_type_request( $query ) {
114 | global $pagenow, $typenow;
115 |
116 | $filters = get_object_taxonomies( $typenow );
117 |
118 | foreach ( $filters as $tax_slug ) {
119 | $var = &$query->query_vars[$tax_slug];
120 |
121 | if ( isset( $var ) ) {
122 | $term = get_term_by( 'id', $var, $tax_slug );
123 |
124 | if ( false != $term ) {
125 | $var = $term->slug;
126 | }
127 | }
128 | }
129 |
130 | return $query;
131 | } // End projects_post_type_request()
132 |
133 | /**
134 | * Add custom columns for the "manage" screen of this post type.
135 | *
136 | * @access public
137 | * @param string $column_name
138 | * @param int $id
139 | * @since 1.0.0
140 | * @return void
141 | */
142 | public function register_custom_columns ( $column_name, $id ) {
143 | global $wpdb, $post;
144 |
145 | $meta = get_post_custom( $id );
146 |
147 | switch ( $column_name ) {
148 |
149 | case 'image':
150 | $value = '';
151 |
152 | $value = projects_get_image( $id, 120 );
153 |
154 | echo $value;
155 | break;
156 |
157 | default:
158 | break;
159 |
160 | }
161 | } // End register_custom_columns()
162 |
163 | /**
164 | * Add custom column headings for the "manage" screen of this post type.
165 | *
166 | * @access public
167 | * @param array $defaults
168 | * @since 1.0.0
169 | * @return void
170 | */
171 | public function register_custom_column_headings ( $defaults ) {
172 |
173 | $new_columns = array();
174 | $new_columns['cb'] = $defaults['cb'];
175 | $new_columns['image'] = __( 'Cover Image', 'projects-by-woothemes' );
176 |
177 | $last_item = '';
178 |
179 | if ( isset( $defaults['date'] ) ) { unset( $defaults['date'] ); }
180 |
181 | if ( count( $defaults ) > 2 ) {
182 | $last_item = array_slice( $defaults, -1 );
183 |
184 | array_pop( $defaults );
185 | }
186 | $defaults = array_merge( $new_columns, $defaults );
187 |
188 | if ( $last_item != '' ) {
189 | foreach ( $last_item as $k => $v ) {
190 | $defaults[$k] = $v;
191 | break;
192 | }
193 | }
194 |
195 | return $defaults;
196 | } // End register_custom_column_headings()
197 |
198 | /**
199 | * Update messages for the post type admin.
200 | * @since 1.0.0
201 | * @param array $messages Array of messages for all post types.
202 | * @return array Modified array.
203 | */
204 | public function updated_messages ( $messages ) {
205 | global $post, $post_ID, $projects;
206 |
207 | $messages[$this->post_type] = array(
208 | 0 => '', // Unused. Messages start at index 1.
209 | 1 => sprintf( __( '%s updated. View %s%s%s', 'projects-by-woothemes' ), $projects->singular_name, '', strtolower( $projects->singular_name ), ' ' ),
210 | 2 => __( 'Custom field updated.', 'projects-by-woothemes' ),
211 | 3 => __( 'Custom field deleted.', 'projects-by-woothemes' ),
212 | 4 => sprintf( __( '%s updated.', 'projects-by-woothemes' ), $projects->singular_name ),
213 | /* translators: %s: date and time of the revision */
214 | 5 => isset( $_GET['revision'] ) ? sprintf( __( '%s restored to revision from %s', 'projects-by-woothemes' ), $projects->singular_name, wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
215 | 6 => sprintf( __( '%s published. View %s%s%s', 'projects-by-woothemes' ), $projects->singular_name, '', strtolower( $projects->singular_name ), ' ' ),
216 | 7 => sprintf( __( '%s saved.' ), $projects->singular_name ),
217 | 8 => sprintf( __( '%s submitted. Preview %s%s%s', 'projects-by-woothemes' ), $projects->singular_name, '', strtolower( $projects->singular_name ), ' ' ),
218 | 9 => sprintf( __( '%s scheduled for: %s. Preview %s', 'projects-by-woothemes' ), $projects->singular_name,
219 | // translators: Publish box date format, see http://php.net/date
220 | '' . date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ) . ' ', '', strtolower( $projects->singular_name ), ' ' ),
221 | 10 => sprintf( __( '%s draft updated. Preview %s%s%s', 'projects-by-woothemes' ), $projects->singular_name, '', strtolower( $projects->singular_name ), ' ' ),
222 | );
223 |
224 | return $messages;
225 | } // End updated_messages()
226 |
227 | /**
228 | * Setup the meta box.
229 | *
230 | * @access public
231 | * @since 1.1.0
232 | * @return void
233 | */
234 | public function meta_box_setup () {
235 | global $projects;
236 |
237 | // Add short description meta box (replaces default excerpt)
238 | add_meta_box( 'postexcerpt', sprintf( __( '%s Short Description', 'projects-by-woothemes' ), $projects->singular_name ), array( $this, 'meta_box_short_description' ), $this->post_type, 'normal' );
239 |
240 | // Project Details Meta Box Load
241 | add_meta_box( 'project-data', sprintf( __( '%s Details', 'projects-by-woothemes' ), $projects->singular_name ), array( $this, 'meta_box_content' ), $this->post_type, 'normal', 'high' );
242 |
243 | // Project Images Meta Bog Load
244 | add_meta_box( 'project-images', sprintf( __( '%s Gallery', 'projects-by-woothemes' ), $projects->singular_name ), array( $this, 'meta_box_content_project_images' ), $this->post_type, 'side' );
245 |
246 | } // End meta_box_setup()
247 |
248 |
249 | /**
250 | * The project short description meta box.
251 | *
252 | * @access public
253 | * @since 1.1.0
254 | * @return void
255 | */
256 | public function meta_box_short_description( $post ) {
257 | $settings = array(
258 | 'textarea_name' => 'excerpt',
259 | 'quicktags' => array( 'buttons' => 'em,strong,link' ),
260 | 'tinymce' => array(
261 | 'theme_advanced_buttons1' => 'bold,italic,strikethrough,separator,bullist,numlist,separator,blockquote,separator,justifyleft,justifycenter,justifyright,separator,link,unlink,separator,undo,redo,separator',
262 | 'theme_advanced_buttons2' => '',
263 | ),
264 | 'editor_css' => ''
265 | );
266 |
267 | wp_editor( htmlspecialchars_decode( $post->post_excerpt ), 'excerpt', apply_filters( 'projects_product_short_description_editor_settings', $settings ) );
268 | } // End meta_box_short_description()
269 |
270 | /**
271 | * The contents of our meta box.
272 | *
273 | * @access public
274 | * @since 1.0.0
275 | * @return void
276 | */
277 | public function meta_box_content () {
278 | global $post_id;
279 | $fields = get_post_custom( $post_id );
280 | $field_data = $this->get_custom_fields_settings();
281 |
282 | $html = '';
283 |
284 | $html .= ' ';
285 |
286 | if ( 0 < count( $field_data ) ) {
287 | $html .= '' . "\n";
397 | }
398 |
399 | echo $html;
400 | } // End meta_box_content()
401 |
402 | /**
403 | * Display the project images meta box.
404 | *
405 | * @access public
406 | * @return void
407 | */
408 | public function meta_box_content_project_images () {
409 | global $post, $projects;
410 | ?>
411 |
412 |
413 | ID, '_project_image_gallery' ) ) {
415 | $project_image_gallery = get_post_meta( $post->ID, '_project_image_gallery', true );
416 | } else {
417 | // Backwards compat
418 | $attachment_ids = get_posts( 'post_parent=' . $post->ID . '&numberposts=-1&post_type=attachment&orderby=menu_order&order=ASC&post_mime_type=image&fields=ids' );
419 | $attachment_ids = array_diff( $attachment_ids, array( get_post_thumbnail_id() ) );
420 | $project_image_gallery = implode( ',', $attachment_ids );
421 | }
422 |
423 | $attachments = array_filter( explode( ',', $project_image_gallery ) );
424 |
425 | if ( $attachments )
426 | foreach ( $attachments as $attachment_id ) {
427 | echo '
428 | ' . wp_get_attachment_image( $attachment_id, 'thumbnail' ) . '
429 |
433 | ';
434 | }
435 | ?>
436 |
437 |
438 |
439 |
440 |
441 |
442 | singular_name ) ); ?>
443 |
444 | post_type ) || ! isset( $_POST['woo_' . $this->token . '_nonce'] ) || ! wp_verify_nonce( $_POST['woo_' . $this->token . '_nonce'], plugin_basename( $this->dir ) ) ) {
460 | return $post_id;
461 | }
462 |
463 | if ( 'page' == $_POST['post_type'] ) {
464 | if ( ! current_user_can( 'edit_page', $post_id ) ) {
465 | return $post_id;
466 | }
467 | } else {
468 | if ( ! current_user_can( 'edit_post', $post_id ) ) {
469 | return $post_id;
470 | }
471 | }
472 |
473 | $field_data = $this->get_custom_fields_settings();
474 | $fields = array_keys( $field_data );
475 |
476 | foreach ( $fields as $f ) {
477 |
478 | switch ( $field_data[$f]['type'] ) {
479 | case 'url':
480 | ${$f} = isset( $_POST[$f] ) ? esc_url( $_POST[$f] ) : '';
481 | break;
482 | case 'textarea':
483 | case 'editor':
484 | ${$f} = isset( $_POST[$f] ) ? wp_kses_post( trim( $_POST[$f] ) ) : '';
485 | break;
486 | case 'checkbox':
487 | ${$f} = isset( $_POST[$f] ) ? 'yes' : 'no';
488 | break;
489 | case 'multicheck':
490 | // ensure checkbox is array and whitelist accepted values against options
491 | ${$f} = isset( $_POST[$f] ) && is_array( $field_data[$f]['options'] ) ? (array) array_intersect( (array) $_POST[$f], array_flip( $field_data[$f]['options'] ) ) : '';
492 | break;
493 | case 'radio':
494 | case 'select':
495 | // whitelist accepted value against options
496 | $values = array();
497 | if ( is_array( $field_data[$f]['options'] ) )
498 | $values = array_keys( $field_data[$f]['options'] );
499 | ${$f} = isset( $_POST[$f] ) && in_array( $_POST[$f], $values ) ? $_POST[$f] : '';
500 | break;
501 | default :
502 | ${$f} = isset( $_POST[$f] ) ? strip_tags( trim( $_POST[$f] ) ) : '';
503 | break;
504 | }
505 |
506 | // save it
507 | update_post_meta( $post_id, '_' . $f, ${$f} );
508 |
509 | }
510 |
511 | // Save the project gallery image IDs.
512 | $attachment_ids = array_filter( explode( ',', sanitize_text_field( $_POST['project_image_gallery'] ) ) );
513 | update_post_meta( $post_id, '_project_image_gallery', implode( ',', $attachment_ids ) );
514 |
515 | do_action( 'projects_process_meta', $post_id, $field_data, $fields );
516 |
517 | } // End meta_box_save()
518 |
519 | /**
520 | * Get the settings for the custom fields.
521 | * @since 1.1.0
522 | * @return array
523 | */
524 | public function get_custom_fields_settings () {
525 | $fields = array();
526 |
527 | $fields['client'] = array(
528 | 'name' => __( 'Client', 'projects-by-woothemes' ),
529 | 'description' => __( 'Enter the client name. (Optional)', 'projects-by-woothemes' ),
530 | 'type' => 'text',
531 | 'default' => '',
532 | 'section' => 'info'
533 | );
534 |
535 | $fields['url'] = array(
536 | 'name' => __( 'URL', 'projects-by-woothemes' ),
537 | 'description' => __( 'Enter the project URL. (Optional)', 'projects-by-woothemes' ),
538 | 'type' => 'url',
539 | 'default' => '',
540 | 'section' => 'info'
541 | );
542 |
543 | return apply_filters( 'projects_custom_fields', $fields );
544 | } // End get_custom_fields_settings()
545 |
546 | /**
547 | * Customise the "Enter title here" text.
548 | *
549 | * @access public
550 | * @since 1.0.0
551 | * @param string $title
552 | * @return void
553 | */
554 | public function enter_title_here ( $title ) {
555 | global $projects;
556 | if ( get_post_type() == $this->post_type ) {
557 | $title = sprintf( __( 'Enter the %s title here', 'projects-by-woothemes' ), strtolower( $projects->singular_name ) );
558 | }
559 | return $title;
560 | } // End enter_title_here()
561 |
562 | /**
563 | * Enqueue post type admin CSS.
564 | *
565 | * @access public
566 | * @since 1.0.0
567 | * @return void
568 | */
569 | public function enqueue_admin_styles () {
570 | global $pagenow;
571 |
572 | wp_enqueue_style( 'projects-admin', $this->assets_url . '/css/admin.css', array(), '1.0.0' );
573 |
574 | if ( ( $pagenow == 'post.php' || $pagenow == 'post-new.php' ) && get_post_type() == $this->post_type ) {
575 | wp_enqueue_script( 'projects-admin', $this->assets_url . '/js/admin.js', array( 'jquery' ), '1.0.0', true );
576 |
577 |
578 | wp_localize_script( 'projects-admin', 'woo_projects_admin',
579 | array(
580 | 'gallery_title' => __( 'Add Images to Project Gallery', 'projects-by-woothemes' ),
581 | 'gallery_button' => __( 'Add to gallery', 'projects-by-woothemes' ),
582 | 'delete_image' => __( 'Delete image', 'projects-by-woothemes' ),
583 | 'default_title' => __( 'Upload', 'projects-by-woothemes' ),
584 | 'default_button' => __( 'Select this', 'projects-by-woothemes' ),
585 | )
586 | );
587 |
588 | }
589 |
590 | } // End enqueue_admin_styles()
591 |
592 | /**
593 | * Display an admin notice, if not on the settings screen and if projects page isn't set.
594 | * @access public
595 | * @since 1.0.0
596 | * @return void
597 | */
598 | public function configuration_admin_notice () {
599 | if ( ( isset( $_GET['page'] ) && 'projects-settings-page' == $_GET['page'] ) ) return;
600 |
601 | $projects_page = projects_get_page_id( 'projects' );
602 |
603 | if ( -1 == $projects_page ) {
604 | $url = add_query_arg( 'post_type', 'project', admin_url( 'edit.php' ) );
605 | $url = add_query_arg( 'page', 'projects-settings-page', $url );
606 | echo '' . sprintf( __( '%sProjects by WooThemes is almost ready.%s To get started, %sconfigure your projects page%s.', 'projects-by-woothemes' ), '', ' ', '', ' ' ) . '
' . "\n";
607 | }
608 | } // End configuration_admin_notice()
609 |
610 | /**
611 | * Replace the featured image meta box
612 | * Functionality is identical, this is purely to change the label.
613 | * @access public
614 | * @since 1.0.0
615 | * @return void
616 | */
617 | public function featured_image_label() {
618 | global $projects;
619 | remove_meta_box( 'postimagediv', 'project', 'side' );
620 | add_meta_box( 'postimagediv', sprintf( __( '%s Cover Image', 'projects-by-woothemes' ), $projects->singular_name ), 'post_thumbnail_meta_box', 'project', 'side' );
621 | } // End featured_image_label()
622 |
623 | /**
624 | * Tweak the 'Set featured image' string to say 'Set cover image'.
625 | * @access public
626 | * @since 1.0.0
627 | * @return void
628 | */
629 | public function featured_image_set_link( $content ) {
630 | $post_type = $this->get_current_post_type();
631 |
632 | if ( 'project' == $post_type ) {
633 | $content = str_replace( __( 'Set featured image' ), __( 'Set cover image', 'projects-by-woothemes' ), $content );
634 | }
635 |
636 | return $content;
637 | } // End featured_image_set_link()
638 |
639 | /**
640 | * Tweak the 'Remove featured image' string to say 'Remove cover image'.
641 | * @access public
642 | * @since 1.0.0
643 | * @return void
644 | */
645 | public function featured_image_remove_link( $content ) {
646 | $post_type = $this->get_current_post_type();
647 |
648 | if ( 'project' == $post_type ) {
649 | $content = str_replace( __( 'Remove featured image' ), __( 'Remove cover image', 'projects-by-woothemes' ), $content );
650 | }
651 |
652 | return $content;
653 | } // End featured_image_remove_link()
654 |
655 | /**
656 | * Tweak the featured image strings in the media popup
657 | * @access public
658 | * @since 1.0.0
659 | * @return void
660 | */
661 | public function featured_image_popup_set_link( $strings ) {
662 | $post_type = $this->get_current_post_type();
663 | if ( 'project' == $post_type ) {
664 | $strings['setFeaturedImageTitle'] = __( 'Set Cover Image', 'projects-by-woothemes' );
665 | $strings['setFeaturedImage'] = __( 'Set cover image', 'projects-by-woothemes' );
666 | }
667 | return $strings;
668 | } // End featured_image_popup_set_link()
669 |
670 | /**
671 | * Determine what post type the current admin page is related to
672 | * @access public
673 | * @since 1.0.0
674 | * @return string
675 | */
676 | public function get_current_post_type() {
677 | global $post, $typenow, $current_screen;
678 |
679 | if ( $post && $post->post_type )
680 | return $post->post_type;
681 |
682 | elseif ( $typenow )
683 | return $typenow;
684 |
685 | elseif ( $current_screen && $current_screen->post_type )
686 | return $current_screen->post_type;
687 |
688 | elseif ( isset( $_REQUEST['post_type'] ) )
689 | return sanitize_key( $_REQUEST['post_type'] );
690 |
691 | return null;
692 | } // End get_current_post_type()
693 |
694 | } // End Class
695 |
--------------------------------------------------------------------------------
/classes/class-projects-frontend.php:
--------------------------------------------------------------------------------
1 | template_loader = new Projects_Template_Loader();
43 | add_filter( 'template_include', array( $this->template_loader, 'template_loader' ) );
44 | require_once( 'class-projects-query.php' );
45 | $this->projects_query = new Projects_Query();
46 | } // End __construct()
47 | } // End Class
48 | ?>
--------------------------------------------------------------------------------
/classes/class-projects-integrations.php:
--------------------------------------------------------------------------------
1 | token = 'projects';
27 | $this->post_type = 'project';
28 |
29 | // Testimonials Integration
30 | add_action( 'init', array( $this, 'projects_testimonials_init' ) );
31 |
32 | // WooCommerce Integration
33 | add_action( 'init', array( $this, 'projects_woocommerce_init' ) );
34 |
35 | } // End __construct()
36 |
37 |
38 | /**
39 | * Init function for the Testimonials plugin integration.
40 | * @since 1.1.0
41 | * @return void
42 | */
43 | public function projects_testimonials_init() {
44 |
45 | if ( class_exists( 'Woothemes_Testimonials' ) ) {
46 |
47 | // Add custom fields
48 | add_filter( 'projects_custom_fields', array( $this, 'testimonials_custom_fields' ) );
49 |
50 | // Enqueue admin JavaScript
51 | add_action( 'admin_enqueue_scripts', array( $this, 'testimonials_admin_scripts' ) );
52 | add_action( 'wp_ajax_get_testimonials', array( $this, 'get_testimonials_callback' ) );
53 | add_action( 'admin_footer', array( $this, 'testimonials_javascript' ) );
54 |
55 | }
56 |
57 | } // End projects_testimonials_init()
58 |
59 | public function testimonials_admin_scripts () {
60 | wp_enqueue_script( 'jquery-ui-autocomplete', null, array( 'jquery' ), null, false);
61 | } // End projects_testimonials_admin_scripts()
62 |
63 | /**
64 | * Ajax callback to search for testimonials.
65 | * @param string $query Search Query.
66 | * @since 1.1.0
67 | * @return json Search Results.
68 | */
69 | public function get_testimonials_callback() {
70 |
71 | check_ajax_referer( 'projects_ajax_get_testimonials', 'security' );
72 |
73 | $term = urldecode( stripslashes( strip_tags( $_GET['term'] ) ) );
74 |
75 | if ( !empty( $term ) ) {
76 |
77 | header( 'Content-Type: application/json; charset=utf-8' );
78 |
79 | $query_args = array(
80 | 'post_type' => 'testimonial',
81 | 'orderby' => 'title',
82 | 's' => $term,
83 | 'suppress_filters' => false
84 | );
85 |
86 | $testimonials = get_posts( $query_args );
87 |
88 | $found_testimonials = array();
89 |
90 | if ( $testimonials ) {
91 | foreach ( $testimonials as $testimonial ) {
92 | $found_testimonials[] = array(
93 | 'id' => $testimonial->ID,
94 | 'title' => $testimonial->post_title
95 | );
96 | }
97 | }
98 |
99 | echo json_encode( $found_testimonials );
100 |
101 | }
102 |
103 | die();
104 |
105 | } // End get_testimonials_callback()
106 |
107 | /**
108 | * Output Testimonials admin javascript
109 | * @since 1.1.0
110 | * @return void
111 | */
112 | public function testimonials_javascript() {
113 |
114 | global $pagenow, $post_type;
115 |
116 | if ( ( $pagenow == 'post.php' || $pagenow == 'post-new.php' ) && isset( $post_type ) && esc_attr( $post_type ) == $this->post_type ) {
117 |
118 | $ajax_nonce = wp_create_nonce( 'projects_ajax_get_testimonials' );
119 |
120 | ?>
121 |
158 | __( 'Testimonial', 'projects-by-woothemes' ),
166 | 'description' => __( 'Search for Testimonial to link to this Project. (Optional)', 'projects-by-woothemes' ),
167 | 'type' => 'text',
168 | 'default' => '',
169 | 'section' => 'info',
170 | );
171 |
172 | $fields['testimonials_id'] = array(
173 | 'name' => __( 'Testimonial ID', 'projects-by-woothemes' ),
174 | 'description' => __( 'Holds the id of the selected testimonial.', 'projects-by-woothemes' ),
175 | 'type' => 'hidden',
176 | 'default' => 0,
177 | 'section' => 'info',
178 | );
179 |
180 | return $fields;
181 |
182 | } // End testimonials_custom_fields()
183 |
184 | /**
185 | * Init function for the WooCommerce plugin integration.
186 | * @since 1.2.0
187 | * @return void
188 | */
189 | public function projects_woocommerce_init() {
190 |
191 | if ( class_exists( 'WooCommerce' ) ) {
192 |
193 | // Add custom fields
194 | add_filter( 'projects_custom_fields', array( $this, 'woocommerce_custom_fields' ) );
195 |
196 | // Enqueue admin JavaScript
197 | add_action( 'admin_enqueue_scripts', array( $this, 'woocommerce_admin_scripts' ) );
198 | add_action( 'wp_ajax_get_products', array( $this, 'get_products_callback' ) );
199 | add_action( 'admin_footer', array( $this, 'woocommerce_javascript' ) );
200 |
201 | }
202 |
203 | } // End projects_woocommerce_init()
204 |
205 | public function woocommerce_admin_scripts () {
206 | wp_enqueue_script( 'jquery-ui-autocomplete', null, array( 'jquery' ), null, false );
207 | } // End projects_woocommerce_admin_scripts()
208 |
209 | /**
210 | * Ajax callback to search for products.
211 | * @param string $query Search Query.
212 | * @since 1.2.0
213 | * @return json Search Results.
214 | */
215 | public function get_products_callback() {
216 | check_ajax_referer( 'projects_ajax_get_products', 'security' );
217 |
218 | $term = urldecode( stripslashes( strip_tags( $_GET['term'] ) ) );
219 |
220 | if ( ! empty( $term ) ) {
221 |
222 | header( 'Content-Type: application/json; charset=utf-8' );
223 |
224 | $query_args = array(
225 | 'post_type' => 'product',
226 | 'orderby' => 'title',
227 | 's' => $term,
228 | 'suppress_filters' => false
229 | );
230 |
231 | $products = get_posts( $query_args );
232 |
233 | $found_products = array();
234 |
235 | if ( $products ) {
236 |
237 | foreach ( $products as $product ) {
238 |
239 | $_product = new WC_Product( $product->ID );
240 |
241 | if ( $_product->get_sku() ) {
242 | $identifier = $_product->get_sku();
243 | } else {
244 | $identifier = '#' . $_product->id;
245 | }
246 |
247 | $found_products[] = array(
248 | 'id' => $product->ID,
249 | 'title' => $product->post_title,
250 | 'identifier' => $identifier,
251 | );
252 | }
253 | }
254 |
255 | echo json_encode( $found_products );
256 | }
257 |
258 | die();
259 |
260 | } // End get_products_callback()
261 |
262 | /**
263 | * Output Products admin javascript
264 | * @since 1.2.0
265 | * @return void
266 | */
267 | public function woocommerce_javascript() {
268 |
269 | global $pagenow, $post_type;
270 |
271 | if ( ( $pagenow == 'post.php' || $pagenow == 'post-new.php' ) && isset( $post_type ) && esc_attr( $post_type ) == $this->post_type ) {
272 |
273 | $ajax_nonce = wp_create_nonce( 'projects_ajax_get_products' );
274 |
275 | ?>
276 |
313 | __( 'Product', 'projects-by-woothemes' ),
321 | 'description' => __( 'Search for Product to link to this Project. (Optional)', 'projects-by-woothemes' ),
322 | 'type' => 'text',
323 | 'default' => '',
324 | 'section' => 'info',
325 | );
326 |
327 | $fields['products_id'] = array(
328 | 'name' => __( 'Product ID', 'projects-by-woothemes' ),
329 | 'description' => __( 'Holds the id of the selected product.', 'projects-by-woothemes' ),
330 | 'type' => 'hidden',
331 | 'default' => 0,
332 | 'section' => 'info',
333 | );
334 |
335 | return $fields;
336 |
337 | } // End woocommerce_custom_fields()
338 |
339 | } // End Class
340 |
341 | new Projects_Integrations();
--------------------------------------------------------------------------------
/classes/class-projects-query.php:
--------------------------------------------------------------------------------
1 | init_query_vars();
63 | } // End __construct()
64 |
65 | /**
66 | * Init query vars by loading options.
67 | */
68 | public function init_query_vars() {
69 | // Query vars to add to WP
70 | $this->query_vars = array();
71 | }
72 |
73 | /**
74 | * add_query_vars function.
75 | *
76 | * @access public
77 | * @param array $vars
78 | * @return array
79 | */
80 | public function add_query_vars( $vars ) {
81 | foreach ( $this->query_vars as $key => $var ) {
82 | $vars[] = $key;
83 | }
84 |
85 | return $vars;
86 | }
87 |
88 | /**
89 | * Get query vars
90 | *
91 | * @return array
92 | */
93 | public function get_query_vars() {
94 | return $this->query_vars;
95 | }
96 |
97 | /**
98 | * Parse the request and look for query vars - endpoints may not be supported
99 | */
100 | public function parse_request() {
101 | global $wp;
102 |
103 | // Map query vars to their keys, or get them if endpoints are not supported
104 | foreach ( $this->query_vars as $key => $var ) {
105 | if ( isset( $_GET[ $var ] ) ) {
106 | $wp->query_vars[ $key ] = $_GET[ $var ];
107 | }
108 |
109 | elseif ( isset( $wp->query_vars[ $var ] ) ) {
110 | $wp->query_vars[ $key ] = $wp->query_vars[ $var ];
111 | }
112 | }
113 | }
114 |
115 | /**
116 | * Hook into pre_get_posts to do the main project query
117 | *
118 | * @param mixed $q query object
119 | */
120 | public function pre_get_posts( $q ) {
121 | // We only want to affect the main query
122 | if ( ! $q->is_main_query() ) {
123 | return;
124 | }
125 |
126 | // Fix for verbose page rules
127 | if ( $GLOBALS['wp_rewrite']->use_verbose_page_rules && isset( $q->queried_object_id ) && $q->queried_object_id === projects_get_page_id( 'projects' ) ) {
128 | $q->set( 'post_type', 'project' );
129 | $q->set( 'page', '' );
130 | $q->set( 'pagename', '' );
131 |
132 | // Fix conditional Functions
133 | $q->is_archive = true;
134 | $q->is_post_type_archive = true;
135 | $q->is_singular = false;
136 | $q->is_page = false;
137 | }
138 |
139 | // Fix for endpoints on the homepage
140 | if ( $q->is_home() && 'page' == get_option('show_on_front') && get_option('page_on_front') != $q->get('page_id') ) {
141 | $_query = wp_parse_args( $q->query );
142 | if ( ! empty( $_query ) && array_intersect( array_keys( $_query ), array_keys( $this->query_vars ) ) ) {
143 | $q->is_page = true;
144 | $q->is_home = false;
145 | $q->is_singular = true;
146 |
147 | $q->set( 'page_id', get_option('page_on_front') );
148 | }
149 | }
150 |
151 | // When orderby is set, WordPress shows posts. Get around that here.
152 | if ( $q->is_home() && 'page' == get_option('show_on_front') && get_option('page_on_front') == projects_get_page_id( 'projects' ) ) {
153 | $_query = wp_parse_args( $q->query );
154 | if ( empty( $_query ) || ! array_diff( array_keys( $_query ), array( 'preview', 'page', 'paged', 'cpage', 'orderby' ) ) ) {
155 | $q->is_page = true;
156 | $q->is_home = false;
157 | $q->set( 'page_id', get_option('page_on_front') );
158 | $q->set( 'post_type', 'project' );
159 | }
160 | }
161 |
162 | // Special check for the project archive on front
163 | if ( $q->is_page() && 'page' == get_option( 'show_on_front' ) && $q->get('page_id') == projects_get_page_id( 'projects' ) ) {
164 |
165 | // This is a front-page projects
166 | $q->set( 'post_type', 'project' );
167 | $q->set( 'page_id', '' );
168 | if ( isset( $q->query['paged'] ) ) {
169 | $q->set( 'paged', $q->query['paged'] );
170 | }
171 |
172 | // Define a variable so we know this is the front page projects later on
173 | define( 'PROJECT_IS_ON_FRONT', true );
174 |
175 | // Get the actual WP page to avoid errors and let us use is_front_page()
176 | // This is hacky but works. Awaiting http://core.trac.wordpress.org/ticket/21096
177 | global $wp_post_types;
178 |
179 | $project_page = get_post( projects_get_page_id( 'projects' ) );
180 |
181 | $wp_post_types['project']->ID = $project_page->ID;
182 | $wp_post_types['project']->post_title = $project_page->post_title;
183 | $wp_post_types['project']->post_name = $project_page->post_name;
184 | $wp_post_types['project']->post_type = $project_page->post_type;
185 | $wp_post_types['project']->ancestors = get_ancestors( $project_page->ID, $project_page->post_type );
186 |
187 | // Fix conditional Functions like is_front_page
188 | $q->is_singular = false;
189 | $q->is_post_type_archive = true;
190 | $q->is_archive = true;
191 | $q->is_page = true;
192 |
193 | // Fix WP SEO
194 | if ( class_exists( 'WPSEO_Meta' ) ) {
195 | add_filter( 'wpseo_metadesc', array( $this, 'wpseo_metadesc' ) );
196 | add_filter( 'wpseo_metakey', array( $this, 'wpseo_metakey' ) );
197 | }
198 |
199 | // Only apply to project categories, the project post archive, the projects page, project tags, and project attribute taxonomies
200 | } elseif ( ! $q->is_post_type_archive( 'project' ) && ! $q->is_tax( get_object_taxonomies( 'project' ) ) ) {
201 | return;
202 | }
203 |
204 | $this->project_query( $q );
205 |
206 | if ( is_search() ) {
207 | add_filter( 'posts_where', array( $this, 'search_post_excerpt' ) );
208 | add_filter( 'wp', array( $this, 'remove_posts_where' ) );
209 | }
210 |
211 | // We're on a projects page so queue the get_projects_in_view function
212 | add_action( 'wp', array( $this, 'get_projects_in_view' ), 2);
213 |
214 | // And remove the pre_get_posts hook
215 | $this->remove_project_query();
216 | }
217 |
218 | /**
219 | * search_post_excerpt function.
220 | *
221 | * @access public
222 | * @param string $where (default: '')
223 | * @return string (modified where clause)
224 | */
225 | public function search_post_excerpt( $where = '' ) {
226 | global $wp_the_query;
227 |
228 | // If this is not a WC Query, do not modify the query
229 | if ( empty( $wp_the_query->query_vars['projects_query'] ) || empty( $wp_the_query->query_vars['s'] ) )
230 | return $where;
231 |
232 | $where = preg_replace(
233 | "/post_title\s+LIKE\s*(\'\%[^\%]+\%\')/",
234 | "post_title LIKE $1) OR (post_excerpt LIKE $1", $where );
235 |
236 | return $where;
237 | }
238 |
239 | /**
240 | * wpseo_metadesc function.
241 | * Hooked into wpseo_ hook already, so no need for function_exist
242 | *
243 | * @access public
244 | * @return string
245 | */
246 | public function wpseo_metadesc() {
247 | return WPSEO_Meta::get_value( 'metadesc', projects_get_page_id('projects') );
248 | }
249 |
250 | /**
251 | * wpseo_metakey function.
252 | * Hooked into wpseo_ hook already, so no need for function_exist
253 | *
254 | * @access public
255 | * @return string
256 | */
257 | public function wpseo_metakey() {
258 | return WPSEO_Meta::get_value( 'metakey', projects_get_page_id('projects') );
259 | }
260 |
261 | /**
262 | * Hook into the_posts to do the main project query if needed - relevanssi compatibility
263 | *
264 | * @access public
265 | * @param array $posts
266 | * @param WP_Query|bool $query (default: false)
267 | * @return array
268 | */
269 | public function the_posts( $posts, $query = false ) {
270 | // Abort if there's no query
271 | if ( ! $query )
272 | return $posts;
273 |
274 | // Abort if we're not filtering posts
275 | if ( empty( $this->post__in ) )
276 | return $posts;
277 |
278 | // Abort if this query has already been done
279 | if ( ! empty( $query->projects_query ) )
280 | return $posts;
281 |
282 | // Abort if this isn't a search query
283 | if ( empty( $query->query_vars["s"] ) )
284 | return $posts;
285 |
286 | // Abort if we're not on a post type archive/project taxonomy
287 | if ( ! $query->is_post_type_archive( 'project' ) && ! $query->is_tax( get_object_taxonomies( 'project' ) ) )
288 | return $posts;
289 |
290 | $filtered_posts = array();
291 | $queried_post_ids = array();
292 |
293 | foreach ( $posts as $post ) {
294 | if ( in_array( $post->ID, $this->post__in ) ) {
295 | $filtered_posts[] = $post;
296 | $queried_post_ids[] = $post->ID;
297 | }
298 | }
299 |
300 | $query->posts = $filtered_posts;
301 | $query->post_count = count( $filtered_posts );
302 |
303 | // Ensure filters are set
304 | $this->unfiltered_project_ids = $queried_post_ids;
305 | $this->filtered_project_ids = $queried_post_ids;
306 |
307 | if ( sizeof( $this->layered_nav_post__in ) > 0 ) {
308 | $this->layered_nav_project_ids = array_intersect( $this->unfiltered_project_ids, $this->layered_nav_post__in );
309 | } else {
310 | $this->layered_nav_project_ids = $this->unfiltered_project_ids;
311 | }
312 |
313 | return $filtered_posts;
314 | }
315 |
316 | /**
317 | * Query the projects, applying sorting/ordering etc. This applies to the main wordpress loop
318 | *
319 | * @param mixed $q
320 | */
321 | public function project_query( $q ) {
322 |
323 | // Meta query
324 | $meta_query = $this->get_meta_query( $q->get( 'meta_query' ) );
325 |
326 | // Get a list of post id's which match the current filters set (in the layered nav and price filter)
327 | $post__in = array_unique( apply_filters( 'loop_projects_post_in', array() ) );
328 |
329 | // Query vars that affect posts shown
330 | $q->set( 'meta_query', $meta_query );
331 | $q->set( 'post__in', $post__in );
332 | $q->set( 'posts_per_page', $q->get( 'posts_per_page' ) ? $q->get( 'posts_per_page' ) : apply_filters( 'loop_projects_per_page', get_option( 'posts_per_page' ) ) );
333 |
334 | // Set a special variable
335 | $q->set( 'projects_query', 'project_query' );
336 |
337 | // Store variables
338 | $this->post__in = $post__in;
339 | $this->meta_query = $meta_query;
340 |
341 | do_action( 'projects_project_query', $q, $this );
342 | }
343 |
344 | /**
345 | * Remove the query
346 | */
347 | public function remove_project_query() {
348 | remove_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
349 | }
350 |
351 | /**
352 | * Remove the posts_where filter
353 | */
354 | public function remove_posts_where() {
355 | remove_filter( 'posts_where', array( $this, 'search_post_excerpt' ) );
356 | }
357 |
358 | /**
359 | * Get an unpaginated list all project ID's (both filtered and unfiltered).
360 | */
361 | public function get_projects_in_view() {
362 | global $wp_the_query;
363 |
364 | // Get main query
365 | $current_wp_query = $wp_the_query->query;
366 |
367 | // Get WP Query for current page (without 'paged')
368 | unset( $current_wp_query['paged'] );
369 |
370 | // Get all visible posts, regardless of filters
371 | $unfiltered_project_ids = get_posts(
372 | array_merge(
373 | $current_wp_query,
374 | array(
375 | 'post_type' => 'project',
376 | 'numberposts' => -1,
377 | 'post_status' => 'publish',
378 | 'meta_query' => $this->meta_query,
379 | 'fields' => 'ids',
380 | 'no_found_rows' => true,
381 | 'update_post_meta_cache' => false,
382 | 'update_post_term_cache' => false,
383 | 'pagename' => '',
384 | 'projects_query' => 'get_projects_in_view'
385 | )
386 | )
387 | );
388 |
389 | // Store the variable
390 | $this->unfiltered_project_ids = $unfiltered_project_ids;
391 |
392 | // Also store filtered posts ids...
393 | if ( sizeof( $this->post__in ) > 0 ) {
394 | $this->filtered_project_ids = array_intersect( $this->unfiltered_project_ids, $this->post__in );
395 | } else {
396 | $this->filtered_project_ids = $this->unfiltered_project_ids;
397 | }
398 |
399 | // And filtered post ids which just take layered nav into consideration
400 | if ( sizeof( $this->layered_nav_post__in ) > 0 ) {
401 | $this->layered_nav_project_ids = array_intersect( $this->unfiltered_project_ids, $this->layered_nav_post__in );
402 | } else {
403 | $this->layered_nav_project_ids = $this->unfiltered_project_ids;
404 | }
405 | }
406 |
407 | /**
408 | * Appends meta queries to an array.
409 | * @access public
410 | * @param array $meta_query
411 | * @return array
412 | */
413 | public function get_meta_query( $meta_query = array() ) {
414 | if ( ! is_array( $meta_query ) )
415 | $meta_query = array();
416 |
417 | return array_filter( $meta_query );
418 | }
419 |
420 | } // End Class
--------------------------------------------------------------------------------
/classes/class-projects-settings.php:
--------------------------------------------------------------------------------
1 | get_settings_sections();
51 | if ( isset ( $_GET['tab'] ) ) {
52 | $tab = $_GET['tab'];
53 | } else {
54 | list( $first_section ) = array_keys( $sections );
55 | $tab = $first_section;
56 | } // End If Statement
57 | ?>
58 |
59 |
60 |
61 |
62 | $value ) {
64 | $class = '';
65 |
66 | if ( $tab == $key ) {
67 | $class = ' nav-tab-active';
68 | } // End If Statement
69 |
70 | echo '' . $value . ' ';
71 | } // End For Loop
72 | ?>
73 |
74 |
86 |
87 |
88 | get_settings_sections();
94 | if ( 0 < count( $sections ) ) {
95 | foreach ( $sections as $k => $v ) {
96 | $callback_array = explode( '-', $k );
97 | if ( method_exists( $this, 'projects_' . $callback_array[0] . '_settings_validate' ) ) {
98 | register_setting( 'projects-settings-' . $k, 'projects-' . $k, array( $this, 'projects_' . $callback_array[0] . '_settings_validate' ) );
99 | add_settings_section( $k, $v, array( $this, 'projects_' . $callback_array[0] . '_settings' ), 'projects-' . $k );
100 | } elseif( function_exists( 'projects_' . $callback_array[0] . '_settings_validate' ) ) {
101 | register_setting( 'projects-settings-' . $k, 'projects-' . $k, 'projects_' . $callback_array[0] . '_settings_validate' );
102 | add_settings_section( $k, $v, 'projects_' . $callback_array[0] . '_settings', 'projects-' . $k );
103 | } // End If Statement
104 | } // End For Loop
105 | } // End If Statement
106 |
107 | } // End projects_options_init()
108 |
109 | public function projects_pages_settings() {
110 | ?>
111 |
112 | 'projects-pages-fields[projects_page_id]',
116 | 'selected' => absint( $options['projects_page_id'] ),
117 | 'sort_column' => 'menu_order',
118 | 'sort_order' => 'ASC',
119 | 'show_option_none' => ' ',
120 | );
121 | ?>
122 |
133 |
138 | .
139 | array(
145 | 'width' => 300,
146 | 'height' => 300,
147 | 'crop' => 'no'
148 | ),
149 | 'project-single' => array(
150 | 'width' => 1024,
151 | 'height' => 1024,
152 | 'crop' => 'no'
153 | ),
154 | 'project-thumbnail' => array(
155 | 'width' => 100,
156 | 'height' => 100,
157 | 'crop' => 'yes'
158 | )
159 | ) );
160 |
161 | // Parse incomming $options into an array and merge it with $defaults
162 | $options = wp_parse_args( $options, $defaults );
163 |
164 | ?>
165 |
194 | 'projects',
31 | 'before' => null,
32 | 'after' => null
33 | )
34 | ){
35 | ob_start();
36 |
37 | $before = empty( $wrapper['before'] ) ? '' : $wrapper['before'];
38 | $after = empty( $wrapper['after'] ) ? '
' : $wrapper['after'];
39 |
40 | echo $before;
41 | call_user_func( $function, $atts );
42 | echo $after;
43 |
44 | return ob_get_clean();
45 | }
46 |
47 | /**
48 | * Recent Products shortcode
49 | *
50 | * @access public
51 | * @param array $atts
52 | * @return string
53 | */
54 | public function projects( $atts ) {
55 |
56 | global $projects_loop;
57 |
58 | extract( shortcode_atts( array(
59 | 'limit' => '12',
60 | 'columns' => '2',
61 | 'orderby' => 'date',
62 | 'order' => 'desc',
63 | 'exclude_categories' => null,
64 | 'include_children' => true
65 | ), $atts ) );
66 |
67 | // Cater for fallback on false attribute
68 | if ( $include_children === 'false' ) {
69 | $include_children = false;
70 | } // End If Statement
71 |
72 | $args = array(
73 | 'post_type' => 'project',
74 | 'post_status' => 'publish',
75 | 'ignore_sticky_posts' => 1,
76 | 'posts_per_page' => $limit,
77 | 'orderby' => $orderby,
78 | 'order' => $order,
79 | 'tax_query' => array(
80 | array(
81 | 'taxonomy' => 'project-category',
82 | 'field' => 'id',
83 | 'terms' => explode( ',', $exclude_categories ),
84 | 'include_children' => $include_children,
85 | 'operator' => 'NOT IN'
86 | )
87 | )
88 | );
89 |
90 | ob_start();
91 |
92 | $projects = new WP_Query( apply_filters( 'projects_query', $args, $atts ) );
93 |
94 | $projects_loop['columns'] = $columns;
95 |
96 | if ( $projects->have_posts() ) : ?>
97 |
98 |
99 |
100 | have_posts() ) : $projects->the_post(); ?>
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | ' . ob_get_clean() . '';
113 |
114 | }
115 |
116 | }
117 |
118 |
119 | new Projects_Shortcodes();
--------------------------------------------------------------------------------
/classes/class-projects-taxonomy.php:
--------------------------------------------------------------------------------
1 | post_type = 'project';
67 | $this->token = esc_attr( $token );
68 | $this->singular = apply_filters( 'projects_taxonomy_' . $this->token . '_singular_name', esc_html($singular) );
69 | $this->plural = apply_filters( 'projects_taxonomy_' . $this->token . '_plural_name', esc_html($plural) );
70 |
71 | if ( '' == $this->singular ) $this->singular = __( 'Category', 'projects-by-woothemes' );
72 | if ( '' == $this->plural ) $this->plural = __( 'Categories', 'projects-by-woothemes' );
73 |
74 | $this->args = wp_parse_args( $args, $this->_get_default_args() );
75 | } // End __construct()
76 |
77 | /**
78 | * Return an array of default arguments.
79 | * @access private
80 | * @since 1.0.0
81 | * @return array Default arguments.
82 | */
83 | private function _get_default_args () {
84 | return array(
85 | 'labels' => $this->_get_default_labels(),
86 | 'public' => true,
87 | 'hierarchical' => true,
88 | 'show_ui' => true,
89 | 'show_admin_column' => true,
90 | 'query_var' => true,
91 | 'show_in_nav_menus' => true,
92 | 'show_tagcloud' => false,
93 | 'rewrite' => array( 'slug' => ( $projects_page_id = projects_get_page_id( 'projects' ) ) && get_page( $projects_page_id ) ? get_page_uri( $projects_page_id ) : 'projects', 'with_front' => false )
94 | );
95 | } // End _get_default_args()
96 |
97 | /**
98 | * Return an array of default labels.
99 | * @access private
100 | * @since 1.3.0
101 | * @return array Default labels.
102 | */
103 | private function _get_default_labels () {
104 | return array(
105 | 'name' => sprintf( _x( 'Project %s', 'taxonomy general name', 'projects-by-woothemes' ), $this->plural ),
106 | 'singular_name' => sprintf( _x( '%s', 'taxonomy singular name', 'projects-by-woothemes' ), $this->singular ),
107 | 'search_items' => sprintf( __( 'Search %s', 'projects-by-woothemes' ), $this->plural ),
108 | 'all_items' => sprintf( __( 'All %s', 'projects-by-woothemes' ), $this->plural ),
109 | 'parent_item' => sprintf( __( 'Parent %s', 'projects-by-woothemes' ), $this->singular ),
110 | 'parent_item_colon' => sprintf( __( 'Parent %s:', 'projects-by-woothemes' ), $this->singular ),
111 | 'edit_item' => sprintf( __( 'Edit %s', 'projects-by-woothemes' ), $this->singular ),
112 | 'update_item' => sprintf( __( 'Update %s', 'projects-by-woothemes' ), $this->singular ),
113 | 'add_new_item' => sprintf( __( 'Add New %s', 'projects-by-woothemes' ), $this->singular ),
114 | 'new_item_name' => sprintf( __( 'New %s Name', 'projects-by-woothemes' ), $this->singular ),
115 | 'menu_name' => sprintf( __( '%s', 'projects-by-woothemes' ), $this->plural )
116 | );
117 | } // End _get_default_labels()
118 |
119 | /**
120 | * Register the taxonomy.
121 | * @access public
122 | * @since 1.0.0
123 | * @return void
124 | */
125 | public function register () {
126 | $args = apply_filters( 'projects_register_taxonomy', $this->args );
127 | register_taxonomy( esc_attr( $this->token ), esc_attr( $this->post_type ), (array) $args );
128 | } // End register()
129 | } // End Class
130 |
--------------------------------------------------------------------------------
/classes/class-projects-template-loader.php:
--------------------------------------------------------------------------------
1 | template_url = apply_filters( 'projects_template_url', 'projects/' );
13 | } // End __construct()
14 |
15 | /**
16 | * Load a template.
17 | *
18 | * Handles template usage so that we can use our own templates instead of the themes.
19 | *
20 | * Templates are in the 'templates' folder. projects looks for theme
21 | * overrides in /theme/projects/ by default
22 | *
23 | * @access public
24 | * @param mixed $template
25 | * @return string
26 | */
27 | public function template_loader ( $template ) {
28 | global $projects, $post;
29 |
30 | $find = array( 'projects.php' );
31 | $file = '';
32 |
33 | if ( is_single() && 'project' == get_post_type() ) {
34 |
35 | $file = 'single-project.php';
36 | $find[] = $file;
37 | $find[] = $this->template_url . $file;
38 |
39 | } elseif ( is_tax( 'project-category' ) ) {
40 |
41 | $term = get_queried_object();
42 |
43 | $file = 'taxonomy-' . $term->taxonomy . '.php';
44 | $find[] = 'taxonomy-' . $term->taxonomy . '-' . $term->slug . '.php';
45 | $find[] = $this->template_url . 'taxonomy-' . $term->taxonomy . '-' . $term->slug . '.php';
46 | $find[] = $file;
47 | $find[] = $this->template_url . $file;
48 |
49 | } elseif ( is_post_type_archive( 'project' ) || is_page( projects_get_page_id( 'projects' ) ) ) {
50 |
51 | $file = 'archive-project.php';
52 | $find[] = $file;
53 | $find[] = $this->template_url . $file;
54 |
55 | }
56 |
57 | if ( $file ) {
58 | $template = locate_template( $find );
59 | if ( ! $template ) $template = $projects->plugin_path() . '/templates/' . $file;
60 | }
61 |
62 | return $template;
63 | } // End template_loader()
64 | } // End Class
--------------------------------------------------------------------------------
/classes/class-widget-project-categories.php:
--------------------------------------------------------------------------------
1 | projects_widget_cssclass = 'widget_projects_categories';
42 | $this->projects_widget_description = __( 'Project Categories', 'projects-by-woothemes' );
43 | $this->projects_widget_idbase = 'woothemes-project-categories';
44 | $this->projects_widget_title = __( 'Project Categories', 'projects-by-woothemes' );
45 |
46 | /* Widget settings. */
47 | $widget_ops = array(
48 | 'classname' => $this->projects_widget_cssclass,
49 | 'description' => $this->projects_widget_description
50 | );
51 |
52 | /* Widget control settings. */
53 | $control_ops = array(
54 | 'id_base' => $this->projects_widget_idbase
55 | );
56 |
57 | /* Create the widget. */
58 | parent::__construct( $this->projects_widget_idbase, $this->projects_widget_title, $widget_ops, $control_ops );
59 | } // End __construct()
60 |
61 | /**
62 | * Display the widget on the frontend.
63 | * @since 1.0.0
64 | * @param array $args Widget arguments.
65 | * @param array $instance Widget settings for this instance.
66 | * @return void
67 | */
68 | public function widget( $args, $instance ) {
69 | extract( $args, EXTR_SKIP );
70 |
71 | /* Our variables from the widget settings. */
72 | $title = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base );
73 |
74 | $args = array();
75 |
76 | /* Display the widget title if one was input (before and after defined by themes). */
77 | if ( $title ) { $args['title'] = $title; }
78 |
79 | /* Widget content. */
80 | // Add actions for plugins/themes to hook onto.
81 | do_action( $this->projects_widget_cssclass . '_top' );
82 |
83 | // Checkbox values.
84 | if ( isset( $instance['count'] ) ) { $args['count'] = $instance['count']; }
85 | if ( isset( $instance['hierarchical'] ) ) { $args['hierarchical'] = $instance['hierarchical']; }
86 |
87 | echo $before_widget;
88 |
89 | if ( $title ) {
90 | echo $before_title . $title . $after_title;
91 | }
92 |
93 | // Display the project categories
94 | $project_taxonomies = get_object_taxonomies( 'project' );
95 |
96 | if ( count( $project_taxonomies ) > 0) {
97 | foreach ( $project_taxonomies as $project_tax ) {
98 | $args = array(
99 | 'orderby' => 'name',
100 | 'show_count' => $instance['count'],
101 | 'pad_counts' => 0,
102 | 'hierarchical' => $instance['hierarchical'],
103 | 'taxonomy' => $project_tax,
104 | 'title_li' => '',
105 | );
106 |
107 | echo '';
112 | }
113 | }
114 |
115 | echo $after_widget;
116 |
117 | // Add actions for plugins/themes to hook onto.
118 | do_action( $this->projects_widget_cssclass . '_bottom' );
119 |
120 | } // End widget()
121 |
122 | /**
123 | * Method to update the settings from the form() method.
124 | * @since 1.0.0
125 | * @param array $new_instance New settings.
126 | * @param array $old_instance Previous settings.
127 | * @return array Updated settings.
128 | */
129 | public function update ( $new_instance, $old_instance ) {
130 | $instance = $old_instance;
131 |
132 | /* Strip tags for title and name to remove HTML (important for text inputs). */
133 | $instance['title'] = strip_tags( $new_instance['title'] );
134 |
135 | /* Escape checkbox values */
136 | $instance['count'] = esc_attr( $new_instance['count'] );
137 | $instance['hierarchical'] = esc_attr( $new_instance['hierarchical'] );
138 |
139 | return $instance;
140 | } // End update()
141 |
142 | /**
143 | * The form on the widget control in the widget administration area.
144 | * Make use of the get_field_id() and get_field_name() function when creating your form elements. This handles the confusing stuff.
145 | * @since 1.0.0
146 | * @param array $instance The settings for this instance.
147 | * @return void
148 | */
149 | public function form( $instance ) {
150 |
151 | /* Set up some default widget settings. */
152 | /* Make sure all keys are added here, even with empty string values. */
153 | $defaults = array(
154 | 'title' => __( 'Project Categories', 'projects-by-woothemes' ),
155 | 'count' => 1,
156 | 'hierarchical' => 1,
157 | );
158 |
159 | $instance = wp_parse_args( (array) $instance, $defaults );
160 | ?>
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 | />
170 |
171 |
172 |
173 |
174 |
175 | />
176 |
177 |
178 | projects_widget_cssclass = 'widget_projects_items';
41 | $this->projects_widget_description = __( 'Recent projects listed on your site.', 'projects-by-woothemes' );
42 | $this->projects_widget_idbase = 'projects';
43 | $this->projects_widget_title = __( 'Recent Projects', 'projects-by-woothemes' );
44 |
45 | // Cache
46 | add_action( 'save_post', array($this, 'flush_widget_cache') );
47 | add_action( 'deleted_post', array($this, 'flush_widget_cache') );
48 | add_action( 'switch_theme', array($this, 'flush_widget_cache') );
49 |
50 | /* Widget settings. */
51 | $widget_ops = array(
52 | 'classname' => $this->projects_widget_cssclass,
53 | 'description' => $this->projects_widget_description
54 | );
55 |
56 | /* Widget control settings. */
57 | $control_ops = array(
58 | 'id_base' => $this->projects_widget_idbase
59 | );
60 |
61 | /* Create the widget. */
62 | parent::__construct( $this->projects_widget_idbase, $this->projects_widget_title, $widget_ops, $control_ops );
63 | } // End __construct()
64 |
65 | /**
66 | * Display the widget on the frontend.
67 | * @since 1.0.0
68 | * @param array $args Widget arguments.
69 | * @param array $instance Widget settings for this instance.
70 | * @return void
71 | */
72 | public function widget( $args, $instance ) {
73 |
74 | $cache = wp_cache_get( 'widget_projects_items', 'widget' );
75 |
76 | if ( !is_array($cache) )
77 | $cache = array();
78 |
79 | if ( ! isset( $args['widget_id'] ) )
80 | $args['widget_id'] = $this->id;
81 |
82 | if ( isset( $cache[ $args['widget_id'] ] ) ) {
83 | echo $cache[ $args['widget_id'] ];
84 | return;
85 | }
86 |
87 | ob_start();
88 |
89 | extract( $args, EXTR_SKIP );
90 |
91 | /* Our variables from the widget settings. */
92 | $title = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base );
93 |
94 | $args = array();
95 |
96 | /* Display the widget title if one was input (before and after defined by themes). */
97 | if ( $title ) { $args['title'] = $title; }
98 |
99 | /* Widget content. */
100 | // Add actions for plugins/themes to hook onto.
101 | do_action( $this->projects_widget_cssclass . '_top' );
102 |
103 | // Integer values.
104 | if ( isset( $instance['limit'] ) && ( 0 < count( $instance['limit'] ) ) ) { $args['limit'] = intval( $instance['limit'] ); }
105 |
106 | // Display the projects.
107 |
108 | $args = array(
109 | 'post_type' => 'project',
110 | 'post_status' => 'publish',
111 | 'ignore_sticky_posts' => 1,
112 | 'posts_per_page' => $args['limit'],
113 | 'orderby' => 'date',
114 | 'order' => 'DESC'
115 | );
116 |
117 | $r = new WP_Query( $args );
118 |
119 | if ( $r->have_posts() ) {
120 |
121 | echo $before_widget;
122 |
123 | if ( $title )
124 | echo $before_title . $title . $after_title;
125 |
126 | echo '';
134 |
135 | echo $after_widget;
136 |
137 | wp_reset_postdata();
138 | }
139 |
140 | // Add actions for plugins/themes to hook onto.
141 | do_action( $this->projects_widget_cssclass . '_bottom' );
142 |
143 | $cache[ $widget_id ] = ob_get_flush();
144 |
145 | wp_cache_set('widget_projects_items', $cache, 'widget');
146 |
147 | } // End widget()
148 |
149 | /**
150 | * Method to update the settings from the form() method.
151 | * @since 1.0.0
152 | * @param array $new_instance New settings.
153 | * @param array $old_instance Previous settings.
154 | * @return array Updated settings.
155 | */
156 | public function update ( $new_instance, $old_instance ) {
157 | $instance = $old_instance;
158 |
159 | /* Strip tags for title and name to remove HTML (important for text inputs). */
160 | $instance['title'] = strip_tags( $new_instance['title'] );
161 |
162 | /* Make sure the integer values are definitely integers. */
163 | $instance['limit'] = intval( $new_instance['limit'] );
164 |
165 | /* Flush cache. */
166 | $this->flush_widget_cache();
167 | $alloptions = wp_cache_get( 'alloptions', 'options' );
168 | if ( isset($alloptions['widget_projects_items']) )
169 | delete_option('widget_projects_items');
170 |
171 | return $instance;
172 | } // End update()
173 |
174 | /**
175 | * The form on the widget control in the widget administration area.
176 | * Make use of the get_field_id() and get_field_name() function when creating your form elements. This handles the confusing stuff.
177 | * @since 1.0.0
178 | * @param array $instance The settings for this instance.
179 | * @return void
180 | */
181 | public function form( $instance ) {
182 |
183 | /* Set up some default widget settings. */
184 | /* Make sure all keys are added here, even with empty string values. */
185 | $defaults = array(
186 | 'title' => __( 'Recent Projects', 'projects-by-woothemes' ),
187 | 'limit' => 5,
188 | );
189 |
190 | $instance = wp_parse_args( (array) $instance, $defaults );
191 | ?>
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 | \n"
13 | "Language-Team: LANGUAGE \n"
14 |
15 | #: classes/class-projects-admin.php:175
16 | msgid "Cover Image"
17 | msgstr ""
18 |
19 | #: classes/class-projects-admin.php:209
20 | msgid "%s updated. View %s%s%s"
21 | msgstr ""
22 |
23 | #: classes/class-projects-admin.php:210
24 | msgid "Custom field updated."
25 | msgstr ""
26 |
27 | #: classes/class-projects-admin.php:211
28 | msgid "Custom field deleted."
29 | msgstr ""
30 |
31 | #: classes/class-projects-admin.php:212
32 | msgid "%s updated."
33 | msgstr ""
34 |
35 | #. translators: %s: date and time of the revision
36 |
37 | #: classes/class-projects-admin.php:214
38 | msgid "%s restored to revision from %s"
39 | msgstr ""
40 |
41 | #: classes/class-projects-admin.php:215
42 | msgid "%s published. View %s%s%s"
43 | msgstr ""
44 |
45 | #: classes/class-projects-admin.php:216
46 | msgid "%s saved."
47 | msgstr ""
48 |
49 | #: classes/class-projects-admin.php:217
50 | msgid "%s submitted. Preview %s%s%s"
51 | msgstr ""
52 |
53 | #: classes/class-projects-admin.php:218
54 | msgid "%s scheduled for: %s. Preview %s"
55 | msgstr ""
56 |
57 | #. translators: Publish box date format, see http:php.net/date
58 |
59 | #: classes/class-projects-admin.php:220
60 | msgid "M j, Y @ G:i"
61 | msgstr ""
62 |
63 | #: classes/class-projects-admin.php:221
64 | msgid "%s draft updated. Preview %s%s%s"
65 | msgstr ""
66 |
67 | #: classes/class-projects-admin.php:238
68 | msgid "%s Short Description"
69 | msgstr ""
70 |
71 | #: classes/class-projects-admin.php:241
72 | msgid "%s Details"
73 | msgstr ""
74 |
75 | #: classes/class-projects-admin.php:244
76 | msgid "%s Gallery"
77 | msgstr ""
78 |
79 | #: classes/class-projects-admin.php:429 classes/class-projects-admin.php:581
80 | msgid "Delete image"
81 | msgstr ""
82 |
83 | #: classes/class-projects-admin.php:430
84 | msgid "Edit image"
85 | msgstr ""
86 |
87 | #: classes/class-projects-admin.php:441
88 | msgid "Add %s gallery images"
89 | msgstr ""
90 |
91 | #: classes/class-projects-admin.php:527 templates/single-project/meta.php:43
92 | msgid "Client"
93 | msgstr ""
94 |
95 | #: classes/class-projects-admin.php:528
96 | msgid "Enter the client name. (Optional)"
97 | msgstr ""
98 |
99 | #: classes/class-projects-admin.php:535
100 | msgid "URL"
101 | msgstr ""
102 |
103 | #: classes/class-projects-admin.php:536
104 | msgid "Enter the project URL. (Optional)"
105 | msgstr ""
106 |
107 | #: classes/class-projects-admin.php:556
108 | msgid "Enter the %s title here"
109 | msgstr ""
110 |
111 | #: classes/class-projects-admin.php:579
112 | msgid "Add Images to Project Gallery"
113 | msgstr ""
114 |
115 | #: classes/class-projects-admin.php:580
116 | msgid "Add to gallery"
117 | msgstr ""
118 |
119 | #: classes/class-projects-admin.php:582
120 | msgid "Upload"
121 | msgstr ""
122 |
123 | #: classes/class-projects-admin.php:583
124 | msgid "Select this"
125 | msgstr ""
126 |
127 | #: classes/class-projects-admin.php:603
128 | msgid "%sProjects by WooThemes is almost ready.%s To get started, %sconfigure your projects page%s."
129 | msgstr ""
130 |
131 | #: classes/class-projects-admin.php:617
132 | msgid "%s Cover Image"
133 | msgstr ""
134 |
135 | #: classes/class-projects-admin.php:630
136 | msgid "Set featured image"
137 | msgstr ""
138 |
139 | #: classes/class-projects-admin.php:630 classes/class-projects-admin.php:662
140 | msgid "Set cover image"
141 | msgstr ""
142 |
143 | #: classes/class-projects-admin.php:646
144 | msgid "Remove featured image"
145 | msgstr ""
146 |
147 | #: classes/class-projects-admin.php:646
148 | msgid "Remove cover image"
149 | msgstr ""
150 |
151 | #: classes/class-projects-admin.php:661
152 | msgid "Set Cover Image"
153 | msgstr ""
154 |
155 | #: classes/class-projects-integrations.php:165
156 | msgid "Testimonial"
157 | msgstr ""
158 |
159 | #: classes/class-projects-integrations.php:166
160 | msgid "Search for Testimonial to link to this Project. (Optional)"
161 | msgstr ""
162 |
163 | #: classes/class-projects-integrations.php:173
164 | msgid "Testimonial ID"
165 | msgstr ""
166 |
167 | #: classes/class-projects-integrations.php:174
168 | msgid "Holds the id of the selected testimonial."
169 | msgstr ""
170 |
171 | #: classes/class-projects-integrations.php:320
172 | msgid "Product"
173 | msgstr ""
174 |
175 | #: classes/class-projects-integrations.php:321
176 | msgid "Search for Product to link to this Project. (Optional)"
177 | msgstr ""
178 |
179 | #: classes/class-projects-integrations.php:328
180 | msgid "Product ID"
181 | msgstr ""
182 |
183 | #: classes/class-projects-integrations.php:329
184 | msgid "Holds the id of the selected product."
185 | msgstr ""
186 |
187 | #: classes/class-projects-settings.php:31
188 | msgid "Settings"
189 | msgstr ""
190 |
191 | #: classes/class-projects-settings.php:43
192 | msgid "Pages"
193 | msgstr ""
194 |
195 | #: classes/class-projects-settings.php:44
196 | msgid "Images"
197 | msgstr ""
198 |
199 | #: classes/class-projects-settings.php:60
200 | msgid "Projects Settings"
201 | msgstr ""
202 |
203 | #: classes/class-projects-settings.php:82
204 | msgid "Save Changes"
205 | msgstr ""
206 |
207 | #: classes/class-projects-settings.php:111
208 | msgid "Configure projects pages."
209 | msgstr ""
210 |
211 | #: classes/class-projects-settings.php:124
212 | msgid "Projects Page"
213 | msgstr ""
214 |
215 | #: classes/class-projects-settings.php:128
216 | msgid "The base page of your projects. This is your projects archive."
217 | msgstr ""
218 |
219 | #: classes/class-projects-settings.php:138
220 | msgid "These settings control the dimensions of thumbnails in your projects. After updating these settings you may need to"
221 | msgstr ""
222 |
223 | #: classes/class-projects-settings.php:138
224 | msgid "regenerate your thumbnails"
225 | msgstr ""
226 |
227 | #: classes/class-projects-settings.php:168
228 | msgid "Archive Images"
229 | msgstr ""
230 |
231 | #: classes/class-projects-settings.php:172
232 | #: classes/class-projects-settings.php:181
233 | #: classes/class-projects-settings.php:190
234 | msgid "Width:"
235 | msgstr ""
236 |
237 | #: classes/class-projects-settings.php:172
238 | #: classes/class-projects-settings.php:181
239 | #: classes/class-projects-settings.php:190
240 | msgid "Height:"
241 | msgstr ""
242 |
243 | #: classes/class-projects-settings.php:172
244 | #: classes/class-projects-settings.php:181
245 | #: classes/class-projects-settings.php:190
246 | msgid "Crop:"
247 | msgstr ""
248 |
249 | #: classes/class-projects-settings.php:177
250 | msgid "Single Images"
251 | msgstr ""
252 |
253 | #: classes/class-projects-settings.php:186
254 | msgid "Thumbnails"
255 | msgstr ""
256 |
257 | #: classes/class-projects-taxonomy.php:71
258 | msgid "Category"
259 | msgstr ""
260 |
261 | #: classes/class-projects-taxonomy.php:72 templates/single-project/meta.php:31
262 | msgid "Categories"
263 | msgstr ""
264 |
265 | #: classes/class-projects-taxonomy.php:105
266 | msgctxt "taxonomy general name"
267 | msgid "Project %s"
268 | msgstr ""
269 |
270 | #: classes/class-projects-taxonomy.php:106
271 | msgctxt "taxonomy singular name"
272 | msgid "%s"
273 | msgstr ""
274 |
275 | #: classes/class-projects-taxonomy.php:107
276 | msgid "Search %s"
277 | msgstr ""
278 |
279 | #: classes/class-projects-taxonomy.php:108
280 | msgid "All %s"
281 | msgstr ""
282 |
283 | #: classes/class-projects-taxonomy.php:109
284 | msgid "Parent %s"
285 | msgstr ""
286 |
287 | #: classes/class-projects-taxonomy.php:110
288 | msgid "Parent %s:"
289 | msgstr ""
290 |
291 | #: classes/class-projects-taxonomy.php:111 projects.php:149
292 | msgid "Edit %s"
293 | msgstr ""
294 |
295 | #: classes/class-projects-taxonomy.php:112
296 | msgid "Update %s"
297 | msgstr ""
298 |
299 | #: classes/class-projects-taxonomy.php:113 projects.php:148
300 | msgid "Add New %s"
301 | msgstr ""
302 |
303 | #: classes/class-projects-taxonomy.php:114
304 | msgid "New %s Name"
305 | msgstr ""
306 |
307 | #: classes/class-projects-taxonomy.php:115
308 | msgid "%s"
309 | msgstr ""
310 |
311 | #: classes/class-widget-project-categories.php:42
312 | #: classes/class-widget-project-categories.php:44
313 | #: classes/class-widget-project-categories.php:154
314 | msgid "Project Categories"
315 | msgstr ""
316 |
317 | #: classes/class-widget-project-categories.php:163
318 | #: classes/class-widget-projects.php:194
319 | msgid "Title (optional):"
320 | msgstr ""
321 |
322 | #: classes/class-widget-project-categories.php:170
323 | msgid "Show Count:"
324 | msgstr ""
325 |
326 | #: classes/class-widget-project-categories.php:176
327 | msgid "Show Hierarchy:"
328 | msgstr ""
329 |
330 | #: classes/class-widget-projects.php:41
331 | msgid "Recent projects listed on your site."
332 | msgstr ""
333 |
334 | #: classes/class-widget-projects.php:43 classes/class-widget-projects.php:186
335 | msgid "Recent Projects"
336 | msgstr ""
337 |
338 | #: classes/class-widget-projects.php:199
339 | msgid "Limit:"
340 | msgstr ""
341 |
342 | #: projects-core-functions.php:254
343 | msgctxt "slug"
344 | msgid "uncategorized"
345 | msgstr ""
346 |
347 | #: projects-template.php:140
348 | msgid "Search Results: “%s”"
349 | msgstr ""
350 |
351 | #: projects-template.php:143
352 | msgid " – Page %s"
353 | msgstr ""
354 |
355 | #: projects-template.php:565
356 | msgid "Purchase"
357 | msgstr ""
358 |
359 | #: projects.php:132
360 | msgctxt "post type singular name"
361 | msgid "Project"
362 | msgstr ""
363 |
364 | #: projects.php:133
365 | msgctxt "post type general name"
366 | msgid "Projects"
367 | msgstr ""
368 |
369 | #: projects.php:150
370 | msgid "New %s"
371 | msgstr ""
372 |
373 | #: projects.php:152
374 | msgid "View %s"
375 | msgstr ""
376 |
377 | #: projects.php:153
378 | msgid "Search %a"
379 | msgstr ""
380 |
381 | #: projects.php:154
382 | msgid "No %s Found"
383 | msgstr ""
384 |
385 | #: projects.php:155
386 | msgid "No %s Found In Trash"
387 | msgstr ""
388 |
389 | #: templates/loop/no-projects-found.php:14
390 | msgid "No projects found which match your selection."
391 | msgstr ""
392 |
393 | #: templates/single-project/meta.php:53
394 | msgid "Link"
395 | msgstr ""
396 |
397 | #: templates/single-project/meta.php:54
398 | msgid "Visit project"
399 | msgstr ""
400 | #. Plugin Name of the plugin/theme
401 | msgid "Projects"
402 | msgstr ""
403 |
404 | #. Plugin URI of the plugin/theme
405 | msgid "http://woothemes.com/"
406 | msgstr ""
407 |
408 | #. Description of the plugin/theme
409 | msgid "Hi, I'm your project showcase plugin for WordPress. Show off your recent work using our shortcode, widget or template tag."
410 | msgstr ""
411 |
412 | #. Author of the plugin/theme
413 | msgid "WooThemes"
414 | msgstr ""
415 |
416 | #. Author URI of the plugin/theme
417 | msgid "http://woothemes.com/"
418 | msgstr ""
419 |
--------------------------------------------------------------------------------
/projects-core-functions.php:
--------------------------------------------------------------------------------
1 | tag.
42 | */
43 | function projects_get_image ( $id, $size = 'projects-thumbnail' ) {
44 | $response = '';
45 |
46 | if ( has_post_thumbnail( $id ) ) {
47 | // If not a string or an array, and not an integer, default to 150x9999.
48 | if ( is_int( $size ) || ( 0 < intval( $size ) ) ) {
49 | $size = array( intval( $size ), intval( $size ) );
50 | } elseif ( ! is_string( $size ) && ! is_array( $size ) ) {
51 | $size = array( 150, 9999 );
52 | }
53 | $response = get_the_post_thumbnail( intval( $id ), $size );
54 | }
55 |
56 | return $response;
57 | } // End projects_get_image()
58 |
59 | }
60 |
61 | /**
62 | * is_projects - Returns true if on a page which uses WooThemes Projects templates
63 | *
64 | * @access public
65 | * @return bool
66 | */
67 | function is_projects () {
68 | return ( is_projects_archive() || is_project_category() || is_project() ) ? true : false;
69 | } // End is_projects()
70 |
71 | if ( ! function_exists( 'is_projects_archive' ) ) {
72 |
73 | /**
74 | * is_projects_archive - Returns true when viewing the project type archive.
75 | *
76 | * @access public
77 | * @return bool
78 | */
79 | function is_projects_archive() {
80 | return ( is_post_type_archive( 'project' ) || is_project_taxonomy() || is_page( projects_get_page_id( 'projects' ) ) ) ? true : false;
81 | } // End is_projects_archive()
82 | }
83 |
84 | if ( ! function_exists( 'is_project_taxonomy' ) ) {
85 |
86 | /**
87 | * is_project_taxonomy - Returns true when viewing a project taxonomy archive.
88 | *
89 | * @access public
90 | * @return bool
91 | */
92 | function is_project_taxonomy() {
93 | return is_tax( get_object_taxonomies( 'project' ) );
94 | } // End is_project_taxonomy()
95 | }
96 |
97 | if ( ! function_exists( 'is_project_category' ) ) {
98 |
99 | /**
100 | * is_project_category - Returns true when viewing a project category.
101 | *
102 | * @access public
103 | * @param string $term (default: '') The term slug your checking for. Leave blank to return true on any.
104 | * @return bool
105 | */
106 | function is_project_category( $term = '' ) {
107 | return is_tax( 'project-category', $term );
108 | } // End is_project_category()
109 | }
110 |
111 | if ( ! function_exists( 'is_project' ) ) {
112 |
113 | /**
114 | * is_project - Returns true when viewing a single project.
115 | *
116 | * @access public
117 | * @return bool
118 | */
119 | function is_project() {
120 | return is_singular( array( 'project' ) );
121 | } // End is_project()
122 | }
123 |
124 | if ( ! function_exists( 'is_ajax' ) ) {
125 |
126 | /**
127 | * is_ajax - Returns true when the page is loaded via ajax.
128 | *
129 | * @access public
130 | * @return bool
131 | */
132 | function is_ajax() {
133 | if ( defined('DOING_AJAX') )
134 | return true;
135 |
136 | return ( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && strtolower( $_SERVER['HTTP_X_REQUESTED_WITH'] ) == 'xmlhttprequest' ) ? true : false;
137 | }
138 | }
139 |
140 | /**
141 | * Get template part (for templates like the projects-loop).
142 | *
143 | * @access public
144 | * @param mixed $slug
145 | * @param string $name (default: '')
146 | * @return void
147 | */
148 | function projects_get_template_part( $slug, $name = '' ) {
149 | global $projects;
150 | $template = '';
151 |
152 | // Look in yourtheme/slug-name.php and yourtheme/projects/slug-name.php
153 | if ( $name )
154 | $template = locate_template( array ( "{$slug}-{$name}.php", "{$projects->template_url}{$slug}-{$name}.php" ) );
155 |
156 | // Get default slug-name.php
157 | if ( !$template && $name && file_exists( $projects->plugin_path() . "/templates/{$slug}-{$name}.php" ) )
158 | $template = $projects->plugin_path() . "/templates/{$slug}-{$name}.php";
159 |
160 | // If template file doesn't exist, look in yourtheme/slug.php and yourtheme/projects/slug.php
161 | if ( !$template )
162 | $template = locate_template( array ( "{$slug}.php", "{$projects->template_url}{$slug}.php" ) );
163 |
164 | if ( $template )
165 | load_template( $template, false );
166 | } // End projects_get_template_part()
167 |
168 |
169 | /**
170 | * Get other templates and including the file.
171 | *
172 | * @access public
173 | * @param mixed $template_name
174 | * @param array $args (default: array())
175 | * @param string $template_path (default: '')
176 | * @param string $default_path (default: '')
177 | * @return void
178 | */
179 | function projects_get_template ( $template_name, $args = array(), $template_path = '', $default_path = '' ) {
180 | global $projects;
181 |
182 | if ( $args && is_array($args) )
183 | extract( $args );
184 |
185 | $located = projects_locate_template( $template_name, $template_path, $default_path );
186 |
187 | do_action( 'projects_before_template_part', $template_name, $template_path, $located, $args );
188 |
189 | include( $located );
190 |
191 | do_action( 'projects_after_template_part', $template_name, $template_path, $located, $args );
192 | } // End projects_get_template()
193 |
194 |
195 | /**
196 | * Locate a template and return the path for inclusion.
197 | *
198 | * This is the load order:
199 | *
200 | * yourtheme / $template_path / $template_name
201 | * yourtheme / $template_name
202 | * $default_path / $template_name
203 | *
204 | * @access public
205 | * @param mixed $template_name
206 | * @param string $template_path (default: '')
207 | * @param string $default_path (default: '')
208 | * @return string
209 | */
210 | function projects_locate_template( $template_name, $template_path = '', $default_path = '' ) {
211 | global $projects;
212 |
213 | if ( ! $template_path ) $template_path = $projects->template_url;
214 | if ( ! $default_path ) $default_path = $projects->plugin_path() . '/templates/';
215 |
216 | // Look within passed path within the theme - this is priority
217 | $template = locate_template(
218 | array(
219 | trailingslashit( $template_path ) . $template_name,
220 | $template_name
221 | )
222 | );
223 |
224 | // Get default template
225 | if ( ! $template )
226 | $template = $default_path . $template_name;
227 |
228 | // Return what we found
229 | return apply_filters( 'projects_locate_template', $template, $template_name, $template_path );
230 | } // End projects_locate_template()
231 |
232 | /**
233 | * Filter to allow project-category in the permalinks for projects.
234 | *
235 | * @access public
236 | * @param string $permalink The existing permalink URL.
237 | * @param object $post
238 | * @return string
239 | */
240 | function projects_project_post_type_link( $permalink, $post ) {
241 | // Abort if post is not a project
242 | if ( $post->post_type !== 'project' )
243 | return $permalink;
244 |
245 | // Abort early if the placeholder rewrite tag isn't in the generated URL
246 | if ( false === strpos( $permalink, '%' ) )
247 | return $permalink;
248 |
249 | // Get the custom taxonomy terms in use by this post
250 | $terms = get_the_terms( $post->ID, 'project-category' );
251 |
252 | if ( empty( $terms ) ) {
253 | // If no terms are assigned to this post, use a string instead (can't leave the placeholder there)
254 | $project_cat = _x( 'uncategorized', 'slug', 'projects-by-woothemes' );
255 | } else {
256 | // Replace the placeholder rewrite tag with the first term's slug
257 | $first_term = array_shift( $terms );
258 | $project_cat = $first_term->slug;
259 | }
260 |
261 | $find = array(
262 | '%year%',
263 | '%monthnum%',
264 | '%day%',
265 | '%hour%',
266 | '%minute%',
267 | '%second%',
268 | '%post_id%',
269 | '%category%',
270 | '%project_category%'
271 | );
272 |
273 | $replace = array(
274 | date_i18n( 'Y', strtotime( $post->post_date ) ),
275 | date_i18n( 'm', strtotime( $post->post_date ) ),
276 | date_i18n( 'd', strtotime( $post->post_date ) ),
277 | date_i18n( 'H', strtotime( $post->post_date ) ),
278 | date_i18n( 'i', strtotime( $post->post_date ) ),
279 | date_i18n( 's', strtotime( $post->post_date ) ),
280 | $post->ID,
281 | $project_cat,
282 | $project_cat
283 | );
284 |
285 | $replace = array_map( 'sanitize_title', $replace );
286 |
287 | $permalink = str_replace( $find, $replace, $permalink );
288 |
289 | return $permalink;
290 | } // End projects_project_post_type_link()
291 |
292 | add_filter( 'post_type_link', 'projects_project_post_type_link', 10, 2 );
293 |
294 | /**
295 | * projects_get_gallery_attachment_ids function.
296 | *
297 | * @access public
298 | * @return array
299 | */
300 | function projects_get_gallery_attachment_ids ( $post_id = 0 ) {
301 | global $post;
302 | if ( 0 == $post_id ) $post_id = get_the_ID();
303 | $project_image_gallery = get_post_meta( $post_id, '_project_image_gallery', true );
304 | if ( '' == $project_image_gallery ) {
305 | // Backwards compat
306 | $attachment_ids = get_posts( 'post_parent=' . intval( $post_id ) . '&numberposts=-1&post_type=attachment&orderby=menu_order&order=ASC&post_mime_type=image&fields=ids' );
307 | $attachment_ids = array_diff( $attachment_ids, array( get_post_thumbnail_id() ) );
308 | $project_image_gallery = implode( ',', $attachment_ids );
309 | }
310 | return array_filter( (array) explode( ',', $project_image_gallery ) );
311 | } // End projects_get_gallery_attachment_ids()
312 |
313 |
314 | /**
315 | * Add body classes for Projects pages
316 | *
317 | * @param array $classes
318 | * @return array
319 | */
320 | function woo_projects_body_class( $classes ) {
321 | $classes = (array) $classes;
322 |
323 | if ( is_projects() ) {
324 | $classes[] = 'projects';
325 | $classes[] = 'projects-page';
326 | }
327 |
328 | if ( is_project() ) {
329 |
330 | $attachments = count( projects_get_gallery_attachment_ids() );
331 |
332 | if ( $attachments > 0 ) {
333 | $classes[] = 'has-gallery';
334 | } else {
335 | $classes[] = 'no-gallery';
336 | }
337 |
338 | if ( !has_post_thumbnail() ) {
339 | $classes[] = 'no-cover-image';
340 | }
341 |
342 | }
343 |
344 | return array_unique( $classes );
345 | }
346 |
347 |
348 | /**
349 | * Find a category image.
350 | * @since 1.0.0
351 | * @return string
352 | */
353 | function projects_category_image ( $cat_id = 0 ) {
354 |
355 | global $post;
356 |
357 | if ( 0 == $cat_id ) return;
358 |
359 | $image = '';
360 |
361 | if ( false === ( $image = get_transient( 'projects_category_image_' . $cat_id ) ) ) {
362 |
363 | $cat = get_term( $cat_id, 'project-category' );
364 |
365 | $query_args = array(
366 | 'post_type' => 'project',
367 | 'posts_per_page' => -1,
368 | 'no_found_rows' => 1,
369 | 'tax_query' => array(
370 | array(
371 | 'taxonomy' => 'project-category',
372 | 'field' => 'id',
373 | 'terms' => array( $cat->term_id )
374 | )
375 | )
376 | );
377 |
378 | $query = new WP_Query( $query_args );
379 |
380 | while ( $query->have_posts() && $image == '' ) : $query->the_post();
381 |
382 | $image = projects_get_image( get_the_ID() );
383 |
384 | if ( $image ) {
385 | $image = '' . $image . ' ';
386 | set_transient( 'projects_category_image_' . $cat->term_id, $image, 60 * 60 ); // 1 Hour.
387 | }
388 |
389 | endwhile;
390 |
391 | wp_reset_postdata();
392 |
393 | } // get transient
394 |
395 | return $image;
396 |
397 | } // End projects_category_image()
398 |
399 | /**
400 | * When a post is saved, flush the transient used to store the category images.
401 | * @since 1.0.0
402 | * @return void
403 | */
404 | function projects_category_image_flush_transient ( $post_id ) {
405 | if ( get_post_type( $post_id ) != 'project' ) return; // we only want projects
406 | $categories = get_the_terms( $post_id, 'project-category' );
407 | if ( $categories ) {
408 | foreach ($categories as $category ) {
409 | delete_transient( 'projects_category_image_' . $category->term_id );
410 | }
411 | }
412 | } // End projects_category_image_flush_transient()
413 | add_action( 'save_post', 'projects_category_image_flush_transient' );
414 |
415 | /**
416 | * Enqueue styles
417 | */
418 | function projects_script() {
419 |
420 | // Register projects CSS
421 | wp_register_style( 'projects-styles', plugins_url( '/assets/css/woo-projects.css', __FILE__ ), array(), PROJECTS_VERSION );
422 | wp_register_style( 'projects-handheld', plugins_url( '/assets/css/woo-projects-handheld.css', __FILE__ ), array(), PROJECTS_VERSION );
423 |
424 | if ( apply_filters( 'projects_enqueue_styles', true ) ) {
425 |
426 | // Load Main styles
427 | wp_enqueue_style( 'projects-styles' );
428 |
429 | // Load styles applied to handheld devices
430 | wp_enqueue_style( 'projects-handheld' );
431 |
432 | // Load Dashicons
433 | if ( is_project() ) {
434 | wp_enqueue_style( 'dashicons' );
435 | }
436 | }
437 |
438 | }
--------------------------------------------------------------------------------
/projects-hooks.php:
--------------------------------------------------------------------------------
1 | $menu_item ) {
51 |
52 | $classes = (array) $menu_item->classes;
53 |
54 | // Unset active class for blog page
55 | if ( $page_for_posts == $menu_item->object_id ) {
56 | $menu_items[$key]->current = false;
57 |
58 | if ( in_array( 'current_page_parent', $classes ) )
59 | unset( $classes[ array_search('current_page_parent', $classes) ] );
60 |
61 | if ( in_array( 'current-menu-item', $classes ) )
62 | unset( $classes[ array_search('current-menu-item', $classes) ] );
63 |
64 | // Set active state if this is the shop page link
65 | } elseif ( is_projects() && $projects_page == $menu_item->object_id ) {
66 | $menu_items[$key]->current = true;
67 | $classes[] = 'current-menu-item';
68 | $classes[] = 'current_page_item';
69 |
70 | // Set parent state if this is a product page
71 | } elseif ( is_singular( 'project' ) && $projects_page == $menu_item->object_id ) {
72 | $classes[] = 'current_page_parent';
73 | }
74 |
75 | $menu_items[$key]->classes = array_unique( $classes );
76 |
77 | }
78 |
79 | return $menu_items;
80 | }
81 |
82 | if ( ! function_exists( 'projects_output_content_wrapper' ) ) {
83 |
84 | /**
85 | * Output the start of the page wrapper.
86 | *
87 | * Hooked into projects_before_main_content
88 | *
89 | * @access public
90 | * @return void
91 | */
92 | function projects_output_content_wrapper() {
93 | projects_get_template( 'layout/wrapper-start.php' );
94 | }
95 | }
96 |
97 | if ( ! function_exists( 'projects_output_content_wrapper_end' ) ) {
98 |
99 | /**
100 | * Output the end of the page wrapper.
101 | *
102 | * Hooked into projects_after_main_content
103 | *
104 | * @access public
105 | * @return void
106 | */
107 | function projects_output_content_wrapper_end() {
108 | projects_get_template( 'layout/wrapper-end.php' );
109 | }
110 | }
111 |
112 | if ( ! function_exists( 'projects_get_sidebar' ) ) {
113 |
114 | /**
115 | * Get the projects sidebar template.
116 | *
117 | * Hooked into projects_sidebar
118 | *
119 | * @access public
120 | * @return void
121 | */
122 | function projects_get_sidebar() {
123 | projects_get_template( 'layout/sidebar.php' );
124 | }
125 | }
126 |
127 | /** Loop ******************************************************************/
128 |
129 | if ( ! function_exists( 'projects_page_title' ) ) {
130 |
131 | /**
132 | * projects_page_title function.
133 | *
134 | * @access public
135 | * @return void
136 | */
137 | function projects_page_title() {
138 |
139 | if ( is_search() ) {
140 | $page_title = sprintf( __( 'Search Results: “%s”', 'projects-by-woothemes' ), get_search_query() );
141 |
142 | if ( get_query_var( 'paged' ) )
143 | $page_title .= sprintf( __( ' – Page %s', 'projects-by-woothemes' ), get_query_var( 'paged' ) );
144 |
145 | } elseif ( is_tax() ) {
146 |
147 | $page_title = single_term_title( '', false );
148 |
149 | } else {
150 |
151 | $projects_page_id = projects_get_page_id( 'projects' );
152 | $page_title = get_the_title( $projects_page_id );
153 |
154 | }
155 |
156 | echo apply_filters( 'projects_page_title', $page_title );
157 | }
158 | }
159 |
160 | if ( ! function_exists( 'projects_project_loop_start' ) ) {
161 |
162 | /**
163 | * Output the start of a project loop. By default this is a UL
164 | *
165 | * @access public
166 | * @return void
167 | */
168 | function projects_project_loop_start( $echo = true ) {
169 | ob_start();
170 | projects_get_template( 'loop/loop-start.php' );
171 | if ( $echo )
172 | echo ob_get_clean();
173 | else
174 | return ob_get_clean();
175 | }
176 | }
177 | if ( ! function_exists( 'projects_project_loop_end' ) ) {
178 |
179 | /**
180 | * Output the end of a project loop. By default this is a UL
181 | *
182 | * @access public
183 | * @return void
184 | */
185 | function projects_project_loop_end( $echo = true ) {
186 | ob_start();
187 |
188 | projects_get_template( 'loop/loop-end.php' );
189 |
190 | if ( $echo )
191 | echo ob_get_clean();
192 | else
193 | return ob_get_clean();
194 | }
195 | }
196 | if ( ! function_exists( 'projects_taxonomy_archive_description' ) ) {
197 |
198 | /**
199 | * Show an archive description on taxonomy archives
200 | *
201 | * Hooked into projects_archive_description
202 | *
203 | * @access public
204 | * @subpackage Archives
205 | * @return void
206 | */
207 | function projects_taxonomy_archive_description() {
208 | if ( is_tax( array( 'project-category', 'project-tag' ) ) && get_query_var( 'paged' ) == 0 ) {
209 | $description = apply_filters( 'the_content', term_description() );
210 | if ( $description ) {
211 | echo '' . $description . '
';
212 | }
213 | }
214 | }
215 | }
216 | if ( ! function_exists( 'projects_project_archive_description' ) ) {
217 |
218 | /**
219 | * Show a projects page description on project archives
220 | *
221 | * Hooked into projects_archive_description
222 | *
223 | * @access public
224 | * @subpackage Archives
225 | * @return void
226 | */
227 | function projects_project_archive_description() {
228 | if ( is_post_type_archive( 'project' ) && get_query_var( 'paged' ) == 0 || is_page( projects_get_page_id( 'projects' ) ) ) {
229 | $projects_page = get_post( projects_get_page_id( 'projects' ) );
230 | $page_content = '';
231 | if ( isset( $projects_page->post_content ) ) {
232 | $page_content = $projects_page->post_content;
233 | }
234 | $description = apply_filters( 'the_content', $page_content );
235 | if ( $description ) {
236 | echo '' . $description . '
';
237 | }
238 | }
239 | }
240 | }
241 |
242 | if ( ! function_exists( 'projects_template_loop_project_thumbnail' ) ) {
243 |
244 | /**
245 | * Get the project thumbnail for the loop.
246 | *
247 | * Hooked into projects_loop_item
248 | *
249 | * @access public
250 | * @subpackage Loop
251 | * @return void
252 | */
253 | function projects_template_loop_project_thumbnail() {
254 | echo '' . projects_get_project_thumbnail() . ' ';
255 | }
256 | }
257 |
258 | if ( ! function_exists( 'projects_template_loop_project_title' ) ) {
259 |
260 | /**
261 | * Display the project title in the loop.
262 | *
263 | * Hooked into projects_loop_item
264 | *
265 | * @access public
266 | * @subpackage Loop
267 | * @return void
268 | */
269 | function projects_template_loop_project_title() {
270 | echo '' . get_the_title() . ' ';
271 | }
272 | }
273 |
274 | if ( ! function_exists( 'projects_reset_loop' ) ) {
275 |
276 | /**
277 | * Reset the loop's index and columns when we're done outputting a project loop.
278 | *
279 | * @access public
280 | * @subpackage Loop
281 | * @return void
282 | */
283 | function projects_reset_loop() {
284 | global $projects_loop;
285 | // Reset loop/columns globals when starting a new loop
286 | $projects_loop['loop'] = $projects_loop['column'] = '';
287 | }
288 | }
289 |
290 | add_filter( 'loop_end', 'projects_reset_loop' );
291 |
292 |
293 | if ( ! function_exists( 'projects_get_project_thumbnail' ) ) {
294 |
295 | /**
296 | * Get the project thumbnail, or the placeholder if not set.
297 | *
298 | * @access public
299 | * @subpackage Loop
300 | * @param string $size (default: 'project-archive')
301 | * @param int $placeholder_width (default: 0)
302 | * @param int $placeholder_height (default: 0)
303 | * @return string
304 | */
305 | function projects_get_project_thumbnail( $size = 'project-archive' ) {
306 | global $post;
307 |
308 | if ( has_post_thumbnail() )
309 | return get_the_post_thumbnail( $post->ID, $size );
310 | }
311 | }
312 |
313 | if ( ! function_exists( 'projects_pagination' ) ) {
314 |
315 | /**
316 | * Output the pagination.
317 | *
318 | * Hooked into projects_after_loop
319 | *
320 | * @access public
321 | * @subpackage Loop
322 | * @return void
323 | */
324 | function projects_pagination() {
325 | projects_get_template( 'loop/pagination.php' );
326 | }
327 | }
328 |
329 | if ( ! function_exists( 'projects_template_short_description' ) ) {
330 |
331 | /**
332 | * Output the project short description.
333 | *
334 | * Hooked into projects_after_loop_item
335 | *
336 | * @access public
337 | * @subpackage Project
338 | * @return void
339 | */
340 | function projects_template_short_description() {
341 | projects_get_template( 'loop/short-description.php' );
342 | }
343 | }
344 |
345 | /** Single Project ********************************************************/
346 |
347 | if ( ! function_exists( 'projects_template_single_feature' ) ) {
348 |
349 | /**
350 | * Output the project feature before the single project summary.
351 | *
352 | * Hooked into projects_before_single_project_summary
353 | *
354 | * @access public
355 | * @subpackage Project
356 | * @return void
357 | */
358 | function projects_template_single_feature() {
359 | projects_get_template( 'single-project/project-feature.php' );
360 | }
361 | }
362 |
363 | if ( ! function_exists( 'projects_template_single_gallery' ) ) {
364 |
365 | /**
366 | * Output the project gallery before the single project summary.
367 | *
368 | * Hooked into projects_before_single_project_summary
369 | *
370 | * @access public
371 | * @subpackage Project
372 | * @return void
373 | */
374 | function projects_template_single_gallery() {
375 | projects_get_template( 'single-project/project-gallery.php' );
376 | }
377 | }
378 |
379 | if ( ! function_exists( 'projects_template_single_title' ) ) {
380 |
381 | /**
382 | * Output the project title.
383 | *
384 | * Hooked into projects_before_single_project_summary
385 | *
386 | * @access public
387 | * @subpackage Project
388 | * @return void
389 | */
390 | function projects_template_single_title() {
391 | projects_get_template( 'single-project/title.php' );
392 | }
393 | }
394 |
395 | if ( ! function_exists( 'projects_template_single_short_description' ) ) {
396 |
397 | /**
398 | * Output the project short description (excerpt).
399 | *
400 | * Hooked into projects_before_single_project_summary
401 | *
402 | * @access public
403 | * @subpackage Project
404 | * @return void
405 | */
406 | function projects_template_single_short_description() {
407 | projects_get_template( 'single-project/short-description.php' );
408 | }
409 | }
410 |
411 | if ( ! function_exists( 'projects_template_single_description' ) ) {
412 |
413 | /**
414 | * Output the project description.
415 | *
416 | * Hooked into projects_single_project_summary
417 | *
418 | * @access public
419 | * @subpackage Project
420 | * @return void
421 | */
422 | function projects_template_single_description() {
423 | projects_get_template( 'single-project/description.php' );
424 | }
425 | }
426 |
427 | if ( ! function_exists( 'projects_template_single_meta' ) ) {
428 |
429 | /**
430 | * Output the project meta.
431 | *
432 | * Hooked into projects_single_project_summary
433 | *
434 | * @access public
435 | * @subpackage Project
436 | * @return void
437 | */
438 | function projects_template_single_meta() {
439 | projects_get_template( 'single-project/meta.php' );
440 | }
441 | }
442 |
443 | if ( ! function_exists( 'projects_single_pagination' ) ) {
444 |
445 | /**
446 | * Output the project pagination.
447 | *
448 | * Hooked into projects_after_single_project
449 | *
450 | * @access public
451 | * @subpackage Project
452 | * @return void
453 | */
454 | function projects_single_pagination() {
455 | projects_get_template( 'single-project/pagination.php' );
456 | }
457 | }
458 |
459 | if ( ! function_exists( 'projects_content' ) ) {
460 |
461 | /**
462 | * Output Projects content.
463 | *
464 | * This function is only used in the optional 'projects.php' template
465 | * which people can add to their themes to add basic projects support
466 | * without hooks or modifying core templates.
467 | *
468 | * @access public
469 | * @return void
470 | */
471 | function projects_content() {
472 |
473 | if ( is_singular( 'project' ) ) {
474 |
475 | while ( have_posts() ) : the_post();
476 |
477 | projects_get_template_part( 'content', 'single-project' );
478 |
479 | endwhile;
480 |
481 | } else { ?>
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 | ID, '_testimonials_id', true ) );
535 | if ( isset( $testimonial_id ) && '' != $testimonial_id && '0' != $testimonial_id ) {
536 | $args = apply_filters( 'projects_testimonials_args', array(
537 | 'id' => $testimonial_id,
538 | 'per_row' => 1,
539 | ) );
540 | echo '';
541 | woothemes_testimonials( $args );
542 | echo '
';
543 | }
544 |
545 | }
546 | }
547 | }
548 |
549 | if ( ! function_exists( 'projects_output_product' ) ) {
550 |
551 | /**
552 | * Output Projects Product.
553 | *
554 | * This function is only used if WooCommerce is enabled.
555 | * It can be used to output a 'buy now' button for a product associated with a project.
556 | *
557 | * Hooked into projects_after_meta
558 | *
559 | * @access public
560 | * @return void
561 | * @since 1.2.0
562 | */
563 | function projects_output_product() {
564 | if ( class_exists( 'WooCommerce' ) && is_singular( 'project' ) ) {
565 | global $post;
566 | $product_id = esc_attr( get_post_meta( $post->ID, '_products_id', true ) );
567 | if ( isset( $product_id ) && '' != $product_id && '0' != $product_id ) {
568 | echo '';
569 | echo '
' . apply_filters( 'projects_meta_woocommerce_title', __( 'Purchase', 'projects-by-woothemes' ) ) . ' ';
570 | echo do_shortcode( '[add_to_cart id="' . $product_id . '" style=""]' );
571 | echo '';
572 | }
573 |
574 | }
575 | }
576 | }
577 |
578 | if ( ! function_exists( 'projects_woocommerce_messages' ) ) {
579 |
580 | /**
581 | * Output Projects WooCommerce Messages.
582 | *
583 | * Displays WooCommerce Messages on the single project page - for feedback adding products to the cart when js is disabled
584 | *
585 | * Hooked into projects_before_single_project
586 | *
587 | * @access public
588 | * @return void
589 | * @since 1.2.0
590 | */
591 | function projects_woocommerce_messages() {
592 | if ( class_exists( 'WooCommerce' ) && is_singular( 'project' ) ) {
593 | global $post;
594 | $product_id = esc_attr( get_post_meta( $post->ID, '_products_id', true ) );
595 | if ( isset( $product_id ) && '' != $product_id && '0' != $product_id ) {
596 | echo do_shortcode( '[woocommerce_messages]' );
597 | }
598 |
599 | }
600 | }
601 | }
--------------------------------------------------------------------------------
/projects.php:
--------------------------------------------------------------------------------
1 | dir = dirname( $file );
60 | $this->file = $file;
61 | $this->assets_dir = trailingslashit( $this->dir ) . 'assets';
62 | $this->assets_url = esc_url( trailingslashit( plugins_url( '/assets/', $file ) ) );
63 | $this->token = 'projects';
64 | $this->post_type = apply_filters( 'projects_post_type_designation', 'project' );
65 |
66 | // Upgrade data
67 | $this->upgrade_data( true );
68 |
69 | // Variables
70 | $this->template_url = apply_filters( 'projects_template_url', 'projects/' );
71 |
72 | $this->load_plugin_textdomain();
73 | add_action( 'init', array( $this, 'load_localisation' ), 0 );
74 |
75 | // Define constants
76 | $this->define_constants();
77 |
78 | // Include required files
79 | $this->includes();
80 |
81 | // Run this on activation.
82 | register_activation_hook( $this->file, array( $this, 'activation' ) );
83 |
84 | // Run this on deactivation.
85 | register_deactivation_hook( $this->file, array( $this, 'deactivation' ) );
86 |
87 | add_action( 'init', array( $this, 'post_type_names' ) );
88 | add_action( 'init', array( $this, 'register_rewrite_tags' ) );
89 | add_action( 'init', array( $this, 'register_post_type' ) );
90 | add_action( 'init', array( $this, 'register_taxonomy' ) );
91 |
92 | add_action( 'widgets_init', array( $this, 'include_widgets' ) );
93 |
94 | add_action( 'after_setup_theme', array( $this, 'ensure_post_thumbnails_support' ) );
95 | add_action( 'after_setup_theme', array( $this, 'register_image_sizes' ) );
96 |
97 | if ( is_admin() ) {
98 | require_once( 'classes/class-projects-admin.php' );
99 | $this->admin = new Projects_Admin( $file );
100 | } else {
101 | require_once( 'classes/class-projects-frontend.php' );
102 | $this->frontend = new Projects_Frontend( $file );
103 | }
104 |
105 | } // End __construct()
106 |
107 | /**
108 | * Register custom rewrite tags.
109 | * @access public
110 | * @since 1.0.0
111 | * @return void
112 | */
113 | public function register_rewrite_tags () {
114 | add_rewrite_tag( '%project_category%','([^&]+)' );
115 | } // End register_rewrite_tags()
116 |
117 | /**
118 | * Define Projects Constants
119 | */
120 | private function define_constants() {
121 | define( 'PROJECTS_PLUGIN_FILE', __FILE__ );
122 | define( 'PROJECTS_VERSION', $this->version );
123 | } // End define_constants()
124 |
125 | /**
126 | * Change the UI names in the admin
127 | *
128 | * @access public
129 | * @since 1.1.0
130 | * @return void
131 | */
132 | public function post_type_names () {
133 | $this->singular_name = apply_filters( 'projects_post_type_singular_name', _x( 'Project', 'post type singular name', 'projects-by-woothemes' ) );
134 | $this->plural_name = apply_filters( 'projects_post_type_plural_name', _x( 'Projects', 'post type general name', 'projects-by-woothemes' ) );
135 | } // End post_type_names()
136 |
137 | /**
138 | * Register the post type.
139 | *
140 | * @access public
141 | * @return void
142 | */
143 | public function register_post_type () {
144 |
145 | $labels = array(
146 | 'name' => $this->plural_name,
147 | 'singular_name' => $this->singular_name,
148 | 'add_new' => _x( 'Add New', $this->post_type, 'projects-by-woothemes' ),
149 | 'add_new_item' => sprintf( __( 'Add New %s', 'projects-by-woothemes' ), $this->singular_name ),
150 | 'edit_item' => sprintf( __( 'Edit %s', 'projects-by-woothemes' ), $this->singular_name ),
151 | 'new_item' => sprintf( __( 'New %s', 'projects-by-woothemes' ), $this->singular_name ),
152 | 'all_items' => sprintf( _x( 'All %s', $this->post_type, 'projects-by-woothemes' ), $this->plural_name ),
153 | 'view_item' => sprintf( __( 'View %s', 'projects-by-woothemes' ), $this->singular_name ),
154 | 'search_items' => sprintf( __( 'Search %a', 'projects-by-woothemes' ), $this->plural_name ),
155 | 'not_found' => sprintf( __( 'No %s Found', 'projects-by-woothemes' ), $this->plural_name ),
156 | 'not_found_in_trash' => sprintf( __( 'No %s Found In Trash', 'projects-by-woothemes' ), $this->plural_name ),
157 | 'parent_item_colon' => '',
158 | 'menu_name' => $this->plural_name
159 |
160 | );
161 | $args = array(
162 | 'labels' => apply_filters( 'projects_post_type_labels', $labels, $labels ),
163 | 'public' => true,
164 | 'publicly_queryable' => true,
165 | 'show_ui' => true,
166 | 'show_in_menu' => true,
167 | 'query_var' => true,
168 | 'rewrite' => apply_filters( 'projects_post_type_rewrite', true ),
169 | 'capability_type' => 'post',
170 | 'has_archive' => ( $projects_page_id = projects_get_page_id( 'projects' ) ) && get_page( $projects_page_id ) ? get_page_uri( $projects_page_id ) : 'projects',
171 | 'hierarchical' => false,
172 | 'supports' => array(
173 | 'title',
174 | 'editor',
175 | 'thumbnail',
176 | 'excerpt'
177 | ),
178 | 'menu_position' => 5,
179 | 'menu_icon' => 'dashicons-portfolio'
180 | );
181 |
182 | $args = apply_filters( 'projects_register_post_type', $args );
183 |
184 | register_post_type( $this->post_type, (array) $args );
185 | } // End register_post_type()
186 |
187 | /**
188 | * Register the "project-category" taxonomy.
189 | * @access public
190 | * @since 1.3.0
191 | * @return void
192 | */
193 | public function register_taxonomy () {
194 | $this->taxonomy_category = new Projects_Taxonomy(); // Leave arguments empty, to use the default arguments.
195 | $this->taxonomy_category->register();
196 | } // End register_taxonomy()
197 |
198 | /**
199 | * Register image sizes.
200 | * @since 1.0.0
201 | * @return void
202 | */
203 | public function register_image_sizes () {
204 | if ( function_exists( 'add_image_size' ) ) {
205 |
206 | $options = get_option( 'projects-images-fields' );
207 |
208 | $defaults = apply_filters( 'projects_default_image_size', array(
209 | 'project-archive' => array(
210 | 'width' => 300,
211 | 'height' => 300,
212 | 'crop' => 'no'
213 | ),
214 | 'project-single' => array(
215 | 'width' => 1024,
216 | 'height' => 1024,
217 | 'crop' => 'no'
218 | ),
219 | 'project-thumbnail' => array(
220 | 'width' => 100,
221 | 'height' => 100,
222 | 'crop' => 'yes'
223 | )
224 | ) );
225 |
226 | // Parse incomming $options into an array and merge it with $defaults
227 | $options = wp_parse_args( $options, $defaults );
228 |
229 | // Register each image size
230 | foreach ( $options as $image_size => $size ) {
231 | $crop = isset( $size['crop'] ) && 'yes' == $size['crop'] ? true : false;
232 | add_image_size( $image_size, $size['width'], $size['height'], $crop );
233 | }
234 |
235 | }
236 | } // End register_image_sizes()
237 |
238 | /**
239 | * Get projects.
240 | * @param string/array $args Arguments to be passed to the query.
241 | * @since 1.0.0
242 | * @return array/boolean Array if true, boolean if false.
243 | */
244 | public function get_projects ( $args = '' ) {
245 | $defaults = array(
246 | 'limit' => 5,
247 | 'orderby' => 'menu_order',
248 | 'order' => 'DESC',
249 | 'id' => 0
250 | );
251 |
252 | $args = wp_parse_args( $args, $defaults );
253 |
254 | // Allow child themes/plugins to filter here.
255 | $args = apply_filters( 'projects_get_projects_args', $args );
256 |
257 | // The Query Arguments.
258 | $query_args = array();
259 | $query_args['post_type'] = 'project';
260 | $query_args['numberposts'] = $args['limit'];
261 | $query_args['orderby'] = $args['orderby'];
262 | $query_args['order'] = $args['order'];
263 |
264 | if ( is_numeric( $args['id'] ) && ( intval( $args['id'] ) > 0 ) ) {
265 | $query_args['p'] = intval( $args['id'] );
266 | }
267 |
268 | // Whitelist checks.
269 | if ( ! in_array( $query_args['orderby'], array( 'none', 'ID', 'author', 'title', 'date', 'modified', 'parent', 'rand', 'comment_count', 'menu_order', 'meta_value', 'meta_value_num' ) ) ) {
270 | $query_args['orderby'] = 'date';
271 | }
272 |
273 | if ( ! in_array( $query_args['order'], array( 'ASC', 'DESC' ) ) ) {
274 | $query_args['order'] = 'DESC';
275 | }
276 |
277 | if ( ! in_array( $query_args['post_type'], get_post_types() ) ) {
278 | $query_args['post_type'] = 'project';
279 | }
280 |
281 | // The Query.
282 | $query = get_posts( $query_args );
283 |
284 | // The Display.
285 | if ( ! is_wp_error( $query ) && is_array( $query ) && count( $query ) > 0 ) {
286 | foreach ( $query as $k => $v ) {
287 | $meta = get_post_custom( $v->ID );
288 |
289 | // Get the image.
290 | $query[$k]->image = projects_get_image( $v->ID, $args['size'] );
291 |
292 | // Get the URL.
293 | if ( isset( $meta['_url'][0] ) && '' != $meta['_url'][0] ) {
294 | $query[$k]->url = esc_url( $meta['_url'][0] );
295 | } else {
296 | $query[$k]->url = get_permalink( $v->ID );
297 | }
298 | }
299 | } else {
300 | $query = false;
301 | }
302 |
303 | return $query;
304 | } // End get_projects()
305 |
306 | /**
307 | * Load the plugin's localisation file.
308 | * @access public
309 | * @since 1.0.0
310 | * @return void
311 | */
312 | public function load_localisation () {
313 | load_plugin_textdomain( 'projects-by-woothemes', false, dirname( plugin_basename( $this->file ) ) . '/lang/' );
314 | } // End load_localisation()
315 |
316 | /**
317 | * Load the plugin textdomain from the main WordPress "languages" folder.
318 | * @since 1.0.0
319 | * @return void
320 | */
321 | public function load_plugin_textdomain () {
322 | $domain = 'projects-by-woothemes';
323 | // The "plugin_locale" filter is also used in load_plugin_textdomain()
324 | $locale = apply_filters( 'plugin_locale', get_locale(), $domain );
325 |
326 | load_textdomain( $domain, WP_LANG_DIR . '/' . $domain . '/' . $domain . '-' . $locale . '.mo' );
327 | load_plugin_textdomain( $domain, FALSE, dirname( plugin_basename( $this->file ) ) . '/lang/' );
328 | } // End load_plugin_textdomain()
329 |
330 | /**
331 | * Run on activation.
332 | * @access public
333 | * @since 1.0.0
334 | * @return void
335 | */
336 | public function activation () {
337 | $this->register_plugin_version();
338 |
339 | // Flush rewrite rules
340 | flush_rewrite_rules();
341 | } // End activation()
342 |
343 | /**
344 | * Run on deactivation.
345 | * @access public
346 | * @since 1.0.0
347 | * @return void
348 | */
349 | public function deactivation () {
350 | // Flush rewrite rules
351 | flush_rewrite_rules();
352 | } // End deactivation()
353 |
354 | /**
355 | * Register the plugin's version.
356 | * @access public
357 | * @since 1.0.0
358 | * @return void
359 | */
360 | private function register_plugin_version () {
361 | if ( $this->version != '' ) {
362 | update_option( 'projects' . '-version', $this->version );
363 | }
364 | } // End register_plugin_version()
365 |
366 | /**
367 | * Ensure that "post-thumbnails" support is available for those themes that don't register it.
368 | * @since 1.0.0
369 | * @return void
370 | */
371 | public function ensure_post_thumbnails_support () {
372 | if ( ! current_theme_supports( 'post-thumbnails' ) ) { add_theme_support( 'post-thumbnails' ); }
373 | } // End ensure_post_thumbnails_support()
374 |
375 | /**
376 | * Get the plugin url.
377 | * @access public
378 | * @since 1.0.0
379 | * @return string
380 | */
381 | public function plugin_url () {
382 | return untrailingslashit( plugins_url( '/', $this->file ) );
383 | } // End plugin_url()
384 |
385 |
386 | /**
387 | * Get the plugin path.
388 | * @access public
389 | * @since 1.0.0
390 | * @return string
391 | */
392 | public function plugin_path () {
393 | return untrailingslashit( plugin_dir_path( $this->file ) );
394 | } // End plugin_path()
395 |
396 |
397 | /**
398 | * Get an image size.
399 | *
400 | * Variable is filtered by projects_get_image_size_{image_size}
401 | *
402 | * @access public
403 | * @since 1.0.0
404 | * @param mixed $image_size
405 | * @return string
406 | */
407 | public function get_image_size ( $image_size ) {
408 | // Only return sizes we define in settings
409 | if ( ! in_array( $image_size, array( 'project-thumbnail', 'project-archive', 'project-single' ) ) )
410 | return apply_filters( 'projects_get_image_size_' . $image_size, '' );
411 |
412 | // Get image size from options
413 | $options = get_option( 'projects-images-fields', array() );
414 | $size = $options[ $image_size ];
415 |
416 | $size['width'] = isset( $size['width'] ) ? $size['width'] : '300';
417 | $size['height'] = isset( $size['height'] ) ? $size['height'] : '300';
418 | $size['crop'] = isset( $size['crop'] ) ? $size['crop'] : 1;
419 |
420 | return apply_filters( 'projects_get_image_size_' . $image_size, $size );
421 | } // End get_image_size()
422 |
423 | /**
424 | * Include Projects widgets.
425 | *
426 | * @access public
427 | * @since 1.2.2
428 | */
429 | public function include_widgets() {
430 | include_once( 'classes/class-widget-projects.php' );
431 | include_once( 'classes/class-widget-project-categories.php' );
432 | } // End include_widgets()
433 |
434 | /**
435 | * Include required files.
436 | * @since 1.2.2
437 | */
438 | private function includes() {
439 | require_once( 'classes/class-projects-taxonomy.php' );
440 | require_once( 'classes/class-projects-shortcodes.php' );
441 | require_once( 'classes/class-projects-settings.php' );
442 | require_once( 'classes/class-projects-integrations.php' );
443 |
444 | require_once( 'projects-template.php' );
445 | require_once( 'projects-core-functions.php' );
446 | require_once( 'projects-hooks.php' );
447 | } // End includes()
448 |
449 | /**
450 | * upgrade_data upgrades old data structure to the new data structure
451 | * @param boolean $upgrade_data override setting to run the function
452 | * @since 1.2.3
453 | * @return void
454 | */
455 | private function upgrade_data( $upgrade_data = false ) {
456 | if ( $upgrade_data ) {
457 | // Get old data
458 | $old_options = get_option( 'projects' );
459 | if ( isset( $old_options['projects_page_id'] ) && is_array( $old_options ) && !empty( $old_options ) ) {
460 | // Check if new pages data exists
461 | $new_pages_options = get_option( 'projects-pages-fields' );
462 | if ( !isset( $new_pages_options['projects_page_id'] ) ) {
463 | update_option( 'projects-pages-fields', array( 'projects_page_id' => $old_options['projects_page_id'] ) );
464 | } // End If Statement
465 | // Check if new images data exists
466 | $new_images_options = get_option( 'projects-images-fields' );
467 | if ( !isset( $new_images_options['project-archive'] ) && !isset( $new_images_options['project-single'] ) && !isset( $new_images_options['project-thumbnail'] ) ) {
468 | update_option( 'projects-images-fields', array( 'project-archive' => $old_options['project-archive'],
469 | 'project-single' => $old_options['project-single'],
470 | 'project-thumbnail' => $old_options['project-thumbnail']
471 | ) );
472 | } // End If Statement
473 | // Remove old data
474 | delete_option( 'projects' );
475 | } // End If Statement
476 | } // End If Statement
477 | } // End upgrade_data()
478 |
479 | } // End Class
480 |
481 | global $projects;
482 |
483 | $projects = new Projects( __FILE__ );
--------------------------------------------------------------------------------
/readme.txt:
--------------------------------------------------------------------------------
1 | === Projects by WooThemes ===
2 | Contributors: woothemes, mattyza, jameskoster, tiagonoronha, jeffikus
3 | Donate link: http://woothemes.com/
4 | Tags: portfolio, projects, project, showcase, artwork, work, creative, photography, art, images, woocommerce
5 | Requires at least: 4.0
6 | Tested up to: 4.3.1
7 | Stable tag: 1.5.0
8 | License: GPLv2 or later
9 | License URI: http://www.gnu.org/licenses/gpl-2.0.html
10 |
11 | Hi, I'm your projects showcase plugin for WordPress. Use me to show off a portfolio of your latest work.
12 |
13 | == Description ==
14 |
15 | = Create and display a portfolio of projects =
16 |
17 | "Projects" by WooThemes is a clean and easy-to-use portfolio showcase management system for WordPress. Load in your recent projects, and display them on a specified page using our template system, or via a shortcode, widget or template tag.
18 |
19 | Projects integrates with our [testimonials plugin](http://wordpress.org/plugins/testimonials-by-woothemes/) allowing you to associate a testimonial with a project and display it on the single project page.
20 |
21 | You can even assign a project to a product you've created in [WooCommerce](http://wordpress.org/plugins/woocommerce/) and let customers add it to their cart from the project page.
22 |
23 | = Easy to use =
24 |
25 | Publish and categorise your portfolio of projects using the familiar WordPress interface.
26 |
27 | = Detailed project information =
28 |
29 | Include full project details such as cover images, galleries, categories, client details and projects URLs.
30 |
31 | = Fully integrated with WordPress =
32 |
33 | Display your portfolio of projects using native WordPress architecture (project archives & single pages).
34 |
35 | = Widgets & Shortcodes included =
36 |
37 | Use Widgets & Shortcodes for situational project display.
38 |
39 | = Mobile friendly =
40 |
41 | Projects includes a responsive layout to integrate with any theme.
42 |
43 | = Customisable =
44 |
45 | Get your hands dirty! Customise & extend Projects via a vast array of hooks, filters & templates.
46 |
47 | = WooCommerce =
48 | Assign projects to products and give visitors an easy way to add products to their cart using [WooCommerce](http://wordpress.org/plugins/woocommerce/) functionality.
49 |
50 | = Testimonials =
51 |
52 | Integrated with our [testimonials plugin](http://wordpress.org/plugins/testimonials-by-woothemes/) allowing you to assign a client testimonial to a project and display it on the single project page.
53 |
54 | = Documentation =
55 |
56 | Extensive [documentation](http://docs.woothemes.com/documentation/plugins/projects/) to help you out if you get stuck.
57 |
58 | == Usage ==
59 |
60 | Once installed you can begin adding projects to your portfolio right away via the 'Projects' item in the main menu. But before you do that you should go ahead and create a page for your projects (via the Pages menu item) and specify that page as your projects base page in the projects settings. The interface for adding projects is very similar to adding posts so you should feel right at home.
61 |
62 | For more detailed usage instructions take a look at the [Projects Documentation](http://docs.woothemes.com/documentation/plugins/projects/).
63 |
64 | == Installation ==
65 |
66 | Installing "Projects" can be done either by searching for "Projects by WooThemes" via the "Plugins > Add New" screen in your WordPress dashboard, or by using the following steps:
67 |
68 | 1. Download the plugin via WordPress.org.
69 | 2. Upload the ZIP file through the "Plugins > Add New > Upload" screen in your WordPress dashboard.
70 | 3. Activate the plugin through the 'Plugins' menu in WordPress
71 |
72 | == Frequently Asked Questions ==
73 |
74 | = My project images are blurry / distorted, how do I fix that? =
75 |
76 | It's possible that your theme is scaling images to fit their container by setting `width: 100%;`. If this is the case, and your project thumbnails are too small they will become distored / blurred as they are scaled up. To fix this change the project thumbnail size options in the Projects settings then regenerate your thumbnails using the [Regenerate Thumbnails plugin](http://wordpress.org/plugins/regenerate-thumbnails/).
77 |
78 | = How do I integrate projects into my theme? =
79 |
80 | If you run into layout issues on Projects pages then you will need to peruse one of two methods to make your theme compatible. You can read all about this in the [documentation](http://docs.woothemes.com/document/third-party-theme-compatibility/).
81 |
82 | = I want to change X =
83 |
84 | Projects uses template files to control the display of it's various components. These templates can be safely editied so that your customisations are not lost during updates as described in the [documentation](http://docs.woothemes.com/document/editing-projects-templates-safely/).
85 |
86 | = Is it possible to add cusstom fields to the Project details meta box? =
87 |
88 | Yes! You can follow this tutorial to [add custom fields to projects](http://docs.woothemes.com/document/add-a-project-meta-field/) and display them.
89 |
90 | = How do I contribute? =
91 |
92 | We encourage everyone to contribute their ideas, thoughts and code snippets. This can be done by forking the [repository over at GitHub](http://github.com/woothemes/projects/).
93 |
94 | = Can I display a tesitmonial on a project page? =
95 |
96 | You sure can! Read about how in the [documentation](http://docs.woothemes.com/document/adding-testimonials-to-projects/).
97 |
98 | == Screenshots ==
99 |
100 | 1. The projects base page
101 | 2. A single project page
102 | 3. The projects management screen within the WordPress dashboard.
103 |
104 | == Upgrade Notice ==
105 |
106 | = 1.5.0 =
107 | * Fixes projects page not loading - please resave permalinks after updating!
108 |
109 | = 1.4.2 =
110 | * Removes deprecated constructor call for WP_Widget
111 |
112 | = 1.4.0 =
113 | * The default permalink structure has been tweaked to remove the project category. So http://localhost/network/project/landscapes/the-barrow-downs/ becomes http://localhost/network/project/the-barrow-downs/. Any old links will automatically redirect to their newer counterparts. You may have to re-save your permalink settings after performing this update. You can use the `projects_post_type_rewrite` filter to adjust this.
114 |
115 | = 1.3.0 =
116 | * The project category urls have been improved to use the base page title as the slug opposed to the `project-category` default. So, previously your project cateogry urls will have looked like: yoursite.com/project-category/illustration. Now, `project-category` is replaced with the slug of your projects base page. So if you're using a page called 'Portfolio' that url will now look like: yoursite.com/portfolio/illustration. You will have to create custom redirects if you want the old urls work.
117 | * This version adds admin tabs to the settings screens, and will run an update to your existing settings data. If your data is not retained, simply resave your settings.
118 |
119 | = 1.2.0 =
120 | * The project archive slug now mirrors your projects base page slug isntead of being fixed as 'projects'. If you're using a base page with a slug other than 'projects' you may want to check any static links to your projects page. For example if your base page is 'portfolio' your projects post type archive will now exist at http://yoursite.com/portfolio rather than http://yoursite.com/projects.
121 |
122 | = 1.0.0 =
123 | * Initial release. Woo!
124 |
125 | == Changelog ==
126 |
127 | = 1.5.0 =
128 | * 2015.12.07
129 | * New/Fix - Adds query class to modify the query to fix the Project page not loading.
130 |
131 | = 1.4.2 =
132 | * 2015.07.07
133 | * Tweak - Allow attribute for include_children inside taxonomy query.
134 | * Removes deprecated constructor call for WP_Widget
135 |
136 | = 1.4.1 =
137 | * 2014.12.05
138 | * Fix - Redirect issue when setting projects page as homepage.
139 |
140 | = 1.4.0 =
141 | * 2014-11-11
142 | * Fix - Project gallery thumbnail sizes in admin. (Props @corvannoorloos).
143 | * Fix - Undefined index notice when trashing/untrashing projects. (Props @johnbuck).
144 | * Tweak - Improvements to `projects_template_redirect()`.
145 | * Tweak - Added `rel="lightbox"` to project galleries for compatibility with lightbox plugins.
146 | * Tweak - Project post type default url structure no longer includes project category (resolves attachment page 404's.
147 |
148 | = 1.3.0 =
149 | * 2014-08-26
150 | * New - Adds admin tabs to the settings screens for better UX.
151 | * New - Category permalinks use base page for structure.
152 |
153 | = 1.2.2 =
154 | * 2014-06-06
155 | * Tweak - Product linking label now includes sku / id.
156 | * Tweak - Widgets now called via a single function and other minor refactoring.
157 | * Tweak - Project Category taxonomy names filterable. (Props @abouolia)
158 | * Fix - Reset post data in projects widget.
159 |
160 | = 1.2.1 =
161 | * 2014-04-24
162 | * Fix - Javascript error in admin
163 | * Fix - Select box save method. (Props @anija).
164 |
165 | = 1.2.0 =
166 | * 2014-04-09
167 | * New - Replaced .less files with .scss.
168 | * New - Integrated with WooCommerce.
169 | * New - Added config.codekit.
170 | * New - Project images can now be cropped. (Props @helgatheviking).
171 | * New - Project archive slug is now retreived from base page slug.
172 | * Tweak - Added css for multi column layouts when using the shortcode to display projects.
173 | * Tweak - Project categories can now be added to navigation menus.
174 | * Tweak - Various new input types can now be easily added using projects_custom_fields filter. (Props @helgatheviking).
175 | * Tweak - Menu icon added in register_post_type() and now filterable. (Props @helgatheviking).
176 | * Tweak - Added an edit media link to the project gallery meta box.
177 |
178 | = 1.1.0 =
179 | * 2014-03-25
180 | * New - Integration with Testimonials plugin.
181 | * New - dummy_data.xml containing dummy projects content.
182 | * New - Project excerpt replaced with new short description meta box with tinymce support.
183 | * New - Projects can now be filtered by category on the project management screen.
184 | * Fix - Project category widget list items are now wrapped in a ul.
185 | * Tweak - Shortcodes in project descriptions now work as expected. Shortcodes in excerpts will need to be enabled.
186 | * Tweak - Gallery images link to full size versions. Disable with projects_gallery_link_images filter.
187 | * Tweak - Projects Post Type / Taxonomy args are now filterable. (Props @helgatheviking).
188 | * Tweak - Projects post type single/plural names are now filterable. (Props @helgatheviking).
189 | * Tweak - Several UI tweaks and improvements.
190 | * Tweak - It's now possible to add select and radio custom fields using the projects_custom_fields filter (Props @helgatheviking).
191 |
192 | = 1.0.1 =
193 | * 2014-02-24
194 | * Localization - Replaces incorrect language files.
195 | * Tweak - Localized some strings (props Vaclad)
196 |
197 | = 1.0.0 =
198 | * 2014-02-17
199 | * Initial release. Woo!
200 |
--------------------------------------------------------------------------------
/templates/archive-project.php:
--------------------------------------------------------------------------------
1 |
21 |
22 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
86 |
87 |
95 |
96 |
--------------------------------------------------------------------------------
/templates/content-project-category.php:
--------------------------------------------------------------------------------
1 |
27 |
33 |
34 |
35 |
36 |
37 |
38 |
46 |
47 |
48 | name;
50 |
51 | if ( $category->count > 0 )
52 | echo apply_filters( 'projects_subcategory_count_html', ' (' . $category->count . ') ', $category );
53 | ?>
54 |
55 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/templates/content-project-widget.php:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/templates/content-project.php:
--------------------------------------------------------------------------------
1 |
34 | >
35 |
36 |
37 |
38 |
39 |
40 |
49 |
50 |
51 |
52 |
60 |
61 |
--------------------------------------------------------------------------------
/templates/content-single-project.php:
--------------------------------------------------------------------------------
1 |
14 |
15 |
22 |
23 | >
24 |
25 |
35 |
36 |
37 |
38 |
47 |
48 |
49 |
50 |
57 |
58 |
59 |
60 | ';
15 | break;
16 | case 'twentytwelve' :
17 | echo '';
18 | break;
19 | case 'twentythirteen' :
20 | echo '';
21 | break;
22 | case 'twentyfourteen' :
23 | echo '';
24 | get_sidebar( 'content' );
25 | break;
26 | default :
27 | echo '';
28 | break;
29 | }
--------------------------------------------------------------------------------
/templates/layout/wrapper-start.php:
--------------------------------------------------------------------------------
1 | ';
17 | break;
18 | case 'twentytwelve' :
19 | echo '
';
20 | break;
21 | case 'twentythirteen' :
22 | echo '
';
23 | break;
24 | case 'twentyfourteen' :
25 | echo '
';
26 | break;
27 | default :
28 | echo '
';
29 | break;
30 | }
--------------------------------------------------------------------------------
/templates/loop/loop-end.php:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/templates/loop/loop-start.php:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/templates/loop/no-projects-found.php:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/templates/loop/pagination.php:
--------------------------------------------------------------------------------
1 | max_num_pages <= 1 )
15 | return;
16 | ?>
17 |
--------------------------------------------------------------------------------
/templates/loop/short-description.php:
--------------------------------------------------------------------------------
1 | post_excerpt ) ) {
15 | $excerpt_raw = $post->post_excerpt;
16 | } // End If Statement
17 | if ( '' === trim( $excerpt_raw ) ) {
18 | $excerpt_raw = get_the_excerpt();
19 | } // End If Statement
20 | ?>
21 |
22 |
23 |
--------------------------------------------------------------------------------
/templates/single-project.php:
--------------------------------------------------------------------------------
1 |
15 |
16 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
39 |
40 |
48 |
49 | post_content ) return;
15 | ?>
16 |
17 |
18 |
--------------------------------------------------------------------------------
/templates/single-project/meta.php:
--------------------------------------------------------------------------------
1 |
14 |
--------------------------------------------------------------------------------
/templates/single-project/pagination.php:
--------------------------------------------------------------------------------
1 |
12 |
20 |
--------------------------------------------------------------------------------
/templates/single-project/project-feature.php:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 | ID, 'project-single' );
21 | $image_title = esc_attr( get_the_title( get_post_thumbnail_id() ) );
22 | $image_link = wp_get_attachment_url( get_post_thumbnail_id() );
23 | $attachment_count = count( projects_get_gallery_attachment_ids() );
24 | $lightbox_rel = apply_filters( 'projects_lightbox_rel', $rel = 'lightbox' );
25 |
26 | if ( $attachment_count > 0 ) {
27 | $gallery = '[project-gallery]';
28 | } else {
29 | $gallery = '';
30 | }
31 |
32 | if ( apply_filters( 'projects_gallery_link_images', true ) ) {
33 | echo '
' . $image . ' ';
34 | } else {
35 | echo $image;
36 | }
37 |
38 | }
39 |
40 | ?>
41 |
42 |
43 |
--------------------------------------------------------------------------------
/templates/single-project/project-gallery.php:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
23 |
24 | ID . '">' . $image . '';
50 | } else {
51 | echo $image;
52 | }
53 |
54 | $loop++;
55 |
56 | } // endforeach ?>
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/templates/single-project/short-description.php:
--------------------------------------------------------------------------------
1 | post_excerpt ) return;
15 | ?>
16 |
17 | post_excerpt ) ) ?>
18 |
--------------------------------------------------------------------------------
/templates/single-project/title.php:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/templates/taxonomy-project-category.php:
--------------------------------------------------------------------------------
1 |